ANTLR4:高效构建语言解析器的秘密武器,让代码解析不再‘烧脑’,开发者必备技能

可以直接在Antlr4网站进行实践:ANTLR Lab: learn, test, and experiment with ANTLR grammars online!

这里有很多语言的例子:grammars-v4/lisp at master · antlr/grammars-v4 

中文文档:ANTLR v4 中文文档 

学习 ANTLR4 是一个非常棒的选择!它是一个功能强大且灵活的语法分析器生成器,适用于构建各种语言工具。以下是一些建议,帮助你更有效地学习 ANTLR4:

ANTLR4学习资料

1. 学习基础知识

  • 编译原理: 了解编译器的基本概念,如词法分析、语法分析、语义分析等。可以阅读一些经典的编译原理书籍,如《编译原理》(龙书)或《现代编译原理》(虎书)。
  • 形式语言与自动机: 了解形式语言、正则文法、上下文无关文法、有限状态自动机、下推自动机等概念,这对理解 ANTLR4 的工作原理非常有帮助。

2. 安装 ANTLR4 工具

  • 安装 ANTLR4 运行时库: 根据你使用的编程语言,安装相应的 ANTLR4 运行时库。例如,如果你使用 Java,可以使用 Maven 或 Gradle 添加 ANTLR4 的依赖。
  • 下载 ANTLR4 工具: 下载 ANTLR4 的命令行工具,包括 antlr4 (用于生成词法分析器和语法分析器代码) 和 grun (用于测试语法规则)。

3. 学习 ANTLR4 语法

  • ANTLR4 语法文件: 学习如何编写 ANTLR4 语法文件(.g4 文件),包括定义词法规则 (lexer rules) 和语法规则 (parser rules)。
  • 词法规则: 学习如何使用正则表达式定义词法规则,例如标识符、数字、字符串等。
  • 语法规则: 学习如何使用上下文无关文法定义语法规则,例如表达式、语句、函数定义等。
  • 语法分析树: 了解 ANTLR4 如何生成语法分析树 (parse tree),以及如何使用 Visitor 或 Listener 模式遍历语法分析树。

4. 实践项目

  • 简单计算器: 从一个简单的计算器开始,逐步增加功能,例如支持变量、函数调用等。
  • JSON 解析器: 尝试编写一个 JSON 解析器,将 JSON 字符串解析为数据结构。
  • 领域特定语言 (DSL): 设计并实现一个简单的 DSL,用于特定领域的任务,例如配置管理、数据处理等。
  • 代码生成器: 尝试编写一个代码生成器,将一种语言的代码转换为另一种语言的代码。

5. 阅读 ANTLR4 官方文档

  • ANTLR4 官方文档非常详细,包含了 ANTLR4 的各种特性和使用方法。

6. 阅读书籍

  • 《The Definitive ANTLR 4 Reference》: Terence Parr 编写的 ANTLR4 权威参考书,强烈推荐阅读。

7. 参与社区

  • ANTLR 社区: 加入 ANTLR 社区,参与讨论、提问、分享经验,与其他 ANTLR4 开发者交流。
  • GitHub: 在 GitHub 上搜索 ANTLR4 相关的项目,学习其他开发者的代码。

8. 示例代码

以下是一个简单的 ANTLR4 语法文件示例(Calc.g4):

grammar Calc;

// Parser Rules
prog:   stat+ ;
stat:   expr NEWLINE                # printExpr
    |   ID '=' expr NEWLINE         # assign
    |   NEWLINE                     # blank
    ;
expr:   expr op=('*'|'/') expr      # MulDiv
    |   expr op=('+'|'-') expr      # AddSub
    |   INT                         # int
    |   ID                          # id
    |   '(' expr ')'                # parens
    ;

// Lexer Rules
ID  :   [a-zA-Z]+ ;
INT :   [0-9]+ ;
NEWLINE  :   '\r'? '\n' ;
WS  :   [ \t]+ -> skip ;

9. 学习资源

  • ANTLR 官方网站ANTLR
  • 《The Definitive ANTLR 4 Reference》: Terence Parr 著。

希望这些建议能帮助你更好地学习 ANTLR4!

VSCode插件安装

ANTLR4 有插件,在VSCode插件系统里搜索ANTLR4 grammar syntax support 即可。

python ANTlR4使用

官网:ANTLR

学习参考:raw.githubusercontent.com/antlr/antlr4/master/doc/getting-started.md 

pip安装

pip install antlr4-tools

语法测试文件

一个小例子Expr.g4 ,将下面代码存到文件里。

grammar Expr;		
prog:	expr EOF ;
expr:	expr ('*'|'/') expr
    |	expr ('+'|'-') expr
    |	INT
    |	'(' expr ')'
    ;
NEWLINE : [\r\n]+ -> skip;
INT     : [0-9]+ ;

 分析测试

执行语法分析

E:\work\antlr4>antlr4-parse Expr.g4 prog -tree
10+20+3
^Z
(prog:1 (expr:2 (expr:2 (expr:3 10) + (expr:3 20)) + (expr:3 3)) <EOF>)

先键入命令:antlr4-parse Expr.g4 prog -tree

然后键入10+20+3 回车

最后键入^z 退出(注意,windows下键入^z,且还需要一个回车。linux下键入^D 退出)

退出的时候会看到语法分析输出:(prog:1 (expr:2 (expr:2 (expr:3 10) + (expr:3 20)) + (expr:3 3)) <EOF>)

详细语法分析

E:\work\antlr4>antlr4-parse Expr.g4 prog -tokens -trace
10+20*30
^Z
[@0,0:1='10',<INT>,1:0]
[@1,2:2='+',<'+'>,1:2]
[@2,3:4='20',<INT>,1:3]
[@3,5:5='*',<'*'>,1:5]
[@4,6:7='30',<INT>,1:6]
[@5,10:9='<EOF>',<EOF>,2:0]
enter   prog, LT(1)=10
enter   expr, LT(1)=10
consume [@0,0:1='10',<8>,1:0] rule expr
enter   expr, LT(1)=+
consume [@1,2:2='+',<3>,1:2] rule expr
enter   expr, LT(1)=20
consume [@2,3:4='20',<8>,1:3] rule expr
enter   expr, LT(1)=*
consume [@3,5:5='*',<1>,1:5] rule expr
enter   expr, LT(1)=30
consume [@4,6:7='30',<8>,1:6] rule expr
exit    expr, LT(1)=<EOF>
exit    expr, LT(1)=<EOF>
exit    expr, LT(1)=<EOF>
consume [@5,10:9='<EOF>',<-1>,2:0] rule prog
exit    prog, LT(1)=<EOF>

看语法树gui

antlr4-parse Expr.g4 prog -gui
10+20*30
^Z

输入方法为,先输入 antlr4-parse Expr.g4 prog -gui ,然后键入10+20*30 

然后键入Ctrl+z ,回车后,就会看到语法树的gui页面了:

生成解析器代码

执行

antlr4 Expr.g4

这样默认应该是生成java的解析器代码。如果要生成python3代码,执行: 

antlr4 -Dlanguage=Python3 Expr.g4

测试解析器

写测试脚本,将下面代码写入test.py文件

import ExprLexer
import ExprParser
import antlr4

input = "10+20*30"
input_stream = antlr4.InputStream(input)
lexer = ExprLexer.ExprLexer(input_stream)
tokens = antlr4.CommonTokenStream(lexer)
parser = ExprParser.ExprParser(tokens)
tree = parser.prog()
print(tree.toStringTree(recog=parser))

运行测试

python test.py

输出:

(prog (expr (expr 10) + (expr (expr 20) * (expr 30))) )

测试成功。 

换一个例子

先生成Hello.g4文件:

// 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

然后

$ antlr4 Hello.g4
$ javac Hello*.java

 执行测试

grun Hello r -tree
## A First Example

In a temporary directory, put the following grammar inside file Hello.g4:
Hello.g4

```
// 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
```

Then run ANTLR the tool on it:

```
$ cd /tmp
$ antlr4 Hello.g4
$ javac Hello*.java
```

Now test it:

```
$ grun Hello r -tree
(Now enter something like the string below)
hello parrt
(now,do:)
^D
(The output:)
(r hello parrt)
(That ^D means EOF on unix; it's ^Z in Windows.) The -tree option prints the parse tree in LISP notation.
It's nicer to look at parse trees visually.
$ grun Hello r -gui
hello parrt
^D
```

That pops up a dialog box showing that rule `r` matched keyword `hello` followed by identifier `parrt`.


版本3下载安装等(不需要)

官网:ANTLR Software Download

点击下载这个:http://www.antlr3.org/download/antlrworks-1.5.1.jar

这个下载:http://www.antlr3.org/download/antlr-3.5.3-complete-no-st3.jar

使用命令: 

java -jar /path/to/antlr4-4.13.2-complete.jar Expr.g4 -Dlanguage=Python3

总结

ANTLR(ANother Tool for Language Recognition)是一款功能强大且灵活的工具,能够处理复杂的语法规则,支持多种语言特性的定义,ANTLR支持生成多种编程语言的解析器代码,如Java、C#、Python等,这大大方便了不同语言环境下的开发者使用,提高了工具的通用性和可移植性。

个人感觉简单应用的话,Windows下安装不需要像官网讲的那样麻烦。python版本只需要pip安装即可,pip安装的时候会自动安装java,但考虑国内情况,还是建议手工安装java。

调试

报错python test.py  ModuleNotFoundError: No module named 'ExprLexer'

python test.py
Traceback (most recent call last):
  File "E:\work\antlr4\test.py", line 1, in <module>
    import ExprLexer
ModuleNotFoundError: No module named 'ExprLexer'

没有ExprLexer这个库啊,而且库名还有大写? 

先闷头安装:

pip install starlette

这不对劲啊,装错了

原来要这样装:

pip install antlr4-tools

不行,又试

pip install antlr4-python3-runtime

 还是不行。

暂时未解决。

后来才知道是要用这条命令生成

antlr4 -Dlanguage=Python3 Expr.g4

执行antlr4 显示:Downloading antlr4-4.13.2-complete.jar

速度很慢,手工npm install antlr4-tool 也不行。

阿里云maven镜像

  • https://maven.aliyun.com/nexus/content/groups/public/
    

也可以在这里搜索:仓库服务 

搜索文件:antlr4-4.13.2-complete.jar ,但是并没有找到。

好长时间后显示:ANTLR tool needs Java to run; install Java JRE 11 yes/no (default yes)? 

选择yes ,然后继续

碰到报错:jdk.JdkError: [Errno 13] Permission denied: 'C:\\Users\\Admin\\.jre\\jdk-11.0.26+4-jre\\bin\\ucrtbase.dll'

用管理员账户进入cmd,报错:Error: could not open `C:\Users\Admin\.jre\jdk-11.0.26+4-jre\lib\jvm.cfg'

没搞定,先放弃。

后手工安装java11解决。

install Java JRE 11 报错,尝试手工安装

从这里下载:Java Downloads | Oracle

但是官网需要注册才能下载。也可以从这里下载:

项目首页 - Java11下载-版本11.0.17Windows各版本:本仓库提供 Java 11 版本 11.0.17 的下载资源,适用于 Windows 系统的各个版本。该安装包为最新版本,上传时间为 2022 年 11 月 09 日 - GitCode

 下载完毕后安装。安装完毕再来试试命令:

antlr4 -Dlanguage=Python3 Expr.g4

没有报错!解决了前面执行antlr4报错的问题。

执行python test.py 报错:line 1:8 missing NEWLINE at '<EOF>' 

因为是在windows下,需要加回车 

input = "10+20*30\r\n"

后来发现,是自己的Expr.g4文件有问题,应该是:

grammar Expr;		
prog:	expr EOF ;
expr:	expr ('*'|'/') expr
    |	expr ('+'|'-') expr
    |	INT
    |	'(' expr ')'
    ;
NEWLINE : [\r\n]+ -> skip;
INT     : [0-9]+ ;

原来写的是:

grammar Expr;

prog:   (expr NEWLINE)* ;
expr:   expr ('*'|'/') expr
    |   expr ('+'|'-') expr
    |   INT
    |   '(' expr ')'
    ;
NEWLINE : [\r\n]+ ;
INT     : [0-9]+ ;

用新的即可。

报错:HelloParser.java:74: 错误: 方法不会覆盖或实现超类型的方法
        @Override

这行这段代码的时候报错:

$ antlr4 Hello.g4
$ javac Hello*.java

估计可能是因为windows10的原因。 

 学习参考书

https://github.com/Philippe-Laval/tpantlr2