Создание файлов грамматики ANTLR4 с объявлением пакета в gradle

Я пытаюсь использовать плагин gradle antlr, но сталкиваюсь с несколькими проблемами.

У меня есть файл грамматики под названием wls.g4:

grammar WlsScript;

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

program
  : 'statementList'? EOF
  ;

// Several more grammar and lexer rules

(Примечание. Я сделал оператор statement для ключевого слова только для того, чтобы создать правильный грамматик, не включая всю грамматику.; -))

Этот файл находится в /src/main/antlr (в качестве исходной папки по умолчанию для файлов грамматики производства antlr).

Вот фрагмент из build.gradle:

project('common') {

    apply plugin: 'antlr'

    dependencies {
       // Some dependencies

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

Когда я использую задачу generateGrammarSource gradle (начиная с antlr plugin) для генерации исходных файлов, он генерирует файлы в папке build/generated-src/antlr/main, которая по умолчанию.

Что не так, что он не создает папки java-пакета (hu/pmi/wls/antlr/ws в нашем случае), поэтому источник будет неправильно расположен в Eclipse.

Мой основной вопрос: каким образом я могу заставить задачу генерировать исходные файлы структурированным способом?. Другими словами, как настроить задачу gradle для использования объявления пакета из грамматика?

Спасибо!

Ответ 1

У меня был тот же самый вопрос, и я смог изменить outputDirectory, используемый AntlrTask, чтобы получить там имя пакета.

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

Я не нашел простого способа извлечь пакет грамматики из файлов, поэтому ему пришлось жестко задавать его в задаче.

Ответ 2

Добавьте это в свой подпроект build.gradle

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

добавьте это в свою грамматику после своей "грамматики";

@header {
    package com.example.parser;
}

Протестировано и работает с Java8-грамматика из грамматик примера antlr

Дополнительные ссылки:

Вот краткий путеводитель плагина Antlr от docs.gradle.org

Я не тестировал это, помещая его в родительский проект, как будто он выглядит так, как вы, но должен быть достаточно простым, чтобы расширять его. (Я пытаюсь сохранить родительский проект пустым, кроме использования репозиториев.)

Ответ 3

У меня аналогичная проблема с использованием antlr3. Вы можете зафиксировать позиции, добавляющие пост-обработку, в задачу generateGrammarSource:

/* Antlr generated files have wrong position so fix it with a post generation processing */
import groovy.io.FileType
generateGrammarSource << {
    logger.info("Antlr doesn't produce files to rigth place. Fix using package declaration")
    def move = [/*File wrong position*/:/*File rigth position*/]
    generateGrammarSource.outputDirectory.eachFileMatch( FileType.FILES, ~/.*\.java/ ) { f ->
        def pkg = f.readLines().find { it.trim() =~ /^package/ }
        if (pkg) {
            pkg = pkg.split( ' ' )[1].replace( ';','' )
            pkg = pkg.replace( '.','/' )
            move.put( f,new File("${generateGrammarSource.outputDirectory}/$pkg/${f.name}") )
        }
    }
    move.each { s,t ->
    logger.info( "Moving ${s.name} to right location .." )
    t.parentFile.mkdirs()
    s.renameTo( t.absolutePath )
}