Search code examples
javamavenantlrantlr4

How to specify separately the path of the java file and the tokens file generated by Antlr?


I`m attempting to use antlr4 in my project to parse files in custom format. But when I use antlr4 maven plugin, I cannot find a parameter to set separately the path of tokens file and java file, as it can only set a common path.

Here`s the configuration of antlr4 maven plugin:

<plugin>
    <groupId>org.antlr</groupId>
    <artifactId>antlr4-maven-plugin</artifactId>
    <version>4.11.1</version>
    <executions>
        <execution>
            <id>antlr</id>
            <goals>
                <goal>antlr4</goal>
            </goals>
            <phase>compile</phase>
        </execution>
    </executions>

    <configuration>
        <libDirectory>src/main/antlr4/imports</libDirectory>
        <sourceDirectory>src/main/antlr4</sourceDirectory>
        <outputDirectory>src/main/java</outputDirectory>
        <listener>true</listener>
        <visitor>true</visitor>
        <treatWarningsAsErrors>true</treatWarningsAsErrors>
    </configuration>
</plugin>

The grammar file test.g4 is in <sourceDirectory>/relativePath(src/main/antlr4/org/trance233/antlr/).

The .tokens file is in <outputDirectory>(src/main/java/), the .java file is in <sourceDirectory>/relativePath(src/main/java/org/trance233/antlr/).

Is there any way that can set the path separately? Such as the .tokens file above is put in src/main/resources, and the .java file is put in src/main/java/org/trance233/antlr/.


Solution

  • A configuration for antlr4 is usually very simple like this:

      <plugin>
        <groupId>org.antlr</groupId>
        <artifactId>antlr4-maven-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>antlr4</goal>
            </goals>
            <configuration>
              <visitor>true</visitor>
              <listener>false</listener>
            </configuration>
          </execution>
        </executions>
      </plugin>
    

    This assumes you have your grammar file in src/main/antlr4/<package>/test.g4 (default location). There is no need to configure such things etc. because by conventions the generated class will be available in target/generated-sources/antlr4/. Exactly in this directory you will find the *.tokens files. The imports directory is defined by default as src/main/antl4/imports. The default configuration for the antlr4-maven-plugin defines some very useful defaults and it is strongly recommended to follow those conventions.

    I strongly recommmend NOT to configure the <outputDirectory>src/main/java</outputDirectory> because that will generate code in your src/ directory tree which can cause issues with your versions control system.

    BTW: Binding the code generation to the phase compile is very bad because the code generation should be done before the compile phase. The generate-sources phase is exactly intended for such cases. This phase is used by default by the antlr4-maven-plugin.