What is minimal sample Gradle project for ANTLR4 (

2020-07-06 05:04发布

问题:

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:

回答1:

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;
}


回答2:

What helped me is two things:

  • Add header:@header{ package com.example.something.antlrparser; } to the top of the grammar file.
  • 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
}


回答3:

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



回答4:

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

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



回答5:

For Issue 2:

you can configure in the gradle.build:

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

}


回答6:

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



回答7:

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 !