1. 絮絮叨叨
- 读研时,需要基于不同的应用(大数据组件)比较HDFS改造后的性能,当时有使用到Impala
- 当时,导师给我推荐了ANTLR(
ANother Tool for Language Recognition
),说这个东西很有趣,可以研究研究 - 可是自己心浮气躁,一看介绍就怂了:词法解析、语法解析?那不是编译原理吗?本科时《编译原理》自己考的不错,但也离不开老师的仁慈和临时抱佛脚啊。
ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files. It’s widely used to build languages, tools, and frameworks. From a grammar, ANTLR generates a parser that can build and walk parse trees.
- 现在由于工作原因,接触的大数据组件很多都使用ANTLR定义SQL的解析规则,不得不静下心来,重新学习ANTLR
- 目前使用的ANTLR版本已经是4.x,因此ANTLR一般又叫
antlr4
2. windows上安装antlr4
2.1 选择合适的antlr4安装包
-
本人使用的开发语言主要是Java,因此本文或者后续的文章都会使用Java作为目标语言
code generation target
-
安装antlr4前,需要检查自己的Java版本,如果低版本的Java却安装高版本的antlr4,使用时会报错:
Execute 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
-
class文件的version与Java的对应关系,可以参考记录了class file version与JDK版本对应关系的博客
下载最新的jar包
- 如果windows上安装的是Java 11,则可以下载最新的jar包
- 具体做法:antlr4的官方下载页面,点击红框中的链接,可以下载最新的jar包
下载历史jar包
- 本人的Java version为1.8,因此只能下载旧版本的antlr4
- 具体做法:antlr4的官方下载页面的最底部,点击
download
,进入下载列表,选择合适的jar包 —— 本人选择的是antlr-4.8-complete.jar
2.2 安装anltr4
-
将下载的jar放在一个合适的目录,本人将其放到了
D:\antlr4
-
修改系统环境变量
CLASSPATH
,在尾部添加如下内容;D:\antlr4\antlr-4.8-complete.jar
-
修改系统环境变量
Path
,新建一个antlr4的entry,内容为jar包所在的目录,以便系统可以自动执行D:\antlr4\
目录下的bat
文件D:\antlr4\
-
在
D:\antlr4\
目录,新建antlr4.bat
文件,用于编译.g4
文件,生成各种.java
文件java org.antlr.v4.Tool %*
-
在
D:\antlr4\
目录下,新建grun.bat
文件,从而可以基于TestRig
测试工具、在不创建主程序的情况下测试文法java org.antlr.v4.gui.TestRig %*
-
最终,
D:\antlr4\
目录存在以下文件
-
打开命令提示符,执行
antlr4
命令,将有如下输出:
-
执行grun命令,输出如下:
2.3 一些说明
bat文件的创建
- 在windows中,右键 —> 新建 —> 文本文档,将生成以
.txt
结尾的文本文档 - 需要修改文件扩展名,才能得到想要的文件
- 所以,笔者一般都是使用类似
vscode
的文本编辑器创建不同扩展名的文件,然后移动到目标目录
grun.bat
文件的内容
-
在参考文档Setting up ANTLR4 on Windows中,
grun.bat
文件的内容如下:java org.antlr.v4.runtime.misc.TestRig %*
-
在执行
grun
命令时,会有Warning提示:
3. antlr4的简单使用
3.1 antlr4命令编译.g4文件
-
参考官方文档中的A First Example,编写一个简单的
Hello.g4
文件,用于识别类似hello xxx
的语法// Define a grammar called Hello grammar Hello; r : 'hello' ID ; // match keyword hello followed by an identifier ID : [a-z]+ ; // match lower-case identifiers WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
-
注意: .g4文件的文件名应与
grammar xxx
一致,因此该.g4文件名为Hello.g4
-
进入
Hello.g4
所在的目录,使用antlr4
命令编译Hello.g4
d: cd antlr4\file antlr4 Hello.g4
-
在
file/
目录,将生成很多以Hello开头的.java
文件
-
使用
javac
编译生成的Java文件javac Hello*.java
3.2 grun命令测试rule
-
使用
grun
命令,测试Hello语法- windows中,使用
ctrl + Z
表示EOF(^
Z) - linux、mac中
ctrl + D
表示EOF(^D
)
# Hello为语法名,r为规parser rule(语法解析规则),-tree:以 LISP 表示法打印分析树 grun Hello r -tree
- windows中,使用
-
执行结果如下:
-
此外,还可以通过可视化的树形结构展示语法分析树
grun Hello r -gui
-
最终将弹出一个Java图形化界面,展示语法分析树
-
博客《antlr4 简明教程 —— 入门》 ,还提到了使用
-tokens
选项打印词法分析生成的token(单词)grun Hello r -tokens
-
执行结果如下:
- antlr4命令的官方说明文档:ANTLR Tool Command Line Options
- grun(即TestRig)的官方说明文档,暂未发现。
4. 后记
- 使用antlr4的过程中,发现自己连语法分析、词法分析、抽象语法树啥的度不怎么清楚😂
- 感谢 Antlr4简易快速入门,帮助自己以上术语有一个快速地了解
- 按照自己喜欢有把握的"狗脾气"来说,下一步当然是需要恶补下编译原理的有关知识😂