Reputation: 460
I'm writing a C parser using Bison. My parser's .y file, when watered down VERY much, looks a bit like this:
%parse-param {YYSTYPE *root} /* Used to detect the statement/declaration type, and print the tokens back out again */
/* Tokens defined here, etc */
%start program
program : decl { *root = $1; } |
decl program { *root = $1; }
;
decl : INTEGER_TOKEN identifier SEMICOLON
;
This all works okay when you do for example "int x;" but if I want to do "int x; int y" then it will ignore the second line, and pretend I only inputted "int x;"
Is there some special way that you need to handle multiple lines of input? Any suggestions you have would be appreciated.
Upvotes: 0
Views: 833
Reputation: 241671
It's hard to know what your program actually does but the reduced program will certainly ignore all but the first decl. Consider:
program : decl { *root = $1; } |
decl program { *root = $1; }
;
Since this rule is right-recursive (which is likely not what you want) it will effectively execute the actions *root = $1;
from right to left. That is, the first assignment to *root
will be the last declaration, and subsequently executed actions (corresponding to successively previous declarations) will overwrite that value. The last action executed corresponds to the first declaration, which will be the final value placed into *root
.
Why do the actions execute right-to-left? Because actions are executed at the end of the matched string. An action corresponding to program: decl program
will execute after the second non-terminal program
has been recognised, which means that the inner program
's action will already have been executed. Since the action for program
is really dealing with the decl
, that means that the decl
s are dealt with backwards. If you used normal left-recursion (program : program decl
), the the inner program
will be executed first, so the decl
s will be handled left-to-right.
Upvotes: 1