对于编译项目,我的小组和我正在使用Antlr定义语法。 我们目前有这些规则的问题:
expr: ...
| lvalue expr3 expr2
| ID '('exprList')' expr2
|... ;
lvalue: ID lvalue2;
lvalue2: '.' ID lvalue2
| '[' expr ']' lvalue2
| ;
如您所见,左值可能会导致ID,从而导致非LL()语法。 所以我的问题是:如何在不允许额外内容的情况下修改语法以使其成为LL()。
提前谢谢!
答案 0 :(得分:0)
确实你可以重构规则,但另一方面它不是你在那里使用的左递归构造,所以你的结论将不再是LL(k)是不正确的。你所拥有的只有两个以相同的标记开头的选择。如上所述,考虑到这一点是克服这种情况的一种方法。另一个是简单地增加前瞻,这允许解析器还检查后续标记以决定采取哪个alt。
您可以在语法选项中设置前瞻值:
options {
k = 2;
}
或在特定规则中仅增加该规则的值:
expr options { k = 2; }: ...
| lvalue expr3 expr2
| ID '('exprList')' expr2
|... ;
注意: ANTLR 4没有这种问题,因为它始终具有无限的前瞻性。