0

这是错误:

    12 shift/reduce conflicts

error:  state 34: shift/reduce conflict (shift OR, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift AND, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift GE, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift GT, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift LE, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift LT, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift NEQ, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift EQ, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift DIVIDE, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift TIMES, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift MINUS, reduce by rule 11)
error:  state 34: shift/reduce conflict (shift PLUS, reduce by rule 11)

这是语法:

program : exp               ()

exp:

 exp binop exp             ()
|  ID                      ()
| lvalue                 ()
| STRING                    ()
| INT                       ()
| NIL                       ()
| LPAREN expseq RPAREN      ()
| lvalue ASSIGN exp         ()
| ID LPAREN explist RPAREN  ()
| LET declist IN expseq END ()
| IF exp THEN exp ELSE exp  ()
| IF exp THEN exp           ()


binop:
    EQ      ()
|   NEQ      ()
|   LT       ()
|   GT       ()
|   LE       ()
|   GE       ()
|   AND      ()
|   OR       ()
|   PLUS     ()
|   MINUS    ()
|   TIMES    ()
|   DIVIDE   ()

我该如何解决这个问题?我是否需要重新思考语法并找到另一种方式来描述这种语法?

我也尝试过声明偏好顺序(尽管我使用这些的经验非常少),例如:

%nonassoc OR NEQ EQ LT LE GT GE AND

%right PLUS MINUS
%right TIMES DIVIDE

但什么都没有。

4

1 回答 1

1

冲突都来自exp: exp binop exp规则的模糊性——像a+b*c这样带有两个二进制运算的输入可以被解析为(a+b)*ca+(b*c)

要解决这个问题,最简单的方法是为令牌所涉及的规则设置优先级。您已经为令牌做到了这一点,但还没有为 rule 做到这一点exp: exp binop exp。不幸的是,您只能为每个规则设置一个优先级,并且此规则需要不同的优先级,具体取决于匹配的令牌binop。最简单的解决方案是复制规则并摆脱binop

exp : exp EQ exp
    | exp NEQ exp
    | exp LE exp
    | exp GT exp
    | exp LE exp
    | exp GE exp
    | exp AND exp
    | exp OR exp
    | exp PLUS exp
    | exp MINUS exp
    | exp TIMES exp
    | exp DIVIDE exp

现在每个标记都有自己的规则版本,并且每个规则都会自动从其中的单个标记中获取其优先级,因此您甚至不需要显式设置规则的优先级,yacc 会为您完成。

于 2016-03-19T19:50:56.927 回答