Skip to content

Commit

Permalink
Fixed operator precedence by grouping [+ -], [* / %], [< <= > >=] and…
Browse files Browse the repository at this point in the history
… [== !=] into single rules.
  • Loading branch information
bartkiers committed Aug 21, 2014
1 parent f379faf commit f51b791
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 82 deletions.
27 changes: 10 additions & 17 deletions src/main/antlr4/mu/Mu.g4
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,16 @@ log
;

expr
: expr POW<assoc=right> expr #powExpr
| MINUS expr #unaryMinusExpr
| NOT expr #notExpr
| expr MOD expr #modExpr
| expr MULT expr #multExpr
| expr DIV expr #divExpr
| expr PLUS expr #plusExpr
| expr MINUS expr #minusExpr
| expr LTEQ expr #lteqExpr
| expr GTEQ expr #gteqExpr
| expr LT expr #ltExpr
| expr GT expr #gtExpr
| expr NEQ expr #neqExpr
| expr EQ expr #eqExpr
| expr AND expr #andExpr
| expr OR expr #orExpr
| atom #atomExpr
: 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
;

atom
Expand Down
114 changes: 49 additions & 65 deletions src/main/java/mu/EvalVisitor.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package mu;

import org.antlr.v4.runtime.misc.NotNull;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -80,96 +82,78 @@ public Value visitNotExpr(MuParser.NotExprContext ctx) {
}

@Override
public Value visitMultExpr(MuParser.MultExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
return new Value(left.asDouble() * right.asDouble());
}

@Override
public Value visitModExpr(MuParser.ModExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
return new Value(left.asDouble() % right.asDouble());
}
public Value visitMultiplicationExpr(@NotNull MuParser.MultiplicationExprContext ctx) {

@Override
public Value visitDivExpr(MuParser.DivExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
return new Value(left.asDouble() / right.asDouble());
}

@Override
public Value visitPlusExpr(MuParser.PlusExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
if(left.isDouble() && right.isDouble()) {
return new Value(left.asDouble() + right.asDouble());
}
else {
return new Value(left.asString() + right.asString());
switch (ctx.op.getType()) {
case MuParser.MULT:
return new Value(left.asDouble() * right.asDouble());
case MuParser.DIV:
return new Value(left.asDouble() / right.asDouble());
case MuParser.MOD:
return new Value(left.asDouble() % right.asDouble());
default:
throw new RuntimeException("unknown operator: " + MuParser.tokenNames[ctx.op.getType()]);
}
}

@Override
public Value visitMinusExpr(MuParser.MinusExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
return new Value(left.asDouble() - right.asDouble());
}
public Value visitAdditiveExpr(@NotNull MuParser.AdditiveExprContext ctx) {

@Override
public Value visitLtExpr(MuParser.LtExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
return new Value(left.asDouble() < right.asDouble());
}

@Override
public Value visitLteqExpr(MuParser.LteqExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
return new Value(left.asDouble() <= right.asDouble());
switch (ctx.op.getType()) {
case MuParser.PLUS:
return left.isDouble() && right.isDouble() ?
new Value(left.asDouble() + right.asDouble()) :
new Value(left.asString() + right.asString());
case MuParser.MINUS:
return new Value(left.asDouble() - right.asDouble());
default:
throw new RuntimeException("unknown operator: " + MuParser.tokenNames[ctx.op.getType()]);
}
}

@Override
public Value visitGtExpr(MuParser.GtExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
return new Value(left.asDouble() > right.asDouble());
}
public Value visitRelationalExpr(@NotNull MuParser.RelationalExprContext ctx) {

@Override
public Value visitGteqExpr(MuParser.GteqExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
return new Value(left.asDouble() >= right.asDouble());
}

@Override
public Value visitNeqExpr(MuParser.NeqExprContext ctx) {
Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
if(left.isDouble() && right.isDouble()) {
double diff = Math.abs(left.asDouble() - right.asDouble());
return new Value(diff >= SMALL_VALUE);
}
else {
return new Value(!left.equals(right));
switch (ctx.op.getType()) {
case MuParser.LT:
return new Value(left.asDouble() < right.asDouble());
case MuParser.LTEQ:
return new Value(left.asDouble() <= right.asDouble());
case MuParser.GT:
return new Value(left.asDouble() > right.asDouble());
case MuParser.GTEQ:
return new Value(left.asDouble() >= right.asDouble());
default:
throw new RuntimeException("unknown operator: " + MuParser.tokenNames[ctx.op.getType()]);
}
}

@Override
public Value visitEqExpr(MuParser.EqExprContext ctx) {
public Value visitEqualityExpr(@NotNull MuParser.EqualityExprContext ctx) {

Value left = this.visit(ctx.expr(0));
Value right = this.visit(ctx.expr(1));
if(left.isDouble() && right.isDouble()) {
double diff = Math.abs(left.asDouble() - right.asDouble());
return new Value(diff < SMALL_VALUE);
}
else {
return new Value(left.equals(right));

switch (ctx.op.getType()) {
case MuParser.EQ:
return left.isDouble() && right.isDouble() ?
new Value(Math.abs(left.asDouble() - right.asDouble()) < SMALL_VALUE) :
new Value(left.equals(right));
case MuParser.NEQ:
return left.isDouble() && right.isDouble() ?
new Value(Math.abs(left.asDouble() - right.asDouble()) >= SMALL_VALUE) :
new Value(!left.equals(right));
default:
throw new RuntimeException("unknown operator: " + MuParser.tokenNames[ctx.op.getType()]);
}
}

Expand Down

0 comments on commit f51b791

Please sign in to comment.