Search code examples
javaantlr4context-free-grammar

Detect tokens triggering rules in ANTLR4


I have this very simple grammar:

grammar DLR;
dlr : c 'sub' c ;
c  : CN | 'not' c | c 'and' c | c 'or' c ;
CN : [A-Z]+ ;
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines

When I generate the java code with antlr4 command, I got the java interface DLRBaseListener:

public class DLRBaseListener implements DLRListener {

@Override public void enterDlr(DLRParser.DlrContext ctx) { }

@Override public void exitDlr(DLRParser.DlrContext ctx) { }

@Override public void enterC(DLRParser.CContext ctx) { }

@Override public void exitC(DLRParser.CContext ctx) { }

@Override public void enterEveryRule(ParserRuleContext ctx) { }

@Override public void exitEveryRule(ParserRuleContext ctx) { }

@Override public void visitTerminal(TerminalNode node) { }

@Override public void visitErrorNode(ErrorNode node) { }

}

It is possible to extend this interface especially if you want to detect when a rule is triggered. Therefore, methods like enterDlr, exitDlr, enterC and exitC are very useful. My goal is more specific: I want to detect the tokens responsible for triggering that rule. In my example are 'not' c, c 'and' c, c 'or' c. As you can see, there are no methods for these ones in the interface. Is there a way to detect those parts of the grammar?


Solution

  • ANTLR4 provides "alternate labeling" (TDAR pg 117, 261) to achieve this function:

    c  : CN          # justCN 
       | 'not' c     # notC
       | c 'and' c   # andC 
       | c 'or' c    # orC
       ;
    

    The tool will generate separate parser contexts (subclasses of the rule context in Java) for each of the labeled alternatives, with names based on the label names. And, corresponding enter/exit listener methods.