【问题标题】:ML-Yacc Tiger Parser Reduce/Reduce errorML-Yacc Tiger Parser 减少/减少错误
【发布时间】:2017-02-16 03:02:32
【问题描述】:

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

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 的优先级高于 MINUS,并使用 %prec 在我的规则中明确设置它。当然,当我删除任一规则时,冲突就会消失,但语法会错误地解析 MINUS 符号。

我无法诊断此错误 - 有什么想法吗?

【问题讨论】:

    标签: parsing compiler-construction sml tiger ml-yacc


    【解决方案1】:

    大胆猜测:您的一条规则是否允许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*)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-14
        • 2010-12-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多