我试图从LL(1)中的javacc语法中删除选择冲突(没有预见):
我已经定义了语法
我知道我必须做一些左保理,但我很难知道如何去做这个:左
以下是一些示例代码:
void expression2() :{}{
fragment() (<MULT_SIGN>|<DIV_SIGN>|<MOD_SIGN> fragment())* (expression2()| {})
}
void fragment() :{}{
<ID>
|<LEFTPARENTHESES>arg_list()<RIGHTPARENTHESES>
|<TRUE>
|<FALSE>
|<NUM>
|(<PLUS_SIGN>|<MINUS_SIGN>)fragment()
}
void condition() :{}{
<NOT>expression2()|expression2()
(<EQ_SIGN>|<NOT_EQUAL_SIGN>|<LESS_THAN_SIGN>|<GREATER_THAN_SIGN>|<LESS_THAN_OR_EQUAL_SIGN>|<GREATER_THAN_OR_EQUAL_SIGN>|<AND>|<OR>)expression2()
|<ID>
}
警告是:
Warning: Choice conflict involving two expansions at
line 226, column 20 and line 228, column 2 respectively.
A common prefix is: <ID>
Consider using a lookahead of 2 for earlier expansion.
哪里:
第226行,第20列对应于第一行条件()中的第二个表达式2()
第228行,第2列对应于最后一行条件()中的<ID>
答案 0 :(得分:1)
假设您要解析condition
而下一个令牌是ID
以下是可能的
condition()
==> 4th choice for condition
<Id>
和
condition()
==> 2nd choice for condition
expression2() (<EQ_SIGN>|...) expression2()
==> the only choice for expression2
fragment() (<MULT_SIGN>|<DIV_SIGN>|<MOD_SIGN> fragment())* (expression2()| {}) (<EQ_SIGN>|...) expression2()
==> the first choice for fragment
<ID> (<MULT_SIGN>|<DIV_SIGN>|<MOD_SIGN> fragment())* (expression2()| {}) (<EQ_SIGN>|...) expression2()
因此,鉴于解析器希望看到condition
而下一个令牌是<ID>
,condition
的第2或第4个选项都可行。
至于如何解决它。在Javacc Unreachable Statement讨论了类似的案例。事实上,它是如此相似,以至于我想知道这不是一个每年都在重复使用的课程的作业。如果是这种情况,请务必引用堆栈溢出交换作为您提交的一部分,以免犯下学术上的不诚实行为。