james.garriss james.garriss - 5 months ago 40
Java Question

How do I make the auto-generated parser class implement an interface in ANTLR4?

I am using ANTLR 4 to create a parser, and I have completed my grammar. I need to inject some Java code into the resulting parser file that ANTLR auto-generates for me.

If I want to include a method in the resulting parser, I can add this to the ANTLR grammar:

@parser::members
{
@Override
public CGrammarParser.CSnippetContext call()
{
return cSnippet();
}
}


If I want to include some import statements, I can add this to the grammar:

@header
{
import java.lang.Thread;
import java.lang.InterruptedException;
import java.util.concurrent.Callable;
}


If I want to modify the class declaration so that it implements an interface, how do I do that? In other words, this is what ANTLR auto-generates:

public class CGrammarParser extends Parser
{
...
}


But this is what I want it to generate:

public class CGrammarParser extends Parser implements Callable<CGrammarParser.CSnippetContext>
{
...
}

Answer

Credit for this answer goes to Lucas Trzesniewski.

To have your ANTLR parser implement an interface, no Java is required in the grammar file (.g4) itself. Simply do the following:

1) Create an callable parser class that implements the interface in question, something like:

public class CallableParser extends CGrammarParser implements Callable<CGrammarParser.CSnippetContext>
{
    public CallableParser(TokenStream input)
    {
        super(input);
    }

    @Override
    public CGrammarParser.CSnippetContext call()
    {
        return cSnippet();
    }
}

2) Instead of calling the normal ANTLR parser, call the CallableParser instead, like this:

CharStream in = new ANTLRInputStream(input);
CGrammarLexer lexer = new CGrammarLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
// Instead of doing this...
// CGrammarParser parser = new CGrammarParser(tokens);
// Do this...
CallableParser parser = new CallableParser(tokens);
Comments