Antlr4 表达式是链接的

Antlr4 expressions are chaining

根据我所阅读的我定义 'expression' 的方式,这应该为我提供以下内容:

这是我的输入:

xyz = a + b + c + d

这应该是我的输出:

xyz = ( ( a + b ) + ( c + d) ) 

但我得到的是:

xyz = ( a + (b + (c + d) ) )

我敢打赌这之前已经解决了,我只是找不到解决方案。

statementList       : s=statement sl=statementList  #multipleStatementList
                    | s=statement                   #singleStatementList
                    ;

statement           : statementAssign
                    | statementIf
                    ;

statementAssign     : var=VAR ASSIGN expr=expression        #overwriteStatementAssign
                    | var=VAR PLUS ASSIGN expr=expression   #addStatementAssign
                    | var=VAR MINUS ASSIGN expr=expression  #subStatementAssign
                    ;


                    ;

expression          : BRACKET_OPEN expr=expression BRACKET_CLOSE                    #priorityExp
                    | left=expression operand=('*'|'/') right=expression            #mulDivExp
                    | left=expression operand=('+'|'-') right=expression            #addSubExp
                    | <assoc=right> left=expression POWER right=expression          #powExp
                    | variable=VAR                                                  #varExp
                    | number=NUMBER                                                 #numExp
                    ;



BRACKET_OPEN        : '(' ;
BRACKET_CLOSE       : ')' ;

ASTERISK            : '*' ;
SLASH               : '/' ;
PLUS                : '+' ;
MINUS               : '-' ;
POWER               : '^' ;
MODULO              : '%' ;


ASSIGN              : '=' ;

NUMBER              : [0-9]+ ;

VAR                 : [a-z][a-zA-Z0-9\-]* ;

WS                  : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines

如果你想要表达式

 xyz = ( ( a + b ) + ( c + d) ) 

然后您需要控制 + 运算符与括号的绑定,就像您在预期输出中所做的那样。否则,使用

 xyz = ( a + (b + (c + d) ) )

是解析器解析它的方式,因为所有 + 运算符都具有相同的优先级,并且解析器会继续解析直到到达表达式的末尾。

递归应用

left=expression operand=('+'|'-') right=expression 

直到表达式完成。

你得到了你得到的分组。所以使用这些括号,如果你想强制表达式评估的顺序,这就是它们的用途。 ;)

如果您将输入更改为

xyz = a * b + c + d

你会明白我所说的优先级是什么意思,因为乘法规则出现在加法规则之前——因此绑定更早——这是一个数学约定(缺少分组术语的括号。)

您做得对,解析器也是。如果您想要特定的绑定顺序,只需将您想要的分组即可。