我有以下语法(简化):
filter : eq | and;
eq : 'eq' '(' property ',' value ')';
and : 'and' '(' filter ',' filter (',' filter)* ')';
...
我正在解析简单的前缀结构,如:
and(eq(name,john),eq(location,usa))
循环filter
节点的and
个节点的最佳方法是什么?生成的类AndContext
具有函数filter(int index)
,但仅此而已。我想做点什么:
AndContext c = ...;
for (int i = 0; i < c.numberOfFilters(); ++i) {
FilterContext f = c.filter(i);
}
有函数getChildCount()
,但它返回所有节点的计数(包括代表(
,)
等的终端节点),而不仅仅是有趣的{{ 1}}节点。
答案 0 :(得分:2)
让我们说你的语法是这样的:
grammar F;
eq : 'eq' '(' property ',' value ')';
and : 'and' '(' filter ',' filter (',' filter)* ')';
filter : eq | and;
property : 'name' | 'location';
value : 'john' | 'usa';
然后您可以扩展生成的FBaseListener
并覆盖其enterAnd
以转到FilterContext
:
public class Main {
public static void main(String[] args) throws Exception {
FLexer lexer = new FLexer(new ANTLRInputStream("and(eq(name,john),eq(location,usa))"));
FParser parser = new FParser(new CommonTokenStream(lexer));
ParseTreeWalker.DEFAULT.walk(new AndListener(), parser.and());
}
}
class AndListener extends FBaseListener {
@Override
public void enterAnd(@NotNull FParser.AndContext ctx) {
for (FParser.FilterContext filterContext : ctx.filter()) {
System.out.println("filterContext=" + filterContext.getText());
}
}
}
将打印:
filterContext=eq(name,john)
filterContext=eq(location,usa)