语法定义
根据我的理解,ANTLR4支持左递归以尊重算术的优先顺序。下面是语法:
grammar Arithmetic;
arithmetic: arithmeticExpression;
arithmeticExpression:
LPARAN inner = arithmeticExpression RPARAN # Parentheses
| left = arithmeticExpression POW right = arithmeticExpression # Power
| left = arithmeticExpression MUL right = arithmeticExpression # Multiplication
| left = arithmeticExpression DIV right = arithmeticExpression # Division
| left = arithmeticExpression ADD right = arithmeticExpression # Addition
| left = arithmeticExpression SUB right = arithmeticExpression # Subtraction
| arithmeticExpressionInput # ArithmeticInput;
arithmeticExpressionInput: NUMBER;
number: NUMBER;
/* Operators */
LPARAN: '(';
RPARAN: ')';
POW: '^';
MUL: '*';
DIV: '/';
ADD: '+';
SUB: '-';
/* Data Types */
NUMBER: '-'? [0-9]+;
/* Whitespace & End of Lines */
EOL: '\r'? '\n';
WS: [ \t]+ -> channel(HIDDEN);注意:我简化了测试语法。
输入
5 + 21 / 7 * 3输出分析树

问题
在从arithmetic开始的输出解析树中。您可以看到,优先顺序并不遵循PEMDAS,即使它是通过语法中的左递归来定义的。在调试Antlr生成的访问者代码(函数调用为VisitAddition )时,也会观察到这一点。
我在谷歌上搜索了这个,我看不出我做错了什么,因为它们看起来都是一样的。
环境
反版本: 4.11.1
构建目标: CSharp
.NET项目包:
发布于 2022-09-17 22:28:39
正如@sepp2k评论中提到的(谢谢)。
问题在于语法,因为multiplication、division、addition和subtraction都被分割成单独的OR规则行。本质上是在应该是PE(MD)(AS)的时候创建PEMDAS。
下面是一个固定语法的例子:
arithmeticExpression:
arithmeticExpressionInput # ArithmeticInput
| LPARAN inner = arithmeticExpression RPARAN # Parentheses
| left = arithmeticExpression operator = POW right = arithmeticExpression # Power
| left = arithmeticExpression operator = (MUL|DIV) right = arithmeticExpression #
MultiplicationOrDivision
| left = arithmeticExpression operator = (ADD|SUB) right = arithmeticExpression #
AdditionOrSubtraction;现在输出的解析树要干净得多:

https://stackoverflow.com/questions/73757087
复制相似问题