0

对于一个编译项目,我和我的团队正在用 Antlr 定义一个语法。我们目前对这些规则有疑问:

expr: ...
| lvalue expr3 expr2
|  ID '('exprList')' expr2
|... ;


lvalue: ID lvalue2;

lvalue2: '.' ID lvalue2
    | '[' expr ']' lvalue2
    | ;

如您所见,左值可以产生 ID,从而导致非 LL( ) 语法。所以我的问题是:我们如何修改语法以使其成为 LL( ) 而不允许额外的东西。

先感谢您 !

4

1 回答 1

0

事实上,你可以重构规则,但另一方面,它不是你在那里使用的左递归构造,所以你的结论不再是 LL(k) 是不正确的。您所拥有的只是两个以相同标记开头的替代方案。如上所述,将其排除在外是克服这种情况的一种方法。另一种是简单地增加前瞻,这允许解析器还检查以下标记以决定采用哪个 alt。

您可以在语法选项中设置前瞻值:

options {
  k = 2;
}

或在特定规则中仅增加该规则的值:

expr options { k = 2; }: ...
| lvalue expr3 expr2
|  ID '('exprList')' expr2
|... ;

注意: ANTLR 4 没有这种问题,因为它总是有无限的前瞻。

于 2016-02-18T08:05:46.143 回答