【发布时间】:2015-06-22 09:53:48
【问题描述】:
我正在尝试解析嵌套布尔表达式并分别获取表达式中的各个条件。例如,如果输入字符串是:
(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 或者 F = f 和 G = g 和 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>)
我正在寻求有关如何解析这棵树以获得正确顺序的条件的帮助?在 ANTLR 3 中,我们可以指定 ^ 和 !决定如何构建树(参考这个thread),但我了解到这在 ANTLR 4 中不受支持。
有人可以建议我如何使用 ANTLR 创建的 ParseTree 在 Java 中以正确的顺序解析字符串吗?
【问题讨论】:
-
@BartKiers 你知道如何解决这个问题吗?
-
@BartKiers 你是对的。
GT | GE | LT | LE | EQ都具有相同的优先级,它们应该在AND | OR之前进行评估。解析应基于括号( )。我正在寻找的是有关如何使用上面代码中显示的 ParseTree 在 Java 中解析字符串的帮助。 -
在我们的例子中,只要两个组件之间有
AND,它总是在括号内( )。 -
在您的示例中,
(A = a OR B = b OR C = c AND ((D = d AND E = e) OR (F = f AND G = g))),第一个AND不在括号内。是先评估A = a OR B = b OR C = c,还是先评估C = c AND ((D = d AND E = e) OR (F = f AND G = g))?
标签: java parsing antlr antlr4 antlr3