Bind ANTLR4 subrules of a rule

2019-05-31 19:20发布

问题:

I've a grammar like that:

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 )* )?
;

As you can see I've two optional expr.

I've created my Visitor, and I'm able to get access to entity, K_QUERY and K_FILTER. SearchContext provides a List in order to get a list of all expr. However, how can I bind which expression is for K_QUERY, K_FILTER? What about the exprs of K_SELECT1, K_SELECT2, K_SELECT3.

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);
   }
}

I'm looking for a way in order for visitor to be able to go through the Parse Tree and at the same detecting whether I'm visiting a expr after have to be visited a K_SEARCH, or K---.

Something like that:

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;
    }
}

Any ideas?

回答1:

Use list labels

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 will generate these additional variables within the SearchContext class:

ExprContext q;
ExprContext f;
List<ExprContext> s1;
List<ExprContext> s2;
List<ExprContext> s3;

The values will be non-null iff the corresponding subterms matched.



标签: antlr4