首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Antlr4算法语法忽略优先顺序(PEMDAS)

Antlr4算法语法忽略优先顺序(PEMDAS)
EN

Stack Overflow用户
提问于 2022-09-17 17:28:11
回答 1查看 52关注 0票数 -1

语法定义

根据我的理解,ANTLR4支持左递归以尊重算术的优先顺序。下面是语法:

代码语言:javascript
复制
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);

注意:我简化了测试语法。

输入

代码语言:javascript
复制
5 + 21 / 7 * 3

输出分析树

问题

在从arithmetic开始的输出解析树中。您可以看到,优先顺序并不遵循PEMDAS,即使它是通过语法中的左递归来定义的。在调试Antlr生成的访问者代码(函数调用为VisitAddition )时,也会观察到这一点。

我在谷歌上搜索了这个,我看不出我做错了什么,因为它们看起来都是一样的。

环境

反版本: 4.11.1

构建目标: CSharp

.NET项目包:

  1. Antlr4BuildTasks@11.1.0
  2. Antlr4.Runtime.Standard@4.11.1
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-17 22:28:39

正如@sepp2k评论中提到的(谢谢)。

问题在于语法,因为multiplicationdivisionadditionsubtraction都被分割成单独的OR规则行。本质上是在应该是PE(MD)(AS)的时候创建PEMDAS。

下面是一个固定语法的例子:

代码语言:javascript
复制
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;

现在输出的解析树要干净得多:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73757087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档