我只是将所有表达式包装成一条
expression规则。一定要定义
comparator的替代表述 之前
你
binary表达的替代,以确保
comparator运营商绑定更紧密比
OR和
AND:
grammar SimpleBoolean;parse : expression EOF ;expression : LPAREN expression RPAREN #parenexpression | NOT expression#notexpression | left=expression op=comparator right=expression #comparatorexpression | left=expression op=binary right=expression #binaryexpression | bool #boolexpression | IDENTIFIER #identifierexpression | DECIMAL #decimalexpression ;comparator : GT | GE | LT | LE | EQ ;binary : AND | OR ;bool : TRUE | FALSE ;AND : 'AND' ;OR : 'OR' ;NOT : 'NOT';TRUE : 'TRUE' ;FALSE : 'FALSE' ;GT : '>' ;GE : '>=' ;LT : '<' ;LE : '<=' ;EQ : '=' ;LPAREN : '(' ;RPAREN : ')' ;DECIMAL : '-'? [0-9]+ ( '.' [0-9]+ )? ;IDENTIFIER : [a-zA-Z_] [a-zA-Z_0-9]* ;WS : [ rtu000Cn]+ -> skip;要测试上面的语法,请使用以下快速测试类:
public class Main { public static void main(String[] args) throws Exception { Map<String, Object> variables = new HashMap<String, Object>() {{ put("A", true); put("a", true); put("B", false); put("b", false); put("C", 42.0); put("c", 42.0); put("D", -999.0); put("d", -1999.0); put("E", 42.001); put("e", 142.001); put("F", 42.001); put("f", 42.001); put("G", -1.0); put("g", -1.0); }}; String[] expressions = { "1 > 2", "1 >= 1.0", "TRUE = FALSE", "FALSE = FALSE", "A OR B", "B", "A = B", "c = C", "E > D", "B OR (c = B OR (A = A AND c = C AND E > D))", "(A = a OR B = b OR C = c AND ((D = d AND E = e) OR (F = f AND G = g)))" }; for (String expression : expressions) { SimpleBooleanLexer lexer = new SimpleBooleanLexer(new ANTLRInputStream(expression)); SimpleBooleanParser parser = new SimpleBooleanParser(new CommonTokenStream(lexer)); Object result = new evalVisitor(variables).visit(parser.parse()); System.out.printf("%-70s -> %sn", expression, result); } }}class evalVisitor extends SimpleBooleanbaseVisitor<Object> { private final Map<String, Object> variables; public evalVisitor(Map<String, Object> variables) { this.variables = variables; } @Override public Object visitParse(SimpleBooleanParser.ParseContext ctx) { return super.visit(ctx.expression()); } @Override public Object visitDecimalexpression(SimpleBooleanParser.DecimalexpressionContext ctx) { return Double.valueOf(ctx.DECIMAL().getText()); } @Override public Object visitIdentifierexpression(SimpleBooleanParser.IdentifierexpressionContext ctx) { return variables.get(ctx.IDENTIFIER().getText()); } @Override public Object visitNotexpression(SimpleBooleanParser.NotexpressionContext ctx) { return !((Boolean)this.visit(ctx.expression())); } @Override public Object visitParenexpression(SimpleBooleanParser.ParenexpressionContext ctx) { return super.visit(ctx.expression()); } @Override public Object visitComparatorexpression(SimpleBooleanParser.ComparatorexpressionContext ctx) { if (ctx.op.EQ() != null) { return this.visit(ctx.left).equals(this.visit(ctx.right)); } else if (ctx.op.LE() != null) { return asDouble(ctx.left) <= asDouble(ctx.right); } else if (ctx.op.GE() != null) { return asDouble(ctx.left) >= asDouble(ctx.right); } else if (ctx.op.LT() != null) { return asDouble(ctx.left) < asDouble(ctx.right); } else if (ctx.op.GT() != null) { return asDouble(ctx.left) > asDouble(ctx.right); } throw new RuntimeException("not implemented: comparator operator " + ctx.op.getText()); } @Override public Object visitBinaryexpression(SimpleBooleanParser.BinaryexpressionContext ctx) { if (ctx.op.AND() != null) { return asBoolean(ctx.left) && asBoolean(ctx.right); } else if (ctx.op.OR() != null) { return asBoolean(ctx.left) || asBoolean(ctx.right); } throw new RuntimeException("not implemented: binary operator " + ctx.op.getText()); } @Override public Object visitBoolexpression(SimpleBooleanParser.BoolexpressionContext ctx) { return Boolean.valueOf(ctx.getText()); } private boolean asBoolean(SimpleBooleanParser.expressionContext ctx) { return (boolean)visit(ctx); } private double asDouble(SimpleBooleanParser.expressionContext ctx) { return (double)visit(ctx); }}运行
Main该类将得到以下输出:
1 > 2-> false1 >= 1.0 -> trueTRUE = FALSE -> falseFALSE = FALSE -> trueA OR B -> trueB -> falseA = B-> falsec = C-> trueE > D-> trueB OR (c = B OR (A = A AND c = C AND E > D)) -> true(A = a OR B = b OR C = c AND ((D = d AND E = e) OR (F = f AND G = g))) -> true



