2017-02-16 138 views
1

我正在经历在Appel的“ML中的现代编译器实现”一书中生成Tiger Parser的Ch3编程练习。我的tiger.grm文件是here。我试图诊断的错误是由一元和二元减算子的规则引起的减少 - 减少冲突。这里是YACC错误:ML-Yacc Tiger Parser减少/减少错误

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 

我已经定义与UNARY低于零下更高的优先级,并且在使用%prec我的规则明确设置它。当然,当我删除任一规则时,冲突消失,但语法会错误地解析MINUS标志。

我无法诊断此错误 - 任何想法?

回答

3

疯狂的猜测:你的规则之一可能允许exp为空吗?如果是这样,那么这会在exp是可选的任何地方产生歧义 - 例如在- exp之前。

2

作为接受的答案(他/她是对的)的后续 - 在序列的生产中出现了一个错误,允许exp转到epsilon

这里是问题的代码位(见最后一行):

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*) 

这里是校正后的代码:

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*)