在LL1语法中没有预见的JavaCC选择冲突警告

时间:2014-12-16 21:50:00

标签: compiler-construction javacc

我试图从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>

1 个答案:

答案 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讨论了类似的案例。事实上,它是如此相似,以至于我想知道这不是一个每年都在重复使用的课程的作业。如果是这种情况,请务必引用堆栈溢出交换作为您提交的一部分,以免犯下学术上的不诚实行为。