我的语法有这些规则
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#中的结果?
如果你组+并-在一个另类,它应该工作.我在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将打印在我的控制台上.
| 归档时间: |
|
| 查看次数: |
2983 次 |
| 最近记录: |