ANTLR决策可以使用多个备选项匹配输入

8

我有这个简单的语法:

expr: factor;

factor: atom (('*' ^ | '/'^) atom)*;

atom: INT
    | ':' expr;

INT: ('0'..'9')+

当我运行它时,会显示:
决策可以使用多个替代方案1,2来匹配 '*' 等输入。
决策可以使用多个替代方案1,2来匹配 '/' 等输入。
我无法发现歧义。红色箭头指向哪里呢?任何帮助将不胜感激。 enter image description here

我的语法经验非常生疏,但你有一个左递归(expr -> factor -> atom -> expr),还可能有右递归...你真的想匹配像 :(1/2) * :3 这样的输入吗?你能给出要解析的输入示例吗? - DarkDust
这不是左递归的原子 -> ':' expr。我正在处理一个更大的语法,它有相同的问题,所以我发布了一个等效的示例来说明我的问题。 - John Retallack
好的,我的错误,不过如果您发布一个您认为有效的示例,这仍然会有所帮助。 - DarkDust
1个回答

7

假设你想解析输入:

:3*4*:5*6

您的语法生成的解析器可以将此输入匹配为以下解析树: enter image description here 以及: enter image description here 请注意,您所看到的只是一个警告。通过明确指示ANTLR需要贪婪地匹配`('*' | '/') atom)*`,如下所示:
factor
  :  atom (options{greedy=true;}: ('*'^ | '/'^) atom)*
  ;

解析器“知道”该选择哪个备选项,并且不会发出警告。

编辑

我使用ANTLR 3.3测试了语法,如下:

grammar T;

options {
  output=AST;
}

parse
  :  expr EOF!
  ;

expr
  :  factor
  ;

factor
  :  atom (options{greedy=true;}: ('*'^ | '/'^) atom)*
  ;

atom
  :  INT
  |  ':'^ expr
  ;

INT : ('0'..'9')+;

然后在命令行中执行:

java -cp antlr-3.3.jar org.antlr.Tool T.g

这不会产生任何警告(或错误)。


贪婪难道不是默认选项吗? - John Retallack
@JohnRetallack,是的,没错。这就是为什么在我的第一张图片中,无论是否使用options{greedy=true;},都会创建AST,只有在明确指定时,ANTLR才不会发出警告。 - Bart Kiers
@JohnRetallack,请查看我的EDIT以了解我如何运行测试。 - Bart Kiers
@JohnRetallack,是的,我刚刚检查了v3.2,我也看到了警告。虽然这个错误可能也存在于v3.3中(它应该仍然发出此警告,但实际上没有)。如果我是你,我会看看语法是否可以改变,以便不再存在这种歧义(如果可能的话)... - Bart Kiers
谢谢你的帮助。顺便说一下,我刚开始阅读你的博客文章《使用ANTLR创建自己的编程语言》,这是我到目前为止读过的最好的ANTLR介绍。 - John Retallack
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接