我现在在JavaCC上遇到了一个单一的问题。 我已经定义了语法,语言是LL(1),并且所有左递归都已删除。 我收到一个选择冲突错误(下面转储)。 我相信这是由线路expr2()
线路调用自己并引起冲突引起的。 老实说,我完全被难住了。 我什至不知道如何解决问题。
下面是生成警告的代码片段:
void expr() : {}
{
<LBRAC> arg_list() <RBRAC> expression2()
}
void expr2() : {}
{
section() (<SUB>|<ADD>|<MUL>|<DIV>|<MOD> section())* expr2()
| {}
}
void section() : {}
{
<IDENTIFIER> | <TRUE> | <FALSE> | <REAL> | (<ADD> | <SUB>) section() | expr()
}
警告是:
Warning:
Choice conflict in (...)* construct at line 233, column 14.
Expansion nested within construct and expansion following construct
have common prefixes, one of which is: "-"
Consider using a lookahead of 2 or more for nested expansion.
Parser generated with 0 errors and 1 warnings.
其中第 233 行对应于 expr2() 中的第一行
@Juan Lopes写道:
考虑"2 + 2"。"+"是
expr2()
时的<ADD>
还是<ADD>
section()
?
OP回答说:
我可以从
section()
中删除 Add/Sub 命令,但它仍然会导致同样的问题。我明白你的意思,但这似乎并没有引起问题。
@Theodore诺维尔写道:
胡安说的完全正确。但是将
(<ADD> | <SUB>) section()
改为section()
引入了一个新问题。尝试将expr2
正文中的第一行更改为section() (<MUL>|<DIV>|<MOD> section())* expr2()
或section() ((<MUL>|<DIV>|<MOD>) section())* expr2()
,具体取决于您的实际需求。如果这不起作用,请提出一个新问题。胡安已经回答了这个问题。