Running ANTLR grun (TestRig) on grammar in a package.

4k views Asked by At

I have all the generated java files in a single directory after ANTLR execution, so I used some options to generate a separate directory and namespace to be stored and compiled to store all the generated files.

This is the grammar file:

grammar Expr;

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

I could get the generated files in a different directory with o, and add package information with package option.

java -jar /usr/local/lib/antlr-4.5.3-complete.jar -listener -visitor -package expr -lib . -o gen/expr Expr.g4

Compiling the code requires d and sourcepath option in javac.

javac -cp .:/usr/local/lib/antlr-4.5.3-complete.jar -d out -sourcepath gen gen/expr/Expr*.java

I could check the code works from making the executable.

import expr.*;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

class ExprRunner {
    public static void main(String[] args) throws Exception {
        // create a CharStream that reads from standard input

        String filePath = "input.txt";
        File fileInput = new File(filePath);
        FileInputStream fileInputStream = new FileInputStream(fileInput);


        ANTLRInputStream input = new ANTLRInputStream(fileInputStream); 
        ExprLexer lexer = new ExprLexer(input); 
        CommonTokenStream tokens = new CommonTokenStream(lexer); 
        ExprParser parser = new ExprParser(tokens);
        ParseTree tree = parser.prog(); // begin parsing at init rule
        System.out.println(tree.toStringTree(parser)); // print LISP-style tree        
    }
}

I could build and run it.

javac -cp .:/usr/local/lib/antlr-4.5.3-complete.jar:out -d out -sourcepath . ExprRunner.java
java -cp .:/usr/local/lib/antlr-4.5.3-complete.jar:out ExprRunner

This is the directory structure.

enter image description here After checking everything works fine, I tried to use grun (TestRig). I tried grun Expr prog -tree and grun out/expr/Expr prog -tree, but they did not work.

How to run grun on the ANTLR files located in other directories?

3

There are 3 answers

4
Bart Kiers On BEST ANSWER

AFAIK, grun only works when all files are in the same folder. It is meant as a quick debugging tool.

EDIT

For those who read this more recently: it seems things might have changed and this is now possible. Read raffian's answer to try the -package parameter (I did not try it myself).

0
raffian On

If you generated your parser with the following options:

-package expr -lib . -o gen/expr Expr.g4

..your parser classes now reside in Java package expr. Now, when using grun, just qualify the grammar option so the tool can find the parser class based on its package name:

grun expr.Expr prog -tree

I confirmed this works with ANTLR 4.12.0, the only difference in my setup was packaging all generated parser/lexer classes in a maven library configured on my classpath.

0
Telmo Trooper On

What I do on Linux is to change directory (cd) before running grun.

My project directory has the following structure:

  • Root folder/

    • src/ (where .java files are stored)
    • bin/ (where .class files are stored)
    • input/ (where input programs in .txt are stored)

    • Makefile

And my Makefile has the following rule:

start:
    @cd bin && cat ../$(INPUT) | grun MyGrammar program -gui

So when I call make start INPUT="input/test.txt" it starts grun, showing the parse tree for my input program.