我有一个非常简单的测试语法如下:
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
我得到一棵树(+ (. b x) (. b y))
但是,如果我将expression binary_op expression
替换为expression '+' expression
,我会得到一个非常不同的树:(. (+ (. b x) b) y)
对此有任何解释吗?
由于
答案 0 :(得分:0)
解析器中的文字可能会使事情混乱。检查并修复生成解析器时报告的错误/警告。可能需要将文字从解析器规则移动到词法分析器规则。
您可以验证词法分析器是否按dumping the token stream的预期运行。这将为理解解析器所采用的路径提供明确的基础。
<强>更新强>
您列出的任何解析树表示都不适合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]
树转储:
(statement (expression (expression (expression (expression b) . x) + (expression b)) . y) <EOF>)
使用
ParseTree tree = parser.statement();
System.out.print(tree.toStringTree(parser));
此特定令牌转储中的null
是因为符号首先在解析器中定义。
答案 1 :(得分:0)
您必须使用以下内容设置优先级:
sample
这消除了对运算符优先级的所有歧义。