Search code examples
compiler-constructiongrammarbisonbnfshift-reduce-conflict

Shift reduce conflicts in mid rule action bison


I have the following grammar that is giving me three shift reduce conflicts:

boolexpression:         boolexpression OR boolterm 
                        | boolterm ;

boolterm:              boolterm AND boolfact
                        | boolfact;

boolfact:               "!" "(" boolexpression ")"
                        | "(" boolexpression ")"
                        | BOOLLITERAL
                        | expression boolop expression

boolop:                 "<"| ">"| BOOLOPLEQ /* <= */ | BOOLOPGEQ /* >= */ | BOOLOPEQ /* == */ | BOOLOPNEQ /* != */; 

expression:             sum ;

sum:                    sum "+" term         
                        | sum "-" term      
                        | term ;

term:                 term "*" factor
                        | term "/" factor 
                        | factor;

factor:                 ID        
                        | NUMBER       
                        | "(" {/* rules to generate IR/*} expression ")";

When I remove {/* rules to generate IR/*}, everything works fine.


Solution

  • This conflict is because you have a mid rule action immedietely after "(" in the factor rule. In this case you can't do this because the reductions boolfact --> "(" boolexpression ")" and factor --> "(" {/* rules to generate IR/*} expression ")" both contain the "(" token as their first token recognized. So when bison recognizes a "(", it doesn't know which rule to reduce to.

    One solution is to place {/* rules to generate IR/} somehwere after expression in "(" {/ rules to generate IR/*} expression ")";. There is also more helpful information found at https://www.gnu.org/software/bison/manual/html_node/Mid_002dRule-Conflicts.html#Mid_002dRule-Conflicts.