Antlr4 Project Directory Structure Issue

Tags: , ,



I’m trying to set up an Antlr4 project using Java’s package directory structure.

The top level directory contains PondParser.g4, PondLexer.g4, and build_script.

build_script is expected to build and run the antlr4 test rig

{ 
    echo 'clean project' 
    find ./com/sevan/pond/ -type f -delete
} && { 
    echo 'launch ANTLR parser generator' 
    java -jar /usr/local/lib/antlr-4.8-complete.jar -package com.sevan.pond  ./PondLexer.g4 -o com/sevan/pond
    java -jar /usr/local/lib/antlr-4.8-complete.jar -package com.sevan.pond  ./PondParser.g4 -o com/sevan/pond
} && { 
    echo 'compile .java files'
    javac ./com/sevan/pond/*.java 
} && {
    echo 'run test rig with gui'
    java org.antlr.v4.gui.TestRig  ./com/sevan/pond/PondParser prog -gui 
}

Relevant PondParser.g4 header and options:

parser grammar PondParser;

@header {   
    package com.sevan.pond;
}

options {
    tokenVocab = PondLexer;
}

Relevant PondLexer.g4 header and options:

lexer grammar PondLexer ;

@header {   
    package com.sevan.pond;
}

The build script fails while compiling (javac ./com/sevan/pond/*.java ).

The specific errors are as follows:

./com/sevan/pond/LexerRules.java:4: error: class, interface, or enum expected
    package com.sevan.pond;
    ^
./com/sevan/pond/Pond.java:4: error: class, interface, or enum expected
    package com.sevan.pond;
    ^
./com/sevan/pond/PondBaseListener.java:4: error: class, interface, or enum expected
    package com.sevan.pond;
    ^
./com/sevan/pond/PondListener.java:4: error: class, interface, or enum expected
    package com.sevan.pond;
    ^
4 errors

What’s missing/wrong here? Any suggestions, links, and answers would be greatly appreciated.


Update

The four errors above were due to a double package declaration in the generated java files. This was caused by specifying the package using -package and @header. After fixing this, however, the test rig still fails with Can't load PondParser as lexer or parser.

Answer

Shouldn’t that be:

# *nix
javac -cp .:/usr/local/lib/antlr-4.8-complete.jar ./com/sevan/pond/*.java 

# Windows
javac -cp .;pathtoantlr-4.8-complete.jar .comsevanpond*.java 

?

I.e.: you want to add the current working dir to the classpath (.), as well as the ANTLR lib.

EDIT

Here’s a working demo (just tested it myself).

Files/folder structure:

-+
 |
 +-- antlr-4.8-complete.jar
 |
 +-- com/
      |
      +-- sevan/
           |
           +-- pond/
                |
                +-- PondParser.g4
                |
                +-- PondLexer.g4

Navigate to where antlr-4.8-complete.jar resides.

Generate lexer and parser classes:

java -jar antlr-4.8-complete.jar -package com.sevan.pond com/sevan/pond/*.g4

And compile all generated .java files:

javac -cp .:antlr-4.8-complete.jar com/sevan/pond/*.java

Fianlly, run TestRig as follows:

java -cp .:antlr-4.8-complete.jar org.antlr.v4.gui.TestRig com.sevan.pond.Pond prog -gui

You can now enter some text and can terminate by pressing CTRL+D. I typed abcn and got this:

enter image description here

For reference, heres what the grammars look like:

PondLexer.g4

lexer grammar PondLexer;

ANY
 : .
 ;

PondParser.g4

parser grammar PondParser;

options {
  tokenVocab=PondLexer;
}

prog
 : ANY* EOF
 ;


Source: stackoverflow