什么是 ANTLR4 的最小示例 Gradle 项目(带有 antlr 插件)?

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

我创建了新的 Gradle 项目,添加了

apply plugin: 'antlr'

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

build.gradle

已创建 src/main/antlr/test.g4 包含以下内容的文件

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

但是没用。未生成 java 个源文件(并且未发生错误)。

我错过了什么?

项目在这里:https://github.com/dims12/AntlrGradlePluginTest2

更新

我发现我的示例确实有效,但它把代码放入了 \build\generated-src,这是我没有预料到的 :shame:

片段包含在“片段”文件夹下的 Gradle“全部”分发中。您也可以简单地浏览 GitHub.

上的片段

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

@Mark Vieira 指出的 Gradle 示例只让我完成了一半。我发现我必须在我的 ANTLR 语法文件的 header 中指定包,以便在两个方向上都能看到所有内容(生成的代码能够访问 hand-written 代码和 vice-versa) .

grammar MyGrammar;

@header {
    package com.mypackage;
}

在切换到 Gradle 之前,我一直在使用 IntelliJ 中的 ANTLR 插件,它为我填充了包。切换到 Gradle 后,包消失了,这导致了问题。

来源:https://whosebug.com/a/1655920/1877143

我会在这里添加其他答案。

问题 1:生成的源文件放在 build/generated-src 文件夹中。

我找到了 this discussion,但是那里的解决方案(设置 outputDirectory 属性)是一个 糟糕的 想法。如果您执行 gradle clean build 命令,这将清除您的 整个 源目录。那里的讨论很好地解释了为什么你不应该

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.

但是,如果你想这样做,你可以添加一个gradle任务来将生成的文件复制到构建目录中。

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

问题 2:生成的源文件没有设置包属性。

要解决此问题,请在语法文件顶部附近添加如下内容:

@header {
package com.example.my.package;
}

Gradle STS 插件不会为 antlr4 生成源文件。它生成的误导性输出为:

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

卸载了这个旧插件并从命令行使用..它有效!

将此添加到您的 build.gradle

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

在 "grammar " 之后将其添加到您的语法中;

@header {
    package com.example.parser;
}

已测试并使用 Java8 grammar from antlr example grammars

额外 Link(s):

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

对我有帮助的有两件事:

  • 直接在grammar test;声明后添加header:@header{ package com.example.something.antlrparser; }到语法文件。
  • 将语法文件放在相应的文件夹中,即src/main/antlr/com/example/something/antlrparser/grammar.g4

现在,当我 运行 generateGrammarSource gradle 任务时, .java 文件在 /build/generated-src/antlr/main/com/example/something/antlrparser/*.java 中生成,它们也会被 IntelliJ 自动拾取由 gradle.

编译

build.gradle 文件只是:

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
}

第 2 期:

您可以在gradle.build中配置:

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

}