使用gradle中的包声明生成ANTLR4语法文件

时间:2015-06-04 11:02:44

标签: gradle antlr4

我尝试使用gradle antlr插件,但遇到了几个问题。

我有一个名为wls.g4的语法文件:

grammar WlsScript;

@header {
   package hu.pmi.wls.antlr.ws;
} 

program
  : 'statementList'? EOF
  ;

// Several more grammar and lexer rules

注意:我将statementList设为一个关键字只是为了制作一个正确的语法而不包括整个语法。; - )

此文件位于/ src / main / antlr(作为antlr生产语法文件的默认源文件夹)。

以下是build.gradle的摘要:

project('common') {

    apply plugin: 'antlr'

    dependencies {
       // Some dependencies

       antlr "org.antlr:antlr4:4.5"
    }
} 

当我使用generateGrammarSource gradle任务(来自antlr插件)生成源文件时,它会生成build/generated-src/antlr/main文件夹中的文件,这是默认文件。

出了什么问题,它没有创建java包的文件夹(在我们的例子中为hu/pmi/wls/antlr/ws),因此源代码将错误地放在Eclipse中。

我的主要问题是如何强制任务以包结构的方式生成源文件?换句话说,如何配置gradle任务以使用语法包声明?

谢谢!

5 个答案:

答案 0 :(得分:13)

我有完全相同的问题,我能够更改AntlrTask使用的outputDirectory来获取包名称。

generateGrammarSource {
    outputDirectory = new File("${project.buildDir}/generated-src/antlr/main/net/example".toString())
}

我发现没有简单的方法从文件中提取语法包,因此必须在任务中对其进行硬编码。

答案 1 :(得分:5)

将此添加到您的子项目build.gradle

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

在你的"语法";

之后将它添加到你的语法中
@header {
    package com.example.parser;
}

经过测试并使用Java8 grammar from antlr example grammars

其他链接:

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

我没有对它进行测试,同时将它放在父项目中,就像你看起来一样,但应该很容易扩展到这样做。 (我尝试将父项目保留为空,而不是使用存储库。)

答案 2 :(得分:0)

我使用antlr3有类似的问题。 您可以将附加后处理的位置修复为generateGrammarSource任务:

n

答案 3 :(得分:0)

将生成的ANTLR文件传输到项目文件夹和ZZZ子文件夹。

antlr.g4

...

@header {
package XXX.YYY.ZZZ;
}

.....

的build.gradle

group 'XXX'
version '0.0.1'

apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'antlr'
apply plugin: 'eclipse'

mainClassName = 'XXX.YYY.Test'
final antlr4Version = '4.7'
final antlrGen = 'gen'
final baseDir = 'src/main/java'

repositories {
    mavenCentral()
}

dependencies {
    antlr "org.antlr:antlr4:"+antlr4Version
}

generateGrammarSource {
    outputDirectory = file(antlrGen)
    maxHeapSize = '64m'
    arguments += ['-visitor', '-long-messages']
}

generateGrammarSource.doLast {
    moveAntlrGeneratedFilesToTheirPackages(source, antlrGen, baseDir)
}

def moveAntlrGeneratedFilesToTheirPackages(FileTree grammarFiles, generatedFolder, destFolder) {
    grammarFiles.each {File file ->
        final grammarName = file.name.lastIndexOf('.') >= 0 ? file.name[0 .. file.name.lastIndexOf('.') - 1] : file.name
        final grammarPackage = extractPackageNameFromGrammerFile(file)
        copy {
            from generatedFolder
            include "${grammarName}*.*"
            into destFolder + "/" + grammarPackage.replaceAll("\\.", "/")
        }
    }
    project.delete fileTree(generatedFolder).include('*.*')
}

def extractPackageNameFromGrammerFile(File grammarFile) {
    def grammarPackage = "unknown.package"
    def packageRegex = ~/[ ]*package[ ]*([a-zA-Z]+[a-zA-Z0-9.-_]*)[ ]*;/
    grammarFile.eachLine { line ->
        def matcher = packageRegex.matcher(line)
        if (matcher.find()){
            grammarPackage = matcher.group(1)
        }
    }
    return grammarPackage
}

jar {
    baseName = 'XXX.YYY'
    version =  '1.0.0'
    manifest.attributes('Main-Class': mainClassName);
}

task wrapper(type: Wrapper) {
}

Test.java

package XXX.YYY;

import java.lang.Exception;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import XXX.YYY.ZZZ.*;

public static void main(String[] args) throws Exception {

...

答案 4 :(得分:0)

将语法文件放在hu/pmi/wls/antlr/ws目录中。