【问题标题】:Antlr, rule which could result the same as anotherAntlr,可能导致与另一个相同的规则
【发布时间】:2016-02-17 10:20:51
【问题描述】:

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

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


lvalue: ID lvalue2;

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

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

提前谢谢你!

【问题讨论】:

  • 你必须考虑到它:expr : ID (lvalue2 expr3 | '(' exprList ')') expr2;
  • 哦,是的,现在看起来很明显。谢谢!

标签: antlr grammar ll tiger


【解决方案1】:

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

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

options {
  k = 2;
}

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

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

注意: ANTLR 4 不存在此类问题,因为它始终具有无限前瞻。

【讨论】:

  • 感谢您的回答。 Antlrworks 向我显示了一个非 LL(*) 错误,所以我猜我的语法不是 LL(k)。主要问题是我们必须使它成为 LL(1),所以我不能使用你的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
相关资源
最近更新 更多