Bison semantic predicate syntax error, stray '

2019-07-30 15:38发布

问题:

So I am trying to use bison's semantic predicate feature, but I've been running into a few issues trying to have it work.

The problem comes when I try to compile the generated .tab.c file with gcc. I am using gcc 7.1.0 and bison 3.0.4. Here's a snippet of the compile error:

test2.tab.c: In function ‘yyuserAction’:
test2.tab.c:811:12: error: stray ‘#’ in program
     if (! (#line 19 "test2.y" /* glr.c:816  */
            ^
test2.tab.c:811:13: error: ‘line’ undeclared (first use in this function); did you mean ‘uint’?
     if (! (#line 19 "test2.y" /* glr.c:816  */
             ^~~~
             uint

So I've taken bison's example for semantic predicate, and made it a working example:

%{

int new_syntax = 0;
int yyerror(const char* msg) { /* some error handling */ }

%}

%token id

%glr-parser

%%

prog: %empty
    | prog widget
    | prog flip
    ;

widget: %?{  new_syntax } "widget" id old_arg
      | %?{ !new_syntax } "widget" id new_arg
      ;

flip: "flip" { new_syntax = !new_syntax; }
    ;

old_arg: /* something here */
       ;
new_arg: /* something else here */
       ;

%%

After playing around with the tab file, I realized that adding a newline before the #line directives resolves the syntax error, (but it feels kinda hacky directly modifying the generated file. Plus, you would have to align with some spaces in order for gcc to compute the right column position of the code).

I wonder if is this a bug with bison itself, or is it that I'm using semantic predicates wrong, or if this syntax was correct in an earlier version of gcc, or something else.

I've also tried searching the web for this issue, or for a bug already filed with bison, but I found none. (The latest bison version seems to be 3-ish years old. I would be surprised if this issue has not been addressed anywhere at all). Can someone enlighten me about this issue? Thanks.

If necessary, I could try filing a bug with bison (need to figure out how to do that), but I'm not sure if it's my own issue or what not.

回答1:

As far as I can see, this bug has been present for some time (possibly since the semantic predicate feature was introduced, although it seems like someone should have tested it at some point with some version of bison.)

The simplest workaround is to turn off the generation of #line directives, which you can do by simply adding -l (or --no-lines) to the bison command line. However, that will make it harder to interpret error messages which would otherwise refer to line numbers in your bison grammar file.

As a second workaround, you could find the file c.m4, which is probably in /usr/share/bison/c.m4 (of course, that depends on your distribution). Line 462 of that file (in bison 3.0.4) reads:

    if (! ($2)) YYERROR;

If you add a newline just before $2, so that it reads

    if (! (
           $2)) YYERROR;

then everything should work out fine. (At least, it did when I tested it.)



标签: c bison