18

I have created new Gradle project, added

apply plugin: 'antlr'

and

dependencies {
    antlr "org.antlr:antlr4:4.5.3"

to build.gradle.

Created src/main/antlr/test.g4 file with the following content

grammar test;
r   : 'hello' ID;
ID  : [a-z]+ ;
WS  : [ \t\r\n]+ -> skip ;

But it doesn't work. No java source files generated (and no error occurred).

What I missed?

Project is here: https://github.com/dims12/AntlrGradlePluginTest2

UPDATE

I found my sample is actually works, but it put code into \build\generated-src which I was not expecting :shame:

Dims
  • 47,675
  • 117
  • 331
  • 600

7 Answers7

18

I will add onto other answers here.

Issue 1: Generated source files are placed in build/generated-src folder.

I found this discussion, but the solution there (setting outputDirectory property) is a bad idea. If you do gradle clean build command, this will clear out your entire source directory. The discussion there gives a good explanation as to why you should not

the antlr generated sources are generated into a subdirectory of the "build" folder like all other artifacts, which are generated during the build. Furthermore your generated directory projectRoot/build/generated-src/antlr/main is added to the java sourceset definition to be sure its considered compileJava task. If you write the antlr generated source directly to the src/main/java folder you're polluting your source folder with output of your build process. ... Polluting your source folder during your build is an antipattern I think.

However, if you want to do this, you can add a gradle task to copy the generated files to the build directory.

generateGrammarSource << {
    println "Copying generated grammar lexer/parser files to main directory."
    copy {
        from "${buildDir}/generated-src/antlr/main"
        into "src/main/java"
    }
}

Issue 2: Generated source files do not have package attribute set.

To solve this issue, add something like the following near the top of the grammar file:

@header {
package com.example.my.package;
}
Kip
  • 107,154
  • 87
  • 232
  • 265
  • the header must be after `grammar Name;` and copying the generated source does not make sense. Whats wrong with `build`? if you really wanna move the gen-src then use `generateGrammarSource { outputDirectory = file("src/gen/java/")}` see answer by mawalker. – JPT Apr 25 '18 at 13:20
  • @Kip This way it gives me an error that "duplicate class found in "build/generated-src/...". What should I do about it? – user3745870 Jan 10 '19 at 21:59
  • Do not copy generated classes into your source directory! Gradle is able to include the generated-src directory while compiling the project. This ways the classes are always generated but also available for compiling. Mixing generated and static sources leads to duplications on the classpath like you expected. – Matthias B Jun 07 '19 at 10:47
11

What helped me is two things:

  • Add header:@header{ package com.example.something.antlrparser; } to the grammar file directly after the grammar test; declaration.
  • Place the grammar file in corresponding folder, i.e. src/main/antlr/com/example/something/antlrparser/grammar.g4

Now when I run the generateGrammarSource gradle task, .java files are generated in /build/generated-src/antlr/main/com/example/something/antlrparser/*.java and they are automatically picked up by IntelliJ as well as compilable by gradle.

The build.gradle file is just:

group 'com.example.something'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'antlr'
apply plugin: 'idea'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    antlr "org.antlr:antlr4:4.5" // use ANTLR version 4
}
fyrkov
  • 2,245
  • 16
  • 41
Martin Melka
  • 7,177
  • 16
  • 79
  • 138
7

Add this to your build.gradle

generateGrammarSource {
    outputDirectory = file("src/main/java/com/example/parser")
}

add this to your grammar after your "grammar ";

@header {
    package com.example.parser;
}

Tested and working with Java8 grammar from antlr example grammars

Additional Link(s):

Here is a short guide of the Antlr plugin from docs.gradle.org

mawalker
  • 2,072
  • 2
  • 22
  • 34
5

For Issue 2:

you can configure in the gradle.build:

  generateGrammarSource {
        maxHeapSize = "64m"
        arguments += ["-visitor", 
                      "-long-messages", 
                      "-package", "your.package.name"]

}
igreenfield
  • 1,618
  • 19
  • 36
2

A snippet is included in the Gradle "all" distribution under the "snippets" folder. You can also simply browse the snippet on GitHub.

https://github.com/gradle/gradle/tree/master/subprojects/docs/src/snippets/antlr

166_MMX
  • 590
  • 5
  • 18
Mark Vieira
  • 13,198
  • 4
  • 46
  • 39
1

The Gradle sample noted by @Mark Vieira only got me halfway there. I found that I had to specify the package in the header of my ANTLR grammar file in order for everything to be seen in both directions (generated code able to access hand-written code and vice-versa).

grammar MyGrammar;

@header {
    package com.mypackage;
}

Prior to switching to Gradle, I had been using the ANTLR plugin in IntelliJ, which filled in the package for me. Upon switching to Gradle, the package went away, which caused problems.

Source: https://stackoverflow.com/a/1655920/1877143

Community
  • 1
  • 1
Hank Schultz
  • 553
  • 5
  • 11
  • 2
    If you put your grammar files in packages, it will do it automatically. Like if you have `src/main/antlr/com/mypackage/MyGrammar.g`, then it will put the generated files in `com.mypackage`. – Kip Oct 04 '16 at 21:18
  • 2
    I take that back... that puts the output files in the right place but still doesn't add the package line to the generated source – Kip Oct 04 '16 at 21:34
0

Gradle STS plugin doesn't generate source files for antlr4. It generates the misleading output as:

[sts] -----------------------------------------------------
[sts] Starting Gradle build for the following tasks: 
[sts]      generateGrammarSource
[sts] -----------------------------------------------------
:generateGrammarSource UP-TO-DATE

Uninstalled this old plugin and used from command line..It works !

Gradle STS plugin doesn't generate source files for antlr4. Need to Use new plugin or command line

Community
  • 1
  • 1
Subra M
  • 581
  • 1
  • 8
  • 16