javaantlrantlr3

Get active Antlr rule


Is it possible to get the "active" ANTLR rule from which a action method was called?

Something like this log-function in Antlr-Pseudo-Code which should show the start and end position of some rules without hand over the $start- and $end-tokens with every log()-call:

@members{
  private void log() {
    System.out.println("Start: " + $activeRule.start.pos +
                       "End: " + $activeRule.stop.pos);
  }
}

expr: multExpr (('+'|'-') multExpr)* {log(); }
    ;

multExpr
    : atom('*' atom)* {log(); }
    ;

atom: INT
    | ID {log(); }
    | '(' expr ')'
    ;

Solution

  • No, there is no way to get the name of the rule the parser is currently in. Realize that parser rules are, by default, simply Java methods returning a void. From a Java method, you cannot find out the name of it at run-time after all (when inside of this method).

    If you set output=AST in the options { ... } of your grammar, every parser rule creates (and returns) an instance of a ParserRuleReturnScope called retval: so you could use that for your purposes:

    // ...
    
    options {
      output=AST;
    }
    
    // ...
    
    @parser::members{
      private void log(ParserRuleReturnScope rule) {
        System.out.println("Rule: "    + rule.getClass().getName() +  
                           ", start: " + rule.start +
                           ", end: "   + rule.stop);
      }
    }
    
    expr: multExpr (('+'|'-') multExpr)*    {log(retval);}
        ;
    
    multExpr
        : atom('*' atom)*                   {log(retval);}
        ;
    
    atom: INT
        | ID                                {log(retval);}
        | '(' expr ')'
        ;
    // ...
    

    This is however not a very reliable thing to do: the name of the variable may very well change in the next version of ANTLR.