I recently picked up bison again, but i'm still fighting with the way precedence works and how to solve basic shift/reduce conflicts. I'm quite comfortable with writing the grammar rules and how recursion works etc. but i still cant wrap my head around the precedence rules.
I would be very much appreciating some comments on the the following examples and my problems and understandings of them.
test1.y
%token ID %token TYPE_NAME %token ASTERIX %nonassoc F_T %nonassoc P_T %% f_type: ID type %prec F_T ; type: TYPE_NAME | type ASTERIX %prec P_T | f_type ; %% test1.output
State 5 1 f_type: ID type . 3 type: type . ASTERIX ASTERIX shift, and go to state 7 ASTERIX [reduce using rule 1 (f_type)] $default reduce using rule 1 (f_type) This example produces a shift reduce conflict, because the state machine cant figure out if it should reduce ID type* -> type* -> type or ID type* -> ID type -> type. That latter is the desired result. I tried resolving this conflict by giving the rule type: type ASTERIX a higher precedence than f_type: ID type but that doesn't seem to work. I also would rather not assign any precedence to the terminal ASTERIX, as i would like to use it in other contexts.
test2.y
%token ID %token DOUBLE_PLUS %left POSTFIX_OP %right PREFIX_OP %% exp: ID | exp DOUBLE_PLUS %prec POSTFIX_OP | DOUBLE_PLUS exp %prec PREFIX_OP ; %% test2.output
State 4 2 exp: exp . DOUBLE_PLUS 3 | DOUBLE_PLUS exp . DOUBLE_PLUS shift, and go to state 6 DOUBLE_PLUS [reduce using rule 3 (exp)] $default reduce using rule 3 (exp) This example produces a shift/reduce conflict, because there is ambiguity in the reduction of DOUBLE_PLUS exp DOUBLE_PLUS. So i tried to assign a higher precedence to DOUBLE_PLUS exp than exp DOUBLE_PLUS, but that doesn't work either. It is possible to resolve this conflict by assigning a left or right precedence to the terminal DOUBLE_PLUS and i'm guessing assigning a left precedence means that exp DOUBLE_PLUS gets reduced first and right means DOUBLE_PLUS exp gets reduced first, but i'm also hoping that there is some way of doing this just by using the %prec annotation.
I'm also unsure if i understand the .output file correctly. The . in the rules indicates what's on the stack and what the lookahead token is, but why is the rule 2 in the latter example even mentioned then? I mean exp: exp . DOUBLE_PLUS shouldn't be of any conflicts?