我有以下语法(简化):
filter : eq | and;
eq : 'eq' '(' property ',' value ')';
and : 'and' '(' filter ',' filter (',' filter)* ')';
...
我正在分析简单的前缀结构,如:
and(eq(name,john),eq(location,usa))
在and
节点的filter
节点之间循环的最佳方式是什么?生成的类AndContext
具有函数filter(int index)
,但仅此而已。我想做一些类似的事情:
AndContext c = ...;
for (int i = 0; i < c.numberOfFilters(); ++i) {
FilterContext f = c.filter(i);
}
函数getChildCount()
,但它返回所有节点(包括代表(
、)
等的终端节点)的计数,而不仅仅是感兴趣的filter
节点。
假设您的语法如下:
grammar F;
eq : 'eq' '(' property ',' value ')';
and : 'and' '(' filter ',' filter (',' filter)* ')';
filter : eq | and;
property : 'name' | 'location';
value : 'john' | 'usa';
然后您可以扩展生成的FBaseListener
并覆盖其enterAnd
以获得FilterContext
s:
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)