问题描述
我正在使用ANTLR创建和/或解析器+评估器.表达式的格式如下:
I am using ANTLR to create an and/or parser+evaluator. Expressions will have the format like:
-
x eq 1 && y eq 10
-
(x lt 10 && x gt 1) OR x eq -1
x eq 1 && y eq 10
(x lt 10 && x gt 1) OR x eq -1
我正在阅读有关ANTLR中的逻辑表达式的文章寻找建议在项目上.解析逻辑表达式,我发现那里发布的语法是一个好的开始:
I was reading this post on logic expressions in ANTLR Looking for advice on project. Parsing logical expression and I found the grammar posted there a good start:
grammar Logic;
parse
: expression EOF
;
expression
: implication
;
implication
: or ('->' or)*
;
or
: and ('&&' and)*
;
and
: not ('||' not)*
;
not
: '~' atom
| atom
;
atom
: ID
| '(' expression ')'
;
ID : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
但是,虽然从解析器中获取一棵树可用于变量只是一个字符的表达式(即"(A || B) AND C"
,但我很难适应这种情况(在示例"x eq 1 && y eq 10"
中,希望有一个"AND"
父级和两个孩子"x eq 1"
和"y eq 10"
,请参见下面的测试用例.
However, while getting a tree from the parser works for expressions where the variables are just one character (ie, "(A || B) AND C"
, I am having a hard time adapting this to my case (in the example "x eq 1 && y eq 10"
I'd expect one "AND"
parent and two children, "x eq 1"
and "y eq 10"
, see the test case below).
@Test
public void simpleAndEvaluation() throws RecognitionException{
String src = "1 eq 1 && B";
LogicLexer lexer = new LogicLexer(new ANTLRStringStream(src));
LogicParser parser = new LogicParser(new CommonTokenStream(lexer));
CommonTree tree = (CommonTree)parser.parse().getTree();
assertEquals("&&",tree.getText());
assertEquals("1 eq 1",tree.getChild(0).getText());
assertEquals("a neq a",tree.getChild(1).getText());
}
我相信这与"ID"
有关.正确的语法是什么?
I believe this is related with the "ID"
. What would the correct syntax be?
推荐答案
对于那些感兴趣的人,我在语法文件中做了一些改进(请参见下面的内容)
For those interested, I made some improvements in my grammar file (see bellow)
当前限制:
-
仅适用于&&/||,而不适用于AND/OR(问题不大)
only works with &&/||, not AND/OR (not very problematic)
在括号和&&/||之间不能有空格. (我通过在提供词法分析器之前在源字符串中用("替换为)"和)"替换为)来解决此问题)
you can't have spaces between the parenthesis and the &&/|| (I solve that by replacing " (" with ")" and ") " with ")" in the source String before feeding the lexer)
语法逻辑;
options {
output = AST;
}
tokens {
AND = '&&';
OR = '||';
NOT = '~';
}
// parser/production rules start with a lower case letter
parse
: expression EOF! // omit the EOF token
;
expression
: or
;
or
: and (OR^ and)* // make `||` the root
;
and
: not (AND^ not)* // make `&&` the root
;
not
: NOT^ atom // make `~` the root
| atom
;
atom
: ID
| '('! expression ')'! // omit both `(` and `)`
;
// lexer/terminal rules start with an upper case letter
ID
:
(
'a'..'z'
| 'A'..'Z'
| '0'..'9' | ' '
| SYMBOL
)+
;
SYMBOL
:
('+'|'-'|'*'|'/'|'_')
;
这篇关于用于和/或逻辑的Antlr解析器-如何在逻辑运算符之间获取表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!