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?