ML-Yacc Tiger Parser Reduce/Reduce error

277 views Asked by At

I am going through the Ch3 programming exercise of generating a Tiger Parser in Appel's "Modern Compiler Implementation in ML" book. My tiger.grm file is here. The error I am trying to diagnose is a reduce-reduce conflict arising from rules for unary and binary minus operator. Here is the yacc error:

error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on OR
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on AND
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on GE
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on GT
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on LE
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on LT
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on NEQ
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on EQ
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on DIVIDE
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on TIMES
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on MINUS
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on PLUS
error:  state 128: reduce/reduce conflict between rule 48 and rule 46 on RPAREN

state 128:

    boolean : exp . AND exp 
    boolean : exp . OR exp 
    arithmetic : MINUS exp .  (reduce by rule 46)
    arithmetic : exp . PLUS exp 
    arithmetic : exp . MINUS exp 
    arithmetic : exp MINUS exp .  (reduce by rule 48)
    arithmetic : exp . DIVIDE exp 
    arithmetic : exp . TIMES exp 
    comparison : exp . EQ exp 
    comparison : exp . NEQ exp 
    comparison : exp . GT exp 
    comparison : exp . LT exp 
    comparison : exp . LE exp 
    comparison : exp . GE exp 

I have defined UNARY with higher precedence than MINUS, and set it explicitly in my rule using %prec. Of course, when I remove either rule, the conflict disappears, but the grammar will parse the MINUS sign incorrectly.

I am unable to diagnose this error - any ideas?

2

There are 2 answers

0
ruakh On BEST ANSWER

Wild guess: is it possible that one of your rules allows an exp to be empty? If so, then that would create an ambiguity anywhere that exp is optional -- such as before - exp.

0
aspen100 On

As a follow up to the accepted answer (he/she was right) - there was a mistake in the production for sequences that allowed exp to go to epsilon.

Here is the offending bit of code (see last line):

sequence : LPAREN exp_sequence RPAREN ()
exp_sequence : (*epsilon*) ()
         | exp seq     ()

seq : (*epsilon*)                () (*an exp sequence can be empty*)
    | SEMICOLON exp exp_sequence () (*exps separated by semicolon*)

Here is the corrected code:

sequence : LPAREN exp_sequence RPAREN ()
exp_sequence : (*epsilon*) ()
             | exp seq     ()

seq : (*epsilon*)                () (*an exp sequence can be empty*)
    | SEMICOLON exp seq () (*exps separated by semicolon*)