当前位置: 首页 > 知识库问答 >
问题:

如何声明gradle Antlr任务输出规范以避免不必要的重建

昝成弘
2023-03-14

我有一个典型的Antlr 4.5项目,其中有两个语法文件:MyLexer。g4和MyParser。Antlr从中生成6个输出文件:MyLexer。java,MyLexer。标记,MyParser。java,MyParser。令牌,MyParserBaseListener。java和MyParserListener。Java语言gradle任务都工作正常,因此输出文件都按预期生成、编译和测试

问题是gradle认为这6个目标文件总是过时,因此每次运行或调试会话都必须重新生成它们,因此即使源文件没有更改,也必须重新编译主java项目。

生成文件的gradle任务将输出规范定义为生成6个输出文件的文件夹。我认为我需要一种方法将其定义为6个特定文件而不是输出文件夹。我只是不知道这样做的语法。

这是我构建的相关部分。gradle文件:

ext.antlr4 = [
    antlrSource:    "src/main/antlr",
    destinationDir: "src/main/java/com/myantlrquestion/core/antlr/generated",
    grammarpackage:               "com.myantlrquestion.core.antlr.generated"
]

task makeAntlrOutputDir << {
    file(antlr4.destinationDir).mkdirs()
}

task compileAntlrGrammars(type: JavaExec, dependsOn: makeAntlrOutputDir) {
    // Grammars are conveniently sorted alphabetically. I assume that will remain true.
    // That ensures that files named *Lexer.g4 are listed and therefore processed before the corresponding *Parser.g4
    // It matters because the Lexer must be processed first since the Parser needs the .tokens file from the Lexer.
    // Also note that the output file naming convention for combined grammars is slightly different from separate Lexer and Parser grammars.
    def grammars = fileTree(antlr4.antlrSource).include('**/*.g4')
    def target = file("${antlr4.destinationDir}")
    inputs.files grammars
    // TODO: This output spec is incorrect, so this task is never considered up to date.
    // TODO: Tweak the outputs collection so it is correct with combined grammars as well as separate Lexer and Parser grammars.
    outputs.dir target

    main = 'org.antlr.v4.Tool'
    classpath = configurations.antlr4
    // Antlr command line args are at https://theantlrguy.atlassian.net/wiki/display/ANTLR4/ANTLR+Tool+Command+Line+Options
    args = ["-o", target,
            "-lib", target,
            //"-listener",      //"-listener" is the default
            //"-no-visitor",    //"-no-visitor" is the default
            "-package", antlr4.grammarpackage,
            grammars.files 
    ].flatten()

    // include optional description and group (shown by ./gradlew tasks command)
    description = 'Generates Java sources from ANTLR4 grammars.'
    group       = 'Build'
}

compileJava {
    dependsOn compileAntlrGrammars
    // this next line isn't technically needed unless the antlr4.destinationDir is not under buildDir, but it doesn't hurt either
    source antlr4.destinationDir
}

task cleanAntlr {
    delete antlr4.destinationDir
}
clean.dependsOn cleanAntlr

共有2个答案

谯嘉木
2023-03-14

请尝试以下代码:

generatedFiles = ['MyLexer.java',] // and so on..
generatedFiles.each { f -> outputs.file("$target/$f") }
魏岳
2023-03-14

我发现问题不在于目标文件过期了,而是因为在清理Antlr任务中的一个错误,每次运行任何gradle任务时,它们都会被删除。问题是在gradle的初始化和配置阶段,即使清理Antlr任务本身没有被执行,清理Antlr中的所有代码都在运行。

最初,任务定义为:

task cleanAntlr {
    delete antlr4.destinationDir
}
clean.dependsOn cleanAntlr

解决方案是这样定义它:(注意“

task cleanAntlr << {
    delete antlr4.destinationDir
}
clean.dependsOn cleanAntlr

...或者,为了更加清晰,请使用这个更详细但功能等效的任务定义:

task cleanAntlr {
    doLast() {
        // Be sure to wrap the execution phase code inside doLast(). 
        // Otherwise it will run during the initialization or configuration phase, even when an unrelated task is is run.
        // It would also run when the NetBeas IDE first loaded the project.
        //println 'Deleting Antlr Directory: ' + antlr4.destinationDir
        delete antlr4.destinationDir
    }
}
clean.dependsOn cleanAntlr

修复该错误后,CompileantlRGramars任务的原始输出规范可以正常工作。无需指定每个单独的输出文件。第15.9.2节对此进行了很好的解释https://gradle.org/docs/current/userguide/more_about_tasks.html.

def grammars = fileTree(antlr4.antlrSource).include('**/*.g4')
def target = file("${antlr4.destinationDir}")
inputs.files grammars
outputs.dir target
 类似资料:
  • 本文向大家介绍在React中如何避免不必要的render?相关面试题,主要包含被问及在React中如何避免不必要的render?时的应答技巧和注意事项,需要的朋友参考一下 shouldComponentUpdate、memoization、PureComponent

  • 我大致了解了TensorFlow图在评估它包含的之一时是如何评估的:该张量的或的执行将触发图中所需的所有级联计算计算该张量的值,因此,图中“导致它”的任何张量也将被计算,并且连接它们的任何操作都将被运行。 因此,如果我有一个包含张量out\u a的图,其计算涉及(可能在许多其他事情中)使用int\u b的操作,这反过来(最终)需要执行本身(最终)使用in的操作 将只评估、和一次:和的计算都使用的相

  • 有时我的connectedAndroidTest实际上并不执行任何测试,即使似乎找到了连接的设备。我最后得到了一个如下所示的报告: 执行,我得到: 我重启了一次设备,得到了我的报告。但这并不总是有帮助的。 我使用的是三星Tab2,运行的是Android4.1.1。我在OS X 10.9.4的Mac电脑上使用Gradle/最新的Android Studio。想法?

  • 我有一个Java servlet,它从android应用程序中获取一些数据,并使用以下代码将字符串数据返回给android应用程序。 然后使用以下方法将该值转换为字符串: 但是这样做之后,结果会添加一些不需要的字符(它们在菱形中以“?”的形式出现)附加到我从servlet传递的原始字符串中。我怎样才能避免这个?

  • 我正在编写一些Swing应用程序,用于使用MigLayout进行测量。我试图消除不必要的差距。 我已经注意到,由于顶部的句子,差距是存在的。然而,当我删除它时,它看起来很好。 该问题在下图中可见: 我加句子的方式是: 我添加按钮的方式: 有人能帮我解释一下为什么会发生这种情况,以及我如何消除与现在句子的差距吗? ////////////编辑 我想使用我当前的基础架构,我已经在miglaway中启用

  • 本文向大家介绍C# 如何规范的写 DEBUG 输出,包括了C# 如何规范的写 DEBUG 输出的使用技巧和注意事项,需要的朋友参考一下 经常在代码中,需要使用 DEBUG 来输出一些奇怪的东西来进行测试。但是输出的窗口只有一个,如果有一个逗比在不停输出,那么就会让输出窗口看不到自己的内容。 于是逗比喜欢自己的测试代码,因为他需要不停看到输出窗口在说自己,但是正常的程序员是只看有用的东西,所以他就会