使用ANTLR的嵌套布尔表达式解析器

我试图解析嵌套的布尔表达式,并分别获取表达式内的各个条件。例如,如果输入字符串是:

(A = a OR B = b OR C = c AND((D = d AND E = e)OR(F = f AND G = g)))

我想以正确的顺序得到条件。即

D = d AND E = e OR F = f AND G = g AND A = a OR B = b OR C = c

我正在使用ANTLR 4来解析输入文本,这是我的语法:

grammar SimpleBoolean;

rule_set : nestedCondition* EOF;

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 : [ \r\t\u000C\n]+ -> skip;

nestedCondition : LPAREN condition+ RPAREN (binary nestedCondition)*;

condition: predicate (binary predicate)*

| predicate (binary component)*;

component: predicate | multiAttrComp;

multiAttrComp : LPAREN predicate (and predicate)+ RPAREN;

predicate : IDENTIFIER comparator IDENTIFIER;

comparator : GT | GE | LT | LE | EQ ;

binary: AND | OR ;

unary: NOT;

and: AND;

这是我用来解析它的Java代码:

ANTLRInputStream inputStr = new ANTLRInputStream(input);

SimpleBooleanLexer lexer = new SimpleBooleanLexer(inputStr);

TokenStream tokens = new CommonTokenStream(lexer);

SimpleBooleanParser parser = new SimpleBooleanParser(tokens);

parser.getBuildParseTree();

ParseTree tree = parser.rule_set();

System.out.println(tree.toStringTree(parser));

输出为:

(rule_set (nestedCondition ( (condition (predicate A (comparator =) a) (binary OR) (component (predicate B (comparator =) b)) (binary OR) (component (predicate C (comparator =) c)) (binary AND) (component (multiAttrComp ( (predicate ( D (comparator =) d) (and AND) (predicate E (comparator =) e) ))) (binary OR) (component (multiAttrComp ( (predicate F (comparator =) f) (and AND) (predicate G (comparator =) g) )))) ) )) <EOF>)

我正在寻找有关如何解析此树以正确顺序获取条件的帮助?在ANTLR3中,我们可以指定^和!决定如何构建树,但是我了解到ANTLR 4不支持此树。

有人可以建议我如何使用ANTLR创建的ParseTree在Java中以正确的顺序解析String吗?

回答:

我只是将所有表达式包装成一条expression规则。一定要定义comparator的替代表述 之前

binary表达的替代,以确保comparator运营商绑定更紧密比ORAND

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 : [ \r\t\u000C\n]+ -> 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 -> %s\n", 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                                                                  -> false

1 >= 1.0 -> true

TRUE = FALSE -> false

FALSE = FALSE -> true

A OR B -> true

B -> false

A = B -> false

c = C -> true

E > D -> true

B 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

以上是 使用ANTLR的嵌套布尔表达式解析器 的全部内容, 来源链接: utcz.com/qa/399842.html

回到顶部