1. 序言
-
antlr4-maven-plugin的官方介绍为:
The ANTLR 4 plugin for Maven can generate parsers for any number of grammars in your project.
-
博客《 mac上的Antlr4环境搭建》,有介绍如何通过antlr4-maven-plugin实现.g4文件的编译
-
这里将介绍antlr4-maven-plugin在开源组件中的使用,以及额外的使用注意事项
2. antlr4-maven-plugin在开源组件中的使用
2.1 Presto中 antlr4-maven-plugin的配置
-
以Presto为例,presto-parser模块的pom.xml文件中,对antlr4-maven-plugin的配置非常简单
<build> <plugins> <plugin> <groupId>org.antlr</groupId> <artifactId>antlr4-maven-plugin</artifactId> </plugin> </plugins> </build>
-
这是因为这里的配置,继承了presto-root(项目的父模块)对antlr4-maven-plugin的配置
<dep.antlr.version>4.7.1</dep.antlr.version> <!-- 指定了插件的版本、goal以及是否生成vistor代码 --> <pluginManagement> <plugins> <plugin> <groupId>org.antlr</groupId> <artifactId>antlr4-maven-plugin</artifactId> <version>${dep.antlr.version}</version> <executions> <execution> <goals> <goal>antlr4</goal> </goals> </execution> </executions> <configuration> <visitor>true</visitor> </configuration> </plugin> </pluginManagement>
-
对标在4.1中的配置,这样的配置显得十分精简,例如,缺少sourceDirectory、outputDirectory、listener这三个关键配置
2.2 antlr4-maven-plugin的配置项
-
点击某个配置项,将进入
plugin.xml
中
-
在plugin.xml中可以发现更多信息,里面有配置的name、type、required、description、默认值等
<!-- 定义和描述 --> <parameter> <name>sourceDirectory</name> <type>java.io.File</type> <required>false</required> <editable>true</editable> <description>The directory where the ANTLR grammar files ({@code *.g4}) are located.</description> </parameter> <!-- 默认值 --> <sourceDirectory implementation="java.io.File" default-value="${basedir}/src/main/antlr4"/> <outputDirectory implementation="java.io.File" default-value="${project.build.directory}/generated-sources/antlr4"/>
-
从sourceDirectory和outputDirectory的默认值可以看出,.g4文件的location以及编译生成的Java代码的路径,都与4.1中的差异很大。例如,甚至将生成的Java代码放在了
target/generated-sources/antrl4
目录下,而非我们理解的/src/main/java
目录下
2.3 Presto中的.g4文件以及生成的Java代码
- presto-parser模块,将
SqlBase.g4
文件放在src/main/antlr4/com/facebook/presto/sql/parser
目录下 - 执行
mvn clean install -DskipTests
完成本地编译后,将在target/generated-sources/antlr4/com/facebook/presto/sql/parser
目录下生成相关的Java代码
- 同时,在
src/main/antlr4
下的多层目录,还变成了Java代码中的package信息
- 这些在
target/generated-sources/antlr4
目录下的Java代码,最终将使用同一版本的antlr-runtime进行编译和运行 - 与普通的Java代码一样,这些Java代码编译生成的.class文件,也将放在
target/classes/
目录下
- 这也是为什么在本地运行Presto时,需要先进行一次全局的编译,不然直接运行,将提示各种类找不到
3. antlr4-maven-plugin对JDK的版本要求
-
将antlr版本定义为4.10.1(antlr4-maven-plugin和antlr-runtime的版本都是4.10.1),然后执行
mvn clean install
命令,使用antlr4-maven-plugin编译.g4文件,却发现报错信息如下:java.lang.UnsupportedClassVersionError: org/antlr/v4/Tool has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0 at java.lang.ClassLoader.defineClass1 (Native Method) at java.lang.ClassLoader.defineClass (ClassLoader.java:763) at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass (URLClassLoader.java:468) at java.net.URLClassLoader.access$100 (URLClassLoader.java:74)
-
与之前安装使用高版本的antlr-4.x-complete.jar,遇到的问题一样
-
总结: 使用antlr4-maven-plugin时,要注意不要超过Antlr对应的JDK版本。
-
其中,version与JDK的对应关系,可以参考《Class has been compiled by a more recent version of the Java Environment》