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
你会明白我所说的优先级是什么意思,因为乘法规则出现在加法规则之前——因此绑定更早——这是一个数学约定(缺少分组术语的括号。)
您做得对,解析器也是。如果您想要特定的绑定顺序,只需将您想要的分组即可。
根据我所阅读的我定义 '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
你会明白我所说的优先级是什么意思,因为乘法规则出现在加法规则之前——因此绑定更早——这是一个数学约定(缺少分组术语的括号。)
您做得对,解析器也是。如果您想要特定的绑定顺序,只需将您想要的分组即可。