What is minimal sample Gradle project for ANTLR4 (with antlr plugin)?
Asked Answered
B

7

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:

Bus answered 7/4, 2016 at 7:33 Comment(0)
R
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;
}
Rus answered 4/10, 2016 at 21:51 Comment(3)
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.Caning
@Rus This way it gives me an error that "duplicate class found in "build/generated-src/...". What should I do about it?Libertylibia
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.Anticlinorium
T
12

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
}
Tempura answered 2/11, 2017 at 17:21 Comment(0)
G
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

Gesner answered 14/2, 2017 at 1:50 Comment(0)
C
5

For Issue 2:

you can configure in the gradle.build:

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

}
Crockett answered 28/10, 2018 at 13:43 Comment(0)
D
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

Dichotomy answered 7/4, 2016 at 22:29 Comment(0)
S
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://mcmap.net/q/337961/-how-to-specify-a-target-package-for-antlr

Significance answered 20/9, 2016 at 21:9 Comment(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.Rus
I take that back... that puts the output files in the right place but still doesn't add the package line to the generated sourceRus
D
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

Deary answered 20/12, 2016 at 16:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.