我有这样的语法:
living
: search EOF
;
search
: K_SEARCH entity
( K_QUERY expr )?
( K_FILTER expr )?
( K_SELECT1 expr ( COMMA expr )* )?
( K_SELECT2 expr ( COMMA expr )* )?
( K_SELECT3 expr ( COMMA expr )* )?
;
如您所见,我有两个可选的expr。
我创建了访问者,并且我能够访问实体,K_QUERY和K_FILTER。 SearchContext提供List以获取所有expr的列表。但是,如何绑定哪个表达式适用于K_QUERY
,K_FILTER
?那么K_SELECT1
,K_SELECT2
,K_SELECT3
的exprs呢。
public class LivingQueryVisitor extends LivingDSLBaseVisitor<Void> {
@Override
public Void visitSearch(SearchContext ctx) {
this.query = search(this.getEntityPath(ctx));
//???????????????????????
List<ExprContext> exprs = ctx.expr();
//???????????????????????
return super.visitSearch(ctx);
}
}
我正在寻找一种方法让访问者能够通过Parse Tree并同时检测我是否必须访问expr K_SEARCH
之后访问expr ,或K---
。
类似的东西:
String currentClause;
visitLiving(LivingContext ctx)
{
//????
}
visitSearch(SearchContext ctx)
{
//set current cluase
this.currentCluase = ???
}
visitExpr(ExprContext ctx)
{
switch (this.currentClause)
{
case "K_SEARCH":
break;
case "K_QUERY":
break;
case "K_FILTER":
break;
case "K_SELECT":
break;
}
}
有什么想法吗?
答案 0 :(得分:2)
使用列表标签
search : K_SEARCH entity
( K_QUERY q=expr )?
( K_FILTER f=expr )?
( K_SELECT1 s1+=expr ( COMMA s1+=expr )* )?
( K_SELECT2 s2+=expr ( COMMA s2+=expr )* )?
( K_SELECT3 s3+=expr ( COMMA s3+=expr )* )?
;
Antlr将在SearchContext类中生成这些附加变量:
ExprContext q;
ExprContext f;
List<ExprContext> s1;
List<ExprContext> s2;
List<ExprContext> s3;
值为非空 iff 相应的子符号匹配。