我目前正在尝试为一种简单的编程语言构建解析器。解析器生成正常,但显示此警告:
Warning: Choice conflict involving two expansions at
line 238, column 7 and line 239, column 7 respectively.
A common prefix is: "(" "("
Consider using a lookahead of 3 or more for earlier expansion.
发生错误的代码如下:
void condition(): {}
{
<NOT> condition() condition_prime()
| <LPAREN> condition() <RPAREN> condition_prime()
| expression() compare_ops() expression() condition_prime()
}
void condition_prime(): {}
{
logical_ops() condition() condition_prime() | {}
}
我这样做是为了消除左递归,但是现在发生了警告。有什么办法可以避免这种警告?
构建expression()
非终端的代码如下:
void expression(): {}
{
fragment() expression_prime()
}
void expression_prime(): {}
{
binary_arith_op() fragment() expression_prime() | {}
}
void fragment(): {}
{
<ID> (<LPAREN> args_list() <RPAREN>)?
| <MINUS> <ID>
| <NUM>
| <DIGIT>
| <TRUE>
| <FALSE>
| <LPAREN> expression() <RPAREN>
}
存在选择冲突的原因是,在非终结符condition
的定义中有3个选择,第二个和第三个可以都以<LPAREN>
开头。这是因为expression
可以以<LPAREN>
开头。
错误消息建议使用至少3的超前值。但是,仅将前瞻量更改为任何有限的数量是不够的。例如,如果将其更改为17,那么如果condition
以左括号开头,后跟一个16个令牌长或更多的表达式,那将是不够的。
您可以通过语法先行解决问题。