对于+, - ,/,*等的正确优先级评估,正确的语法应该是什么?

XBo*_*ond 5 antlr4

我的语法有这些规则

 expression
: expression EQ conditionalOrExpression                     #eqExpr
 | expression NEQ conditionalOrExpression                   #neqExpr
 | expression LT conditionalOrExpression                    #ltExpr
 | expression GT conditionalOrExpression                    #gtExpr
 | expression LTEQ conditionalOrExpression                  #lteqExpr
 | expression GTEQ conditionalOrExpression                  #gteqExpr
 | conditionalOrExpression                                  #next       
;

conditionalOrExpression
 : conditionalOrExpression OR conditionalAndExpression      #orExpr
 | conditionalAndExpression                                 #and
 ;

conditionalAndExpression
 : conditionalAndExpression AND additiveExpression          #andExpr
 | additiveExpression                                       #add
 ;

additiveExpression
 : additiveExpression PLUS multiplicativeExpression         #plusExpr
 | additiveExpression MINUS multiplicativeExpression        #minusExpr
 | multiplicativeExpression                                 #multiplicative
 ;

multiplicativeExpression
 : multiplicativeExpression MULT unaryExpression            #multExpr
 | multiplicativeExpression DIV unaryExpression             #divExpr
 | unaryExpression                                          #unary
 ;

unaryExpression
 : MINUS unaryExpression                                    #unaryMinusExpr
 | NOT unaryExpression                                      #notExpr
 | atom                                                     #atomExpr
 ;

function
: ID OPAR (parameter (',' parameter)*)? CPAR
;

parameter
: STRING                                                    #stringParameter
| expression                                                #exprParameter
;

atom
 : OPAR expression CPAR                                     #parExpr
 | (INT | FLOAT)                                            #numberAtom
 | (TRUE | FALSE)                                           #booleanAtom
 | ID                                                       #idAtom
 | function                                                 #functionAtom
 ;
Run Code Online (Sandbox Code Playgroud)

我已经实施了适当的访客.

如果我评估"40 + 10 - (2*40)+(100/40)+ 0.2",结果为-32.7.这是因为表达式被评估为

(40+10) - (((2*40) + (100/40)) + 0.2) 
Run Code Online (Sandbox Code Playgroud)

根据规则有意义(MINUS前加PLUS).

但是,如果我在Excel中评估相同的表达式或者例如在C#中将其分配给double,则在两种情况下结果都是-27.3.这是因为他们将规则评估为

(((40+10)-(2*40)) + (100/40)) + 0.2
Run Code Online (Sandbox Code Playgroud)

哪个是"正确的"?-32.7在技术上是正确的,因为这是规则所要求的.但是如何改变语法以匹配Excel/C#中的结果?

Bar*_*ers 5

如果你组+-在一个另类,它应该工作.我在GitHub上的演示评估程序中更改了语法,如下所示:

expr
 : expr POW<assoc=right> expr           #powExpr
 | MINUS expr                           #unaryMinusExpr
 | NOT expr                             #notExpr
 | expr op=(MULT | DIV | MOD) expr      #multiplicationExpr
 | expr op=(PLUS | MINUS) expr          #additiveExpr
 | expr op=(LTEQ | GTEQ | LT | GT) expr #relationalExpr
 | expr op=(EQ | NEQ) expr              #equalityExpr
 | expr AND expr                        #andExpr
 | expr OR expr                         #orExpr
 | atom                                 #atomExpr
 ;
Run Code Online (Sandbox Code Playgroud)

然后使用以下代码进行测试:

MuLexer lexer = new MuLexer(new ANTLRInputStream("log(40 + 10 - (2*40) + (100/40) + 0.2);"));
MuParser parser = new MuParser(new CommonTokenStream(lexer));
new EvalVisitor().visit(parser.parse());
Run Code Online (Sandbox Code Playgroud)

该值-27.3将打印在我的控制台上.