最浅俗易懂的入门实例
因为工作原因,本人正在使用antlr解析一种语言,所以本文算是本人的一点学习心得,这里是一个简单的入门案例,对一个只包含数字和字母的字符串的解析规则;由于入门时记录,所以有错还望各位包含纠正,谢谢。
一、新建一个简单地java工程(其他工程也可以)
1、导入antlr的jar包
这里我导入的是antlr-4.4-complete.jar,当然可以去下载最新版:
- 官网下载地址:https://www.antlr.org/download.html
- ANTLR 官方 Github https://github.com/antlr/antlr4
- 大量语法文件例子 https://github.com/antlr/grammars-v4 进去官网后,下拉到此页面ANTLR tool and Java Target,点击下载此jar包即可,目前最新版为ANTLR4.8。
- 工程jar包位置
在新建的工程下创建一个lib文件夹,放进去然后build path即可。
(这是我做案例测试时,创建的java工程)
2、书写规则文件
上一篇(插件开发:ANTRL 语法学习)说了,antlr的精髓就是这个名为xx.g4的文件,所有的语法、此法都是在这里边配置的。所以这里就简单说一下此文件的内容:下面是我做的小案例:
对一个只包含数字和字母的字符串的解析规则:
标注说明:
这里只说后边的内容含义,前面的请看上一篇:g4文件结构讲解①、grammar后面的是此次定义的规则名,此规则名必须与此g4文件同名。
②、options内部的是告诉antlr,我们解析文本的语言是java。
③、@header里边的内容是告诉antlr自动生成解析类的位置。因为如果不设置,默认会在当前工程下的target-generated-sources-antlr4目录下生成,但是此处我们设置了位置,所以会在target-generated-sources-antlr4-com-cn-antlr-test01下生成。
目前发现那俩个文件夹(StringDemo.tokens、StringDemoLexer.tokens)可以暂且不用去管,因为那只是我们写的规则生成的一些token。
StringDemoListener:此类是一个监听器,我们可以在这个监听器内写我们的逻辑,去操作这个解析树。
StringDemoBaseListener:此类是上述StringDemoListener类的实现类。
StringDemoParser:此类是通过g4文件自动生成的语法解析类。
StringDemoLexer:此类是通过g4文件自动生成的词法解析类。
④、stat是我自定义的一个命名,也是代表着这个语法解析的开始,大家可以通过上述的g4文件和下面的语法树结构图对比理解:
因为本人用的是eclipse,所以得把箭头所指的视图显示出来,就可以看到由g4文件生成的语法树结构。
- stat是语法解析的入口,可以看出来它是由一对“{}”构成的;
- value (’,’ value)表示以“,”号隔开的,0个或者多个value。“”表示0个或者多个。
- value表示可以是stat,INT,WORD;
- INT表示从0到9,后边的“+”表示1个或者多个。
- WORD表示从a到z或者A到Z。
从上边的解释可以看出,其实就是一个树结构,比较好理解。
⑤、WS表示一个空格占位符,后边的skip,意思是解析时要跳过“\t\n\r和空格”。
3、下面是测试类
package com.cn.antlr.test01;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
public class Test01 {
public static void main(String[] args) {
String str = "{99, 3, a, 451, A}";
ANTLRInputStream in = new ANTLRInputStream(str);
// 用 in 构造词法分析器 lexer,词法分析的作用是产生记号
StringDemoLexer lexer = new StringDemoLexer(in);
// 用词法分析器 lexer 构造一个记号流 tokens
CommonTokenStream tokens = new CommonTokenStream(lexer);
// 再使用 tokens 构造语法分析器 parser,至此已经完成词法分析和语法分析的准备工作
StringDemoParser parser = new StringDemoParser(tokens);
ParseTree init = parser.stat();
System.out.println(init.toStringTree());
}
}
下面是控制台输出:
4、语法树测试
在上述的测试类中,可能有人觉得这样的输出看的不是很明白,那么,下面的语法树就可以很直接的看到我们的测试案例是否合法。
在eclipse中调出Parse Tree视图,视图分为俩块,左侧这块是用来写我们的测试案例的,右侧这块是由测试案例生成的语法树,语法树有如下特点:
1、可以将鼠标放在不同的语法规则上,不同的规则有不同的语法树(即,语法树不仅可以整树调试,还可以部分调试)。
2、如果语法树,显示红色,且控制台有红色错误说明,则证明此案例不符合语法规则。
使用上述案例测试:String str = “{99, 3, a, 451, A}”;
如下图是一颗完整的语法树:
下面是错误:
备注:
大家可以看一下那个parser类,里边的代码可以充分的看出来,也是基本都是根据树结构生成的类似java的继承结构一样的类。