入门使用ANTLR词法语法分析工具
背景
看到B站开源了golang版的规则引擎, 可以动态加载DSL程序代码, 非常酷。
之前一直感兴趣“代码生成代码”,但不得入门, 基于此项目比较简单, 重点研究下此项目的底层实现ANTLR的逻辑
ANTLR:
能够根据【用户定义的语法文件】自动生成词法分析器和语法分析器, 并将输入文本处理为(可视化)语法分析树。 用户进而可以对此语法分析树做响应的逻辑操作。
ANTLR自动生成的编译器前端搞笑,准确,能够将开发者从繁杂的编译理论中解放出来,集中精力处理自己的业务逻辑, ANTLR 4引入的自动语法分析树创建与遍历机制, 极大的提高了语法识别程序的开发效率。
ANTLR的作者寄语:
为什么不花5天时间编程, 来使你25年的生活自动化呢?
安装
ANTLR是基于java编写, 只要有java环境, 直接下载就能运行
1 |
|
使用流程
- 自定义语法文件
- 通过ANTLR通过语法文件生成对应语言的词法分析器和语法分析器
- 步骤2生成遍历语法树的visitor和listener接口, 自定义自己的业务逻辑
- 根据自定义语法,生成自己的规则内容
- 通过语法分析器和词法分析器 处理 步骤4生成的规则内容, 然后调用自己步骤3定义的业务逻辑, 完成处理
下面我们 定义一个加减乘除法来,帮我们理解此过程
定义语法规则
calc.g4文件
1 |
|
生成对应golang客户端调用语法
这里可以指定对应的语言, 我这里选择golang
1 |
|
生成代码目录如下:
1 |
|
生成自己的listener模式和visitor模式业务逻辑处理代码
为了将文法与分析程序分离,关键是通过分析器创建一颗分析树,随后遍历这颗树,并在遍历时触发相关的处理代码。这可以通过Antlr提供的树遍历机制来实现
listener(观察者模式,通过结点监听,触发处理方法), 这里即编译器方法会自动回调我这里的方法, 不需要用户定义需要
- 程序员不需要显示定义遍历语法树的顺序,实现简单
- 缺点,不能显示控制遍历语法树的顺序
- 动作代码与文法产生式解耦,利于文法产生式的重用
- 没有返回值,需要使用map、栈等结构在节点间传值
1 |
|
visitor模式(访问者模式,主动遍历)
- 程序员可以显示定义遍历语法树的顺序
- 不需要与antlr遍历类ParseTreeWalker一起使用,直接对tree操作
- 动作代码与文法产生式解耦,利于文法产生式的重用
1 |
|
做测试
测试支持解析 1 + 2 * 3+1+2344
1 |
|
增加括号
这里我们完善规则,增加括号, 比如这里即会支持 2*(1+2+3)
表达式。
具体代码地址: https://github.com/l1905/antlr-demo
后续
这里只是入门相关知识,后续需要完善使用, 构造复杂的语法规则, 应用到具体业务中. 具体需要。
- 强化使用
- gui展示表达式
参考资料
- https://github.com/dohkoos/antlr4-short-course
- antlr权威指南(中文翻译)
- ANTLR4笔记-01 ANTLR4笔记-02
- 计算机源码golang例子 比较详细使用
- ANTLR电子书
- https://www.cnblogs.com/clonen/p/9083359.html