2015-06-04 16 views
12

Ich versuche, das GRADLE-AntiLR-Plugin zu verwenden, aber stoßen Sie auf mehrere Probleme.Generieren von ANTLR4-Grammatikdateien mit Paketdeklaration in Gradle

Ich habe eine Grammatikdatei wls.g4 genannt:

grammar WlsScript; 

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

program 
    : 'statementList'? EOF 
    ; 

// Several more grammar and lexer rules 

(. Hinweis: ich die Anweisungsliste nur auf ein Keyword einen richtigen grammer zu machen, ohne die gesamte Grammatik einschließlich ;-))

Diese Datei befindet sich in/src/main/antlr (als Standard-Quellordner der Antitl-Produktionsgrammatikdateien). Hier

ist der Ausschnitt aus build.gradle:

project('common') { 

    apply plugin: 'antlr' 

    dependencies { 
     // Some dependencies 

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

Wenn ich die generateGrammarSource gradle Task (von antlr Plugin comming) die Quelldateien zu erzeugen, die Dateien in build/generated-src/antlr/main Ordner erzeugt, das ist die Standardeinstellung.

Was schief geht, dass es nicht die Ordner des Java-Pakets erstellt (hu/pmi/wls/antlr/ws in unserem Fall), so wird die Quelle in Eclipse falsch sein.

Meine primäre Frage ist, wie könnte ich die Aufgabe zwingen, Quelldateien in einem Paket-strukturierte Weise zu generieren? Mit anderen Worten, wie kann ich die Graplestask konfigurieren, um die Paketdeklaration aus Grammatik zu verwenden?

Danke!

+1

Ich habe das gleiche Problem mit ANTLR 4.5. Ich verwende nur das org.antlr.v4.Tool, um die .g4-Datei zu verarbeiten, und konnte nicht dazu gebracht werden, die Java-Quelle in der entsprechenden Paketnamen-Ordnerstruktur zu generieren. Es könnte Dateien entsprechend dem durch die Option "-o" angegebenen Verzeichnis generieren. Die einzige Möglichkeit besteht darin, die Paketordnerstruktur in der Option "-o" explizit anzugeben. Ich bin mit Gradle nicht vertraut, aber sieh nach, ob es für Gradle eine Möglichkeit gibt, während der Ausführung des ANTLR-Tools Optionen zu übergeben. – anonymous

Antwort

9

Ich hatte genau die gleiche Frage und ich konnte die outputDirectory von der AntlrTask verwendet ändern, um den Paketnamen dort zu bekommen.

Ich fand keine einfache Möglichkeit, das Grammatikpaket aus den Dateien zu extrahieren, also musste ich es in der Aufgabe fest codieren.

+0

Wie versöhnen Sie das in einer IDE? Ich könnte etwas schreiben wie 'import whatever.gen.MyParser' und' MyParser x = new MyParser (...) ', aber die Idee schreit darüber nach, wie sie keine Quelle dafür finden kann - weil die Quelle" gerade rechtzeitig "ist ", aus Mangel an einem besseren Satz. Vielleicht ist es besser, einen gen-src-Ordner zu haben, der von der IDE bestätigt wird, aber unter Versionskontrolle ignoriert wird? ist das gegen Großkonventionen? – Groostav

+1

Sie können das generated-src-Verzeichnis als Quellverzeichnis in der IDE hinzufügen (ich verwende IntelliJ) –

0

Ich habe ähnliches Problem mit Antlr3. Sie können die Positionen fixieren eine Nachbearbeitung der generateGrammarSource Aufgabe anhängt:

/* 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) 
} 
2

zu Ihrem Teilprojekt hinzufügen diese build.gradle

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

dies nach dem „Grammatik“, um Ihre Grammatik hinzuzufügen;

@header { 
    package com.example.parser; 
} 

Getestet und Arbeiten mit Java8 grammar from antlr example grammars

Zusätzliche Link (s):

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

ich dies zwar nicht getestet haben es in Eltern-Projekt setzen, wie es aussieht hast du , sollte aber leicht genug sein, um das zu erreichen. (Ich versuche, das übergeordnete Projekt leer zu halten, außer den zu verwendenden Repositories.)

0

Übertragen Sie eine generierte ANTLR-Datei in den Projektordner und den ZZZ-Unterordner.

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 { 

...

Verwandte Themen