ANTLR4入门:使用mave ANTLR4插件(antlr4-maven-plugin)执行语法解析生成器
Posted 10km
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ANTLR4入门:使用mave ANTLR4插件(antlr4-maven-plugin)执行语法解析生成器相关的知识,希望对你有一定的参考价值。
在上篇博客《ANTLR4入门(二):图示说明eclipse安装Antlr4IDE插件的过程》,我费半天劲装好了Eclise的AntlrIDE插件,简单的创建一个ANTLR 4 工程,感受了一下AntlrIDE插件提供的语法高亮的便利性。及语法文件(.g4)自动生成解析器代码的过程
然而热乎劲儿过后,我发现这个插件对于入门学习或许有用,但在基于maven构建的工程开发中实用性并不大,除了语法高亮比较方便外。
在maven管理的项目中,项目编译可以在命令行进行并不一定依赖Eclipse等IDE环境。所以在maven项目中需要使用ANTL4 Maven插件(antlr4-maven-plugin)来实现语法文件到解析器代码的生成。
本文以示例说明如何在项目pom.xml中通过使用ANTLR 4 Maven 插件,来完成语法文件(.g4)自动生成解析器代码,
为了学习ANTLR4插件的使用,我创建了一个antlr4-demo项目,完整的代码放在码云仓库:https://gitee.com/l0km/antlr4-demo.git 供参考
ANTLR 工具命令行选项
在之前的博客《ANTLR4入门(一):Windows安装antlr4命令行环境》,我们知道通过命令行就能执行解析器代码自动生成。如下是命令行执行 antlr-4.11.1-complete.jar显示的命令行参数说明:
D:\\os.package\\devtools\\antlr4>antlr4.bat
ANTLR Parser Generator Version 4.11.1
-o ___ specify output directory where all output is generated(指定所有的生成文件的输出位置)
-lib ___ specify location of grammars, tokens files(指定语法和tokens)文件的位置
-atn generate rule augmented transition network diagrams(生成规则增强转移网络图)
-encoding ___ specify grammar file encoding; e.g., euc-jp(指定语法文件的编码,例如:utf-8)
-message-format ___ specify output style for messages in antlr, gnu, vs2005(指定消息的输出风格:antlr/gun/vs2005)
-long-messages show exception details when available for errors and warnings(显示详细异常信息)
-listener generate parse tree listener (default)(生成语法分析树侦听器,默认)
-no-listener don't generate parse tree listener(不生成语法分析树节点侦听器)
-visitor generate parse tree visitor(生成语法分析树节点访问器)
-no-visitor don't generate parse tree visitor (default)(不生成解析树节点访问器,默认)
-package ___ specify a package/namespace for the generated code(指定生成代码的包名/命名空间)
-depend generate file dependencies(生成文件依赖)
-D<option>=value set/override a grammar-level option(以Key=Value形式设定/覆盖一个语法级的选项)
-Werror treat warnings as errors(将警告当做错误处理)
-XdbgST launch StringTemplate visualizer on generated code(对生成的代码启动StringTemplate可视化器)
-XdbgSTWait wait for STViz to close before continuing
-Xforce-atn use the ATN simulator for all predictions(对所有的预测启动ATN模拟器)
-Xlog dump lots of logging info to antlr-timestamp.log(将详细日志保存为antlr-timestamp.log)
-Xexact-output-dir all output goes into -o dir regardless of paths/package(所有输出写入-o dir指定的位置,忽略路径和包)
关于命令行的详细说明参见:https://github.com/antlr/antlr4/blob/master/doc/tool-options.md
ANTLR 4 Mave 插件(org.antlr:antlr4-maven-plugin)本身也有一些参数定义,从插件执行和命令行执行最终都运行相同的程序。所以这两个体系提供的参数有重合。命令行参数也可以通过插件的arguments
参数来指定
关于插件的参数说明参见 :《ANTLR 4 Maven plugin》
说实话,这个Maven插件写的质量不怎么样,参数设计有些混乱,我是经过很长时间尝试才让插件运行正常,如下是插件设置的完整内容,详细说明参见pom.xml中的注释:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.l0km</groupId>
<artifactId>antlr4-demo</artifactId>
<version>0.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>antlr4-demo</name>
<url>https://gitee.com/l0km/antlr4-demo</url>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- ANTLR 4 从4.10 版本后最低要求的JDK版本升到了11,所以如果还想在JDK8下运行行ANTLR4可以只能使用4.9.3 -->
<antlr4.vesion>4.9.3</antlr4.vesion>
<!-- <antlr4.vesion>4.11.1</antlr4.vesion> -->
<!-- 定义antlr4插件输出生成代码的位置-->
<antlr4.dir>$project.build.directory/generated-sources/antlr4</antlr4.dir>
<!--
如果希望将antlr4生成的代码加入git版本控制,
就不能将antlr4.dir定义在$project.build.directory文件夹下,如下定义在src文件夹中 -->
<!--<antlr4.dir>$basedir/src/antlr4/java</antlr4.dir>-->
<!-- surefire 插件 跳过测试 -->
<skipTests>true</skipTests>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- 增加antlr4 运行时库依赖 -->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>$antlr4.vesion</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 执行插件 antlr4:antlr4,根据语法文件(.g4)生成解析器(java)代码
完整说明参见 antlr4-maven-plugin 官方文档:
https://www.antlr.org/api/maven-plugin/latest/plugin-info.html
也可以命令行执行 mvn antlr4:help -Ddetail=true -Dgoal=antlr4 查看在线说明
-->
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>$antlr4.vesion</version>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
<configuration>
<arguments>
<!-- 命令行参数 -package $package 定义生成java代码的包名-->
<argument>-package</argument>
<argument>com.gitee.l0km.parser</argument>
<!-- 输出生成的Java源码文件位置
这里的输出文件夹定义一定要与上面 -package 定义的包名匹配
-->
<argument>-o</argument>
<argument>$antlr4.dir/com/gitee/l0km/parser</argument>
</arguments>
<!-- 指定语法文件的编码方式,默认utf-8 -->
<!--<inputEncoding>utf-8</inputEncoding>-->
<!-- ANTLR 语法文件(.g4) 所在位置-->
<sourceDirectory>$basedir/src/main/java/com/gitee/l0km/parser</sourceDirectory>
<!-- 生成语法树侦听器(Listener)代码,默认为true -->
<listener>true</listener>
<!-- 生成语法树访问器(Visitor)代码,默认为false-->
<visitor>true</visitor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
- 不建议使用插件的
outputDirectory
参数指定输出文件夹。如上pom.xml,使用命令行参数-o
代替。 - 因为所有的解析代码器都可以由语法文件生成,所以ANTLR4一般将生成的解析器代码视为中间文件,所以在本例中,也是一样,将生成的解析器代码放在了target文件夹,也就是没有保存,如果希望保存,那就换个文件夹不要指向target。
Maven执行
在antlr4-demo下执行mvn install
,如下即可看到antlr4-maven-plugin
的执行输出
guyadong@guyadong-PC MINGW64 /j/antlr4-demo (master)
$ mvn install
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< com.gitee.l0km:antlr4-demo >---------------------
[INFO] Building antlr4-demo 0.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- antlr4-maven-plugin:4.9.3:antlr4 (default) @ antlr4-demo ---
[INFO] ANTLR 4: Processing source directory J:\\antlr4-demo\\src\\main\\java\\com\\gitee\\l0km\\parser
[INFO] Processing grammar: Hello.g4
[INFO]
[INFO] --- build-helper-maven-plugin:3.0.0:add-source (add-source) @ antlr4-demo ---
[INFO] Source directory: J:\\antlr4-demo\\target\\antlr4-generated\\java added.
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ antlr4-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory J:\\antlr4-demo\\src\\main\\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ antlr4-demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 7 source files to J:\\antlr4-demo\\target\\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ antlr4-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory J:\\antlr4-demo\\src\\test\\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ antlr4-demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to J:\\antlr4-demo\\target\\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ antlr4-demo ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ antlr4-demo ---
[INFO] Building jar: J:\\antlr4-demo\\target\\antlr4-demo-0.0.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ antlr4-demo ---
[INFO] Installing J:\\antlr4-demo\\target\\antlr4-demo-0.0.0-SNAPSHOT.jar to J:\\maven_repository\\com\\gitee\\l0km\\antlr4-demo\\0.0.0-SNAPSHOT\\antlr4-demo-0.0.0-SNAPSHOT.jar
[INFO] Installing J:\\antlr4-demo\\pom.xml to J:\\maven_repository\\com\\gitee\\l0km\\antlr4-demo\\0.0.0-SNAPSHOT\\antlr4-demo-0.0.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.002 s
[INFO] Finished at: 2022-12-19T16:39:35+08:00
[INFO] ------------------------------------------------------------------------
Java 8下执行
ANTLR 4 从4.10 版本后最低要求的JDK版本升到了Java 11,所以如果在Java 8上运行ANTLR4只能使用4.9.3以下的版本。
如果希望在不改变自己的当前默认JDK版本的情况使用最新的ANTLR4版本,建议使用如下脚本来执行mvn命令
mvn11.bat – 使用Java 11执行MAVEN命令
@ECHO OFF
SETLOCAL
SET JAVA_HOME=C:\\Program Files\\Java\\jdk-11.0.11
SET PATH=%JAVA_HOME%\\bin;%PATH%
mvn %*
ENDLOCAL
SETLOCAL/ENDLOCAL
指令之间SET定义/修复的环境变量都只作用于当前脚本,不会影响系统的环境变量
代码结构
用Eclipse打开antlr4-demo,显示的项目结构如下:
完整的代码放在码云仓库:https://gitee.com/l0km/antlr4-demo.git
参考资料
《ANTLR 4 Maven plugin》
《ANTLR 工具命令行选项》
以上是关于ANTLR4入门:使用mave ANTLR4插件(antlr4-maven-plugin)执行语法解析生成器的主要内容,如果未能解决你的问题,请参考以下文章
ANTLR4入门:图示说明eclipse安装Antlr4IDE插件的过程
ANTLR4入门:图示说明eclipse Antlr4IDE插件的安装及语法测试过程
1.ANTLR4 helloworld基础开发与IDEA插件使用