我正在尝试解析以下类型的布尔表达式 B1 = p& A4 = p | A6 = p&(~A5 = c)
我想要一棵树,我可以用它来评估上面的表达式。所以我在Antlr3中使用Antlr parser for and/or logic - how to get expressions between logic operators?
中的示例尝试了这个它在Antlr3中有效。现在我想为Antlr 4做同样的事情。我提出了下面的语法并编译。但是我在编写Java代码时遇到了麻烦。
grammar TestAntlr4;
options {
output = AST;
}
tokens { AND, OR, NOT }
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' | ' '
| ('+'|'-'|'*'|'/'|'_')
| '='
)+
;
我编写了Java代码(下面的代码段),用于获取表达式“B1 = p& A4 = p | A6 = p&(~A5 = c)”的树。我期待&有孩子B1 = p和|。孩子|操作员将有孩子A4 = p和A6 = p&(~A5 = c)。等等。 这是Java代码,但我试图弄清楚如何获得树。我能够在Antlr 3中做到这一点。
String src = "B1=p & A4=p | A6=p &(~A5=c)";
CharStream stream = (CharStream)(new ANTLRInputStream(src));
TestAntlr4Lexer lexer = new TestAntlr4Lexer(stream);
parser.setBuildParseTree(true);
ParserRuleContext tree = parser.parse();
tree.inspect(parser);
if ( tree.children.size() > 0) {
System.out.println(" **************");
test.getChildren(tree, parser);
}
获取儿童方法如下。但这似乎没有提取任何令牌。
public void getChildren(ParseTree tree, TestAntlr4Parser parser ) {
for (int i=0; i<tree.getChildCount(); i++){
System.out.println(" Child i= " + i);
System.out.println(" expression = <" + tree.toStringTree(parser) + ">");
if ( tree.getChild(i).getChildCount() != 0 ) {
this.getChildren(tree.getChild(i), parser);
}
}
}
有人可以帮我弄清楚如何用Java编写解析器吗?
答案 0 :(得分:3)
在ANTLR 4中删除了output=AST
选项,以及您在语法中使用的^
和!
运算符。 ANTLR 4生成解析树而不是AST,因此规则生成的树的根是规则本身。例如,给出以下规则:
and : not (AND not)*;
您最终会得到一个包含AndContext
和NotContext
子项的TerminalNode
树,分别用于not
和AND
个引用。为了更容易使用树,AndContext
将包含一个生成的方法not()
,它返回由not
规则的调用返回的上下文对象列表(返回类型{{1 }})。它还包含一个生成的方法List<? extends NotContext>
,该方法返回为匹配的每个AND
令牌创建的TerminalNode
个实例的列表。