ML-Yacc Tiger 解析器 Reduce/Reduce 错误
ML-Yacc Tiger Parser Reduce/Reduce error
我正在完成 Appel "Modern Compiler Implementation in 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
在我的规则中明确设置它。当然,当我删除任何一条规则时,冲突都会消失,但语法会错误地解析减号。
我无法诊断出这个错误 - 有什么想法吗?
大胆猜测:是否有可能您的规则之一允许 exp
为空?如果是这样,那么在 exp
是可选的任何地方都会产生歧义——比如在 - exp
.
之前
作为已接受答案的后续行动(he/she 是正确的)- 在制作允许 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*)
我正在完成 Appel "Modern Compiler Implementation in 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
在我的规则中明确设置它。当然,当我删除任何一条规则时,冲突都会消失,但语法会错误地解析减号。
我无法诊断出这个错误 - 有什么想法吗?
大胆猜测:是否有可能您的规则之一允许 exp
为空?如果是这样,那么在 exp
是可选的任何地方都会产生歧义——比如在 - exp
.
作为已接受答案的后续行动(he/she 是正确的)- 在制作允许 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*)