Antlr4的使用简介
语法解析器生成工具
有很多生成解析器/编译器的工具,帮你来实现自定义的语言(DSL)。
- yacc Yet Another Compiler Compiler
- jacc just another compiler compiler fro Java,
- ANTLR ANother Tool for Language Recognition
下面主要介绍的是Antlr。
Anltr简介
Antlr的作者是 Terence Parr ,关于他的介绍见Anltr之父 (很励志的成长经历)。他说这个命名是在看了平头哥(蜜獾,话说马云也很赞赏这种勇猛的动物)的视频后想到的,无所畏惧,逮啥吃啥。无论你给啥语法来,都不在话下。
ANTLR v4 is named the “Honey Badger” release after the fearless hero of the YouTube sensation, “The Crazy Nastyass Honey Badger,” It takes whatever grammar you give it; it doesn’t give damn!
参考资料:
- ANTLR 官方网址 http://www.antlr.org/
- ANTLR 官方 Github https://github.com/antlr/antlr4
- 大量语法文件例子 https://github.com/antlr/grammars-v4
Antlr是有很多编辑开发的工具,包括常用的IDE插件都有。
简单介绍下使用,主要有两部分工作,先是用antlr的语法来描述解析规则,用antlr的工具来生成解析器的代码;第二步就看通过扩展生成的解析器代码调用这个解析器了。
解析过程简单来说,就是词法解析Lexer,把输入字符解析成tokens,再通过语法解析Parser得到语法树。如下图:
简单体验一下Antlr的使用
就用最朴素的例子来体验一下
1、下载antlr工具包
目前版本是 antlr-4.7.1-complete.jar,地址如下:
https://www.antlr.org/download/antlr-4.7.1-complete.jar
2、编写语法的描述文件
描述文件一般是以.g4为后缀的。
注意这里例子是一个整数加减法的计算器,Calc.g4
我只做了一些简单注解。
grammar Calc; //名称需要和文件名一致s : expr EOF; //解决问题: no viable alternative at input '<EOF>'expr: expr '+' expr #add //标签会生成对应访问方法方便我们实现调用逻辑编写| expr '-' expr #sub| INT #int;INT : [0-9]+ //定义整数;WS : [ \r\n\t]+ -> skip //跳过空白类字符;
3、用Antlr的工具来生成类
$ java -cp antlr-4.7.1-complete.jar org.antlr.v4.Tool Calc.g4
当然你可以配置别名(unix下)或批处理脚本(win下)来简化执行命令,详见其入门文档
执行完生成,目录下会多出以下文件
Calc.interp
Calc.tokens
CalcBaseListener.java
CalcLexer.interp
CalcLexer.java
CalcLexer.tokens
CalcListener.java
CalcParser.java
运行时只需要java文件,编译成class
$ javac -cp antlr-4.7.1-complete.jar Calc*.java
这时我们可以通过工具看看我们的解析器代码是否能正常工作了。
$ java -cp antlr-4.7.1-complete.jar:. org.antlr.v4.gui.TestRig Calc expr -tree
注意windows下的classpath的分隔符是
;
而unix的是:
-cp antlr-4.7.1-complete.jar;.
接下来输入一个表达式,回车换行,然后输入一个EOF,在win下是^Z
,在unix下是^D
,会输出解析后的表达式。
$ java -cp antlr-4.7.1-complete.jar:. org.antlr.v4.gui.TestRig Calc expr -tree
1+2
(expr (expr 1) + (expr 2))
当然你可以把
-tree
参数换成-gui
,会在你输入EOF后弹出一个GUI的窗口展示解析的树,非常直观。
4、编写访问逻辑
这里需要创建一个java工程或使用IDE工具(如:eclipse)比较方便,当然也可以仍在命令行终端搞定这一切。
要运行执行解析器,只需要antlr4-runtime的jar即可。如果你在IDE工程中,只需要加入POM中这个依赖就行;然后把生成的.java文件拷贝到工程当中即可。
<dependency><groupId>org.antlr</groupId><artifactId>antlr4-runtime</artifactId><version>4.7.1</version>
</dependency>
如果需要生成的代码有包路径,在生成命令中可以通过
-package
来指定。
我这里使用默认包,也就是没有指定包名。
继续回到命令行环境,我们需要编写一个CalcExecuteListener类,继承CalcBaseListener类,通过覆盖(或者说实现)几个访问方法来达到访问我们解析表达式生成的语法树(AST)。
注意,Antlr对语法树访问提供两种模式Visitor和Listener。默认是生成Listener模式代码。这种模式实现了事件访问机制的调用。
其实也可以直接修改生成的CalcBaseListener类,实现其中的需要的方法,但是在修改的表达式定义后,重新生成代码会需要重新修改。所以一般不直接修改生成的代码,而是继承。
CalcExecuteListener.java 如下:
import java.util.Stack;public class CalcExecuteListener extends CalcBaseListener {Stack<Integer> stack = new Stack<>();@Overridepublic void exitInt(CalcParser.IntContext ctx) {stack.add(Integer.parseInt(ctx.INT().getText()));}@Overridepublic void exitAdd(CalcParser.AddContext ctx) {int r = stack.pop();int l = stack.pop();stack.add(l + r);}@Overridepublic void exitSub(CalcParser.SubContext ctx) {int r = stack.pop();int l = stack.pop();stack.add(l - r);}public int result() {return stack.pop();}
}
然后我们写一个测试类,来调用一下
T.java
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CodePointCharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;public class T {public static int exec(String input) {CodePointCharStream cs = CharStreams.fromString(input);CalcLexer lexer = new CalcLexer(cs);CommonTokenStream tokens = new CommonTokenStream(lexer);CalcParser parser = new CalcParser(tokens);ParseTree tree = parser.expr();ParseTreeWalker walker = new ParseTreeWalker();CalcExecuteListener listener = new CalcExecuteListener();walker.walk(listener, tree);return listener.result();}public static void main(String[] args) {String input = "1+2";System.out.println(exec(input));}}
编译一下,然后执行
$ javac -cp antlr-4.7.1-complete.jar:. CalcBaseListener.java T.java
$ java -cp antlr-4.7.1-complete.jar:. T
输出了结果,看起挺顺利。
3
你可以尝试修改input的值,比如: 1+2+3
试试。
至此,一个简单的解释模式表达式解析器就完成了,感觉还不错吧。为了提高执行效率,我们还可以实现访问语法树时,生成一个调用栈,来实现编译模式。
只不过目前的例子里表达式都是常量。如果当一个表达式中包含执行上下文中带来的变量,这个表达式会多次执行的时候,我们就可以用提前编译,在后续执行时省去解析语法树过程,从而加速执行速度。
Antlr4的使用简介相关推荐
- Skywalking-07:OAL原理——解释器实现
OAL 解释器实现 OAL 解释器是基于 Antlr4 实现的,我们先来了解下 Antlr4 Antlr4 基本介绍 Antlr4 使用案例 参考Antlr4的使用简介这篇文章,我们实现了一个简单的案 ...
- Spark-SQL解析
文章目录 Spark-SQL解析 Antlr4 一.简介 1.词法分析阶段 (lexical analysis) 2.解析阶段 二.语法 三.编译 四.遍历模式 1.Listener(观察者模式) 2 ...
- 第一章:antlr4 简介
antlr4 简介 ANTLR(全名:ANother Tool for Language Recognition)是基于LL(*)算法实现的语法解析器生成器(parser generator),用Ja ...
- anltr oracle,Antlr4官方参考手册
[实例简介] Antlr4 文档 参考手册 官方 Early Praise for The Definitive ANTLR 4 Reference Parrs clear writing and l ...
- 使用antlr4及java实现snl语言的解释器
对于antlr4的基础使用,请参考我的前一篇文章<用antlr4来实现<按编译原理的思路设计的一个计算器>中的计算器>. 其实我对于antlr4的理解也仅限于那篇文章的范围,但 ...
- ANTLR4基本语法
原文地址:ANTLR4基本语法 ANTLR4简介 ANTLR4是一个用于构建语法解析器.编译器和其他语言处理工具的强大工具.ANTLR是"Another Tool for Language ...
- Antlr4入门(安装、配置、简单实例)
Antlr4入门(安装.配置.简单实例) 2020.5.28 仅本人初次使用Antlr4的经历分享 目前所知有3种使用Antlr4的方式: 通过命令行使用: 在Eclipse中安装Antlr4插件:( ...
- antlr4 简单实用入门——(一)
Antlr4 简介 简介 Antlr4 是一款强大的语法生成器工具,可用于读取.处理.执行和翻译结构化的文本或二进制文件.基本上是当前 Java 语言中使用最为广泛的语法生成器工具.Twitter搜索 ...
- antlr4 for linux,ANTLR v4 安装以及试用 For Linux
ANTLR 简介 ANTLR-Another Tool for Language Recognition,Antlr 本身是使用 Java 开发的,它为包括Java,Python,C#在内的语言提供了 ...
最新文章
- 2017先知创新大会:有ZHI而来
- 从个人到团队:思维转变是关键
- 按指定格式拼接字符串
- c语言 增删查 案例,C语言实现单链表的增删查改
- Cgroup 好文集合
- Eric6最简单的应用(创建一个项目-窗体-编译-运行)
- qml 信号槽第二次才响应_QML中各种代理的用法
- 牛客网Java刷题知识点之调用线程类的start()方法和run()方法的区别
- 9月TIOBE编程语言排行榜出炉,这个语言或成最大赢家!
- html图表插入ppt
- Java:1加到100的算法
- C++实现简单数独游戏
- C++图书ISBN码校验
- MaratonIME plays Cîrokime
- 第四章(1.2)机器学习——在web攻击检测中的应用实践
- 数字逻辑复习(Wust)
- 怎么录制视频声音,什么录音软件好用
- java时间加30天_java实现,怎么在当前时间往后推三十天
- Nature子刊:AI技术从零开始设计具有生物活性的蛋白质
- 大夏天解渴,喝茶,喝凉白开