AnTLR4优先考虑的奇怪行为

AnTLR4优先考虑的奇怪行为,antlr,grammar,antlr4,Antlr,Grammar,Antlr4,我有一个非常简单的测试语法,如下所示: grammar Test; statement: expression EOF; expression : Identifier | expression binary_op expression | expression assignment_operator expression | expression '.' Identifier ; binary_op: '+

我有一个非常简单的测试语法,如下所示:

grammar Test;

statement: expression EOF;

expression
    :   Identifier
        |   expression binary_op expression
        |   expression assignment_operator expression
        |   expression '.' Identifier 
    ;

binary_op: '+';
assignment_operator : '='  ;

Identifier : [a-zA-Z]+ ;
WS : [ \n\r\t]+ -> channel(HIDDEN) ;
使用此版本的语法,如果我编写以下代码,我将获得预期的行为:

b.x + b.y 
我得到一棵树,名为
(+(.bx)(.by))

但是,如果我用
表达式“+”表达式替换
表达式二进制表达式
,我会得到一个非常不同的树:
(+(.bx)by)

有什么解释吗


谢谢

解析器中的文字可能会混淆问题。检查并修复生成解析器时报告的错误/警告。可能需要将文本从解析器规则移动到lexer规则

您可以验证lexer是否按预期运行。这将为理解解析器的路径提供一个清晰的基础

更新

对于Antlr4解析树,您列出的两种解析树表示形式都不合适。尽管如此,我还是尝试了你的两种语法变体,我始终得到:

令牌转储:

Identifier: [@0,0:0='b',<4>,1:0]
Dot: [@1,1:1='.',<3>,1:1]
Identifier: [@2,2:2='x',<4>,1:2]
null: [@4,4:4='+',<1>,1:4]
Identifier: [@6,6:6='b',<4>,1:6]
Dot: [@7,7:7='.',<3>,1:7]
Identifier: [@8,8:8='y',<4>,1:8]

此特定令牌转储中的
null
s是因为符号是首先在解析器中定义的。

您必须使用如下内容设置前置:

expr  : expr2 (assignment_operator expr3)?  # Equals
expr2 : expr1 (binary_op expr2)?            # Add
expr1 : Identifier | 
        expr1 . Identifier
      ;

这消除了运算符进位的所有歧义。

将文本从解析器规则移动到lexer规则没有任何区别。我测试过。:)
ParseTree tree = parser.statement();
System.out.print(tree.toStringTree(parser));
expr  : expr2 (assignment_operator expr3)?  # Equals
expr2 : expr1 (binary_op expr2)?            # Add
expr1 : Identifier | 
        expr1 . Identifier
      ;