当我试图使用Lemon编译这个简单的解析器时,我遇到了冲突,但我看不出哪个规则是错误的。如果删除二进制表达式或被调用表达式,冲突就会消失。
%left Add.
program ::= expression.
expression ::= binaryexpression.
expression ::= callexpression.
binaryexpression ::= expression Add expression.
callexpression ::= expression arguments.
arguments ::= LParenthesis argumentlist RParenthesis.
arguments ::= LParenthesis RParenthesis.
argumentlist ::= expression argumentlist.
argumentlist ::= expression.
[edit]为L关联添加左侧关联性解决了冲突。然而,我愿意知道这样做是否正确:我已经看到一些语法(例如C++)对构造运算符"()"和调用运算符"(")有不同的优先级。所以我不确定该做什么。
问题是语法不明确。在不查看所有输入序列的情况下,不可能决定是减少到binaryexpression
还是callexpression
。模糊性是由于expression
上的左递归,而expression
无法导出终端,因此无法结束该递归。