使用maven antlr4插件从其他工件生成语法

时间:2013-05-22 03:46:06

标签: maven antlr4

我想使用antlr4为语法生成一个java解析器api。我意识到其他人可能对语法部分感兴趣,所以我想将maven中的解析器工件与语法工件分开。

我几乎得到了所有工作,问题似乎是它使用正确的包生成* .java文件,但将它们放在代表不同包的目录中。

我有一个包含父项和两个模块的多模块maven项目;语法和解析器。语法生成一个包含以下内容的简单jar:

META-INF/
META-INF/MANIFEST.MF
org/
org/boazglean/
org/boazglean/dabar/
org/boazglean/dabar/grammer/
org/boazglean/dabar/grammer/DabarLexer.g4
org/boazglean/dabar/grammer/DabarParser.g4
META-INF/maven/
META-INF/maven/org.boazglean.dabar/
META-INF/maven/org.boazglean.dabar/grammer/
META-INF/maven/org.boazglean.dabar/grammer/pom.xml
META-INF/maven/org.boazglean.dabar/grammer/pom.properties

现在我想生成一个解析器jar,在包org.boazglean.dabar.parser中包含一堆解析器类。这是我使用的pom配置:

<plugin>
    <groupId>org.antlr</groupId>
    <artifactId>antlr4-maven-plugin</artifactId>
    <version>4.0</version>
    <executions>
        <execution>
            <goals>
                <goal>antlr4</goal>
            </goals>
            <configuration>
                <sourceDirectory>${antlr.dir}</sourceDirectory>
                <listener>true</listener>
                <visitor>true</visitor>
                <arguments>
                    <argument>-package</argument>
                    <argument>org.boazglean.dabar.parser</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>extract-grammer</id>
            <phase>initialize</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
                <includeArtifactIds>grammer</includeArtifactIds>
                <outputDirectory>${antlr.dir}</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

现在问题是生成的源出现在错误的目录中(但它们确实有正确的包)。

head -n 2 parser/target/generated-sources/antlr4/org/boazglean/dabar/grammer/DabarLexer.java 

// Generated from org/boazglean/dabar/grammer/DabarLexer.g4 by ANTLR 4.0
package org.boazglean.dabar.parser;

我错过了一些命令我应该用?

配置antlr4

3 个答案:

答案 0 :(得分:4)

  1. 制作语法文件夹结构 /src/main/antlr4/org/nimy/antlr4/xml/xxxx.g4

  2. pom.xml中的
  3. <plugin>
                <groupId>org.antlr</groupId>
                <artifactId>antlr4-maven-plugin</artifactId>
                <version>4.1</version>
                <configuration>
                    <configuration>
                        <listener>true</listener>
                        <visitor>true</visitor>
                        <arguments>
                            <argument>-package</argument>
                        </arguments>
                    </configuration>
                </configuration>
                <executions>
                    <execution>
                        <id>antlr-generate</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>antlr4</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    
  4. 在包中生成Java代码: 包org.nimy.antlr4.xml

  5. github上的antlt4 maven插件源代码。尝试阅读它并获得配置项目的方法。 antlr4 source code

答案 1 :(得分:0)

这看起来正在做完全它应该是什么。实际上,您甚至不需要在pom.xml中指定-package参数,因为它是根据项目中.g4文件的位置自动确定的。

编辑:

如果您希望将输出文件放在org/boazglean/dabar/parser中,那么您还需要将输入文件放在该路径下。

答案 2 :(得分:0)

对于语法项目。文件夹结构应如下所示:

ls -R grammar/
grammar/:
pom.xml  src

grammar/src:
main  test

grammar/src/main:
resources

grammar/src/main/resources:
org

grammar/src/main/resources/org:
boazglean

grammar/src/main/resources/org/boazglean:
dabar

grammar/src/main/resources/org/boazglean/dabar:
grammar

grammar/src/main/resources/org/boazglean/dabar/grammar:
DabarLexer.g4  DabarParser.g4

现在,当你构建这个项目时,你将拥有一个像这样结构的jar:

jar -tf grammar/target/grammar-1.0-SNAPSHOT.jar 
META-INF/
META-INF/MANIFEST.MF
org/
org/boazglean/
org/boazglean/dabar/
org/boazglean/dabar/grammar/
org/boazglean/dabar/grammar/DabarParser.g4
org/boazglean/dabar/grammar/DabarLexer.g4
META-INF/maven/
META-INF/maven/org.boazglean.dabar/
META-INF/maven/org.boazglean.dabar/grammar/
META-INF/maven/org.boazglean.dabar/grammar/pom.xml
META-INF/maven/org.boazglean.dabar/grammar/pom.properties

现在进行解析器项目。它将使用org.boazglean.dabar.grammar中的语法并在org.boazglean.dabar.parser中生成解析器

对于解析器项目。文件夹结构应如下所示:

ls -R parser/
parser/:
pom.xml  src

parser/src:
test

parser/src/test:
java

parser/src/test/java:
org

parser/src/test/java/org:
boazglean

parser/src/test/java/org/boazglean:
dabar

parser/src/test/java/org/boazglean/dabar:
parser

parser/src/test/java/org/boazglean/dabar/parser:
DabarLexerTest.java

现在重磅出现在pom.xml中 供以后使用:

<properties>
    <antlr.grammar.dir>${project.build.directory}/grammar/</antlr.grammar.dir>
    <antlr.parser.dir>${project.build.directory}/generated-sources/antlr/</antlr.parser.dir>
</properties>

首先,我们需要从语法jar中提取语法。这允许antlr对它运行。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>extract-grammar</id>
            <phase>initialize</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
                <includeArtifactIds>grammar</includeArtifactIds>
                <outputDirectory>${antlr.grammar.dir}</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

现在下载了语法,我们可以生成解析器。为了做到这一点,我们需要将antlr指向包的根目录($ {antlr.grammar.dir}),但是在包的顶部$ {antlr.grammar.dir} / org / boazglean / dabar / grammar /同样,我们必须生成不在包{$ project.build.directory} / generated-sources / antlr /的根目录下的java文件,而是在包$ $ project.build.directory的顶部。 } /生成来源/ ANTLR /组织/ boazglean /达巴尔/解析器。为了使其与项目的groupId和artifactId保持一致,我们将使用构建帮助程序插件生成一些新属性,以替换所有&#39;。&#39;在groupId中&#39; /&#39;形成路径。

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>antlr.grammar.package.dir</id>
            <goals>
                <goal>regex-property</goal>
            </goals>
            <configuration>
                <name>antlr.grammar.package.dir</name>
                <regex>\.</regex>
                <value>${antlr.grammar.dir}/${project.groupId}/grammar</value>
                <replacement>/</replacement>
            </configuration>
        </execution>
        <execution>
            <id>antlr.parser.package.dir</id>
            <goals>
                <goal>regex-property</goal>
            </goals>
            <configuration>
                <name>antlr.parser.package.dir</name>
                <regex>\.</regex>
                <value>${antlr.parser.dir}/${project.groupId}/${project.artifactId}</value>
                <replacement>/</replacement>
            </configuration>
        </execution>
    </executions>
</plugin>

现在我们有两个新属性; antlr.grammar.package.dir,antlr.parser.package.dir,它为我们提供了antlr所需的正确路径。现在我们可以调用antlr

<plugin>
    <groupId>org.antlr</groupId>
    <artifactId>antlr4-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>generate-antlr-sources</id>
            <goals>
                <goal>antlr4</goal>
            </goals>
            <configuration>
                <sourceDirectory>${antlr.grammar.package.dir}</sourceDirectory>
                <listener>true</listener>
                <visitor>true</visitor>
                <outputDirectory>${antlr.parser.package.dir}</outputDirectory>
                <arguments>
                    <argument>-package</argument>
                    <argument>${project.groupId}.${project.artifactId}</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

最后一件事,antlr生成非常有用的令牌文件。但在这一点上,他们不会进入你的parser.jar。所以我们将其添加为资源。我们不想添加位于令牌文件旁边的java文件,因此我们将向资源中添加一个排除项:

<resource>
    <directory>${antlr.parser.dir}</directory>
    <includes>
        <include>**/*.tokens</include>
    </includes>
</resource>

现在你可以构建,你的测试将能够使用antlr生成的解析器,你的解析器jar将如下所示:

jar -tf parser/target/parser-1.0-SNAPSHOT.jar 
META-INF/
META-INF/MANIFEST.MF
org/
org/boazglean/
org/boazglean/dabar/
org/boazglean/dabar/parser/
org/boazglean/dabar/parser/DabarLexer.tokens
org/boazglean/dabar/parser/DabarParser.tokens
org/boazglean/dabar/parser/DabarLexer.class
org/boazglean/dabar/parser/DabarParserListener.class
org/boazglean/dabar/parser/DabarParser$ProgramContext.class
org/boazglean/dabar/parser/DabarParser$PhraseContext.class
org/boazglean/dabar/parser/DabarParser$CallContext.class
org/boazglean/dabar/parser/DabarParser$PassContext.class
org/boazglean/dabar/parser/DabarParser$ReferenceContext.class
org/boazglean/dabar/parser/DabarParser$SentenceContext.class
org/boazglean/dabar/parser/DabarParser$CompoundContext.class
org/boazglean/dabar/parser/DabarParser$BlockContext.class
org/boazglean/dabar/parser/DabarParser.class
org/boazglean/dabar/parser/DabarParserBaseVisitor.class
org/boazglean/dabar/parser/DabarParserVisitor.class
org/boazglean/dabar/parser/DabarParserBaseListener.class
META-INF/maven/
META-INF/maven/org.boazglean.dabar/
META-INF/maven/org.boazglean.dabar/parser/
META-INF/maven/org.boazglean.dabar/parser/pom.xml
META-INF/maven/org.boazglean.dabar/parser/pom.properties

成功。