help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Flex-help] How to debug bison/flex program? usage of yyerror()


From: Marcel Laverdet
Subject: Re: [Flex-help] How to debug bison/flex program? usage of yyerror()
Date: Wed, 30 Dec 2009 22:03:55 -0600
User-agent: RoundCube Webmail/0.2-beta


You don't change the BNF. The idea is that it's an unexpected token and
should never come up. If it does come up you've got a problem.

Really you're best off making your scanner be able to handle ALL input no
matter what.

On Wed, 30 Dec 2009 21:52:46 -0600, Peng Yu <address@hidden> wrote:
> On Wed, Dec 30, 2009 at 1:05 PM, Marcel Laverdet <address@hidden>
> wrote:
>>
>>
>>> Do you actually mean '.' matches non newline?
>>
>> Yes, apologies :)
>>
>>> I made some corrections. Now yylval_string.l becomes the following.
You
>> said yyerror should not be used in the flex file. I'm wondering what I
>> should use to replace the line '.       { yyerror("mystery character
>> %c\n",
>> *yytext); }' in order to catch errors.
>>
>> Really, it's up to you. You can replace it with whatever you want. You
>> could replace it with assert(false) if you want or fprintf(stderr, "oh
>> no!"), I don't know what you want it's your program. It's just a matter
>> of
>> what you want to do when something unexpected happens. Bison will
>> generate
>> error messages for you when something bad happens, but Flex is not in a
>> position to generate error messages. In my scanners I usually do one of
>> two
>> things. I either memoize an error message in my yyextra (or just as a
>> global if you're not using "%option reentrant"), which I can then raise
>> to
>> the client of my scanner/parser. Or, I do something like "return
>> UNEXPECTED_CHARACTER;" (you would have to define this token). Then,
Bison
>> would generate an error such as "Error: Unexpected token
>> UNEXPECTED_CHARACTER on line 5".
> 
> If I return UNEXPECTED_CHARACTER in yylval_string.l, how to change the
> BNF in yylval_string.y?
> 
>>yylval_string.l
> %option nodefault
> %{
> # include "yylval_string.tab.h"
> %}
> %%
> [0-9]+ { yylval=atoi(yytext); return NUMBER; }
> [[:space:]] { /*SPACE*/ }
> .     { return UNEXPECED_CHARACTER; }
> %%
>>yylval_string.y
> %{
> #  include <stdio.h>
> %}
> %token NUMBER UNEXPECED_CHARACTER
> %%
> numbers:
>        NUMBER { printf("NUMBER = %d\n", $1); }
>        | numbers NUMBER { printf("NUMBER = %d\n", $2); }
>  ;
> %%
> main()
> {
>   yyparse();
> }
> 
> yyerror(char *s)
> {
>   fprintf(stderr, "error: %s\n", s);
> }
> 
> 
>> On Wed, 30 Dec 2009 09:39:30 -0600, Peng Yu <address@hidden>
wrote:
>>> On Wed, Dec 30, 2009 at 12:54 AM, Marcel Laverdet
<address@hidden>
>>> wrote:
>>>>
>>>>
>>>> 1) [:space:] is a character class expression. If you want one or more
>>>> spaces you would do [[:space:]]+. What your scanner is looking for
>> right
>>>> now is one of either ":, s, p, a, c, or e". Does that make sense?
Just
>>>> wrap
>>>> it in another set of []'s
>>>>
>>>> 2) . only matches newline, the documentation is not lying :). The
>> message
>>>> you're seeing is from the spaces, since your [:space:] does not match
>>>> them
>>>> correctly. Additionally, you're hitting the default rule, whose
default
>>>> action is to print the matching character. Pretend that this always
>>>> exists
>>>> at the bottom of your file:
>>>
>>> Do you actually mean '.' matches non newline?
>>>
>>>> <*>.|\n fprintf(strerr, "%c", *yytext);
>>>>
>>>> You can (and should) override this using "%option nodefault" which
will
>>>> make it so that your scanner fails to build if you don't handle all
>>>> inputs.
>>>> This is a much more reasonable behavior than just spitting out to
>> strerr.
>>>>
>>>> 3) yyerror is a macro defined by bison, not flex. There should be no
>>>> yyerror in your lex file. bison's definition of yyerror is not ("%s",
>>>> ...)
>>>> it's something different (which depends on your options to bison).
>>>
>>> I made some corrections. Now yylval_string.l becomes the following.
>>> You said yyerror should not be used in the flex file. I'm wondering
>>> what I should use to replace the line '.      { yyerror("mystery
>>> character
>>> %c\n", *yytext); }' in order to catch errors.
>>>
>>> %option nodefault
>>> %{
>>> # include "yylval_string.tab.h"
>>> %}
>>> %%
>>> [0-9]+ { yylval=atoi(yytext); return NUMBER; }
>>> [[:space:]] { /*SPACE*/ }
>>> .     { yyerror("mystery character %c\n", *yytext); }
>>> %%
>>>
>>>
>>>
>>>> On Tue, 29 Dec 2009 23:02:33 -0600, Peng Yu <address@hidden>
>> wrote:
>>>>> I have the source files listed at the end of the message. I
basically
>>>>> want to parse a file with only numbers (separated by spaces) and
print
>>>>> the numbers out. It is an overkill to use bison/flex. But I just
want
>>>>> to try how to use bison/flex.
>>>>>
>>>>> I need to understand how to debug the program. Could somebody help
me
>>>>> with the following three questions?
>>>>>
>>>>> 1. I don't understand why the error message is printed. Shouldn't
the
>>>>> regexes [0-9]+ and [:space:] match all the strings in 'test.txt'.
>>>>>
>>>>> 2. I suspect that '.' is matched to EOF. I'm not sure if I'm
correct.
>>>>> But it seem that EOF can not be printed (is it why '%c' is printed
>>>>> literally?).
>>>>>
>>>>> 3. Why yyerror() in the .l file has two arguments but it has one
>>>>> argument in the .y file? Are they the same function or two different
>>>>> functions?
>>>>>
>>>>> $ make
>>>>> bison -d yylval_string.y
>>>>> flex yylval_string.l
>>>>> cc -o yylval_string yylval_string.tab.c lex.yy.c -lfl
>>>>> $./yylval_string< test.txt
>>>>> NUMBER = 133
>>>>> error: mystery character %c
>>>>>
>>>>> NUMBER = 7
>>>>> error: mystery character %c
>>>>>
>>>>> NUMBER = 33
>>>>> error: mystery character %c
>>>>>
>>>>> NUMBER = 76
>>>>>
>>>>> NUMBER = 35
>>>>>
>>>>>
>>>>> --------------------------------source files listed
>>>>> below---------------------------
>>>>>
>>>>> $cat yylval_string.y %{
>>>>> #  include <stdio.h>
>>>>> %}
>>>>>
>>>>> %token NUMBER
>>>>>
>>>>> %%
>>>>>
>>>>> numbers:
>>>>>        NUMBER { printf("NUMBER = %d\n", $1); }
>>>>>        | numbers NUMBER { printf("NUMBER = %d\n", $2); }
>>>>>  ;
>>>>>
>>>>> %%
>>>>> main()
>>>>> {
>>>>>   yyparse();
>>>>> }
>>>>>
>>>>> yyerror(char *s)
>>>>> {
>>>>>   fprintf(stderr, "error: %s\n", s);
>>>>> }
>>>>>
>>>>>
>>>>> $cat yylval_string.l
>>>>> %{
>>>>> # include "yylval_string.tab.h"
>>>>> %}
>>>>>
>>>>> %%
>>>>> [0-9]+ { yylval=atoi(yytext); return NUMBER; }
>>>>> [:space:] { /*SPACE*/ }
>>>>> .     { yyerror("mystery character %c\n", *yytext); }
>>>>> %%
>>>>>
>>>>> $cat Makefile
>>>>>  .PHONY: all
>>>>>
>>>>> all: yylval_string
>>>>>
>>>>> yylval_string:        yylval_string.l yylval_string.y
>>>>>       bison -d yylval_string.y
>>>>>       flex yylval_string.l
>>>>>       cc -o $@ yylval_string.tab.c lex.yy.c -lfl
>>>>>
>>>>> $cat test.txt
>>>>> 133 7 33 76
>>>>> 35
>>>>>
>>>>>
>>>>
>>
------------------------------------------------------------------------------
>>>>> This SF.Net email is sponsored by the Verizon Developer Community
>>>>> Take advantage of Verizon's best-in-class app development support
>>>>> A streamlined, 14 day to market process makes app distribution fast
>> and
>>>>> easy
>>>>> Join now and get one step closer to millions of Verizon customers
>>>>> http://p.sf.net/sfu/verizon-dev2dev
>>>>> _______________________________________________
>>>>> Flex-help mailing list
>>>>> address@hidden
>>>>> https://lists.sourceforge.net/lists/listinfo/flex-help
>>>>
>>
> 
>
------------------------------------------------------------------------------
> This SF.Net email is sponsored by the Verizon Developer Community
> Take advantage of Verizon's best-in-class app development support
> A streamlined, 14 day to market process makes app distribution fast and
> easy
> Join now and get one step closer to millions of Verizon customers
> http://p.sf.net/sfu/verizon-dev2dev 
> _______________________________________________
> Flex-help mailing list
> address@hidden
> https://lists.sourceforge.net/lists/listinfo/flex-help




reply via email to

[Prev in Thread] Current Thread [Next in Thread]