什么是 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 后,包消失了,这导致了问题。
我会在这里添加其他答案。
问题 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"]
}
我创建了新的 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 后,包消失了,这导致了问题。
我会在这里添加其他答案。
问题 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"]
}