Hakan Özler
Hakan Özler

Reputation: 988

Modifying a plain ANLTR file in background

I would like to modify a grammar file by adding some Java code programatically in background. What I mean is that consider you have a println statement that you want to add it in a grammar before ANTLR works (i.e. creates lexer and parser files).

I have this trivial code: {System.out.println("print");}

Here is the simple grammar that I want to add the above snippet in the 'prog' rule after 'expr': Before:

grammar Expr;       
prog:   (expr NEWLINE)* ;
expr:   expr ('*'|'/') expr        
    |   INT
    ;
NEWLINE : [\r\n]+ ;
INT     : [0-9]+ ;

After:

grammar Expr;       
prog:   (expr {System.out.println("print");} NEWLINE)* ;
expr:   expr ('*'|'/') expr 
    |   INT       
    ;
NEWLINE : [\r\n]+ ;
INT     : [0-9]+ ;

Again note that I want to do this in runtime so that the grammar does not show any Java code (the 'before' snippet).

Is it possible to make this real before ANLTR generates lexer and parser files? Is there any way to visit (like AST visitor for ANTLR) a simple grammar?

Upvotes: 0

Views: 70

Answers (2)

Onur
Onur

Reputation: 5205

If the code is always in the same place, simply insert a function call that acts as a hook to include real code afterwards. This way you don't have to modify the source or generate the lexer/parser again.

If you want to insert code at predefined points (like enter rule/leave rule), go with Sam's solution to insert them into a listener. In either case it should not be necessary to modify the grammar file.

grammar Expr;       
prog:   (expr {Hooks.programHook();} NEWLINE)* ;
expr:   expr ('*'|'/') expr 
    |   INT       
    ;
NEWLINE : [\r\n]+ ;
INT     : [0-9]+ ;

In a java file of your choice (I'm no Java programmer, so the real syntax may be different):

public class Hooks
{
    public static void programHook()
    {
       System.out.println("print");
    }
}

Upvotes: 0

Sam Harwell
Sam Harwell

Reputation: 99889

ANTLR 4 generates a listener interface and base class (empty implementation) by default. If you also specify the -visitor flag when generating your parser, it will create a visitor interface and base class. Either of these features may be used to execute code using the parse tree rather than embedding actions directly in the grammar file.

Upvotes: 3

Related Questions