1、Antlr 简介06 通讯软件 06382027 郑毅本文主要介绍了什么是 ANTLR,以及 ANTLR 的使用,其中 ANTLR 的使用包括了 ANTLR 的安装及使用,ANTLR 语法文件解析,ANTLR 规则(RULE)解析,ANTLR 语法实例SensorSQL,ANTLR Studio 及其功能介绍等。Antlr(ANother Tool for Language Recognition)是一个工具,前身是 PCCTS,它为我们构造自己的识别器(recognizers) 、编译器(compiler)和转换器(translators)提供了一个基础。通过定义自己的语言规则,Antlr
2、可以为我们生成相应的语言解析器,这样便可以省却了自己全手工打造的劳苦。它是这样的一种工具,它可以接受文法语言描述,并能产生识别这些语言的语句的程序。作为翻译程序的一部分,你可以使用简单的操作符和动作来参数化你的文法,使之告诉 ANTLR 怎样去创建抽象语法树(AST)和怎样产生输出。ANTLR 知道怎样去生成识别程序,语言包括 Java,C+,C#和不久的 Python。 ANTLR 知道怎样构建识别程序,这些程序可以对以下三种不同的输入应用文法结构:(i) 字符流, (ii) 记号流,和(iii)两维的树结构。很自然的它们分别与词法分析程序(lexers,以下简称 lexer),语言解析程序
3、和树遍历程序向匹配。这个用于定义这些语法的元语言,在所有情况下几乎一样的。 一旦你对 ANTLR 和类似工具比较顺手,你会开始以一种新的目光来看编程。许多任务强烈需要语言解决方案,而不是采用传统编程语言的做法。比如,这些过程的注解都是用特伦斯标记语言写的。而 ANTLR则能来将文本(内含一些额外的东西和转换)转化为 HTML,PDF 或者其他那些生成程序的文件格式。 最后,ANTLR 只是一件工具,仅仅这些。 虽然它能通过将容易理解的乏味部分自动化来帮助你创建软件,但却不能企图让你指定整个编译器。例如,在单个的描述里就不行。那些宣称这类事情非常伟大,可以为发布刊物文章编写惊人的“一揽子解决方案
4、” ,却会悲惨失败在实际项目中。词法分析器(Lexer)词法分析器又称为 Scanner,Lexical analyser 和 Tokenizer。程序设计语言通常由关键字和严格定义的语法结构组成。编译的最终目的是将程序设计语言的高层指令翻译成物力机器或虚拟机可以执行的指令。此法分析器的工作是分析量化那些本来毫无意义的字符流,将他们翻译成离散的字符组(也就是一个一个的 Token)括关键字,标识符,符号(symbols)和操作符供语法分析器使用。语法分析器(Parser)编译器又称为 Syntactical analyser。在分析字符流的时候,Lexer 不关心所生成的单个 Token 的语
5、法意义及其与上下文之间的关系,而这就是 Parser 的工作。语法分析器将收到的 Tokens 组织起来,并转换成为目标语言语法定义所允许的序列。无论是 Lexer 还是 Parser 都是一种识别器,Lexer 是字符序列识别器而 Parser 是 Token 序列识别器。他们在本质上是类似的东西,而只是在分工上有所不同而已。ANTLRANTLR 将上述两者结合起来,它允许我们定义识别字符流的词法规则和用于解释 Token 流的词法分析规则。然后,ANTLR 将根据用户提供的语法文件自动生成相应的词法/语法分析器。用户可以利用他们将输入的文本进行编译,并转换成其他形式(如 ASTAbstra
6、ct Syntax Tree,抽象的语法树)。Antlr 使用安装及使用到 http:/www.antlr.org/下载最新版本的 ANTLR 开发包和源码(例如版本 3.01)。将 antlr-3.0.1.jar所在目录配置到你的环境变量中,写好语法文件(例如 SensorSQL.g),运行命令“java antlr.Tool SensorSQL.g”就可以获得自动生成语法/词法分析器。ANTLR 语法文件解析下面我们对图中所描述的 ANTLR 语法文件做一些详细的分析。为了更好的使用 ANTLR,你还可以下载ANTLR 的 Eclipse 插件来帮助你完成工作。1. header 域:所有
7、出现在这里的部分,都会出现在由 ANTLR 编译之后生成的 Java 文件的最顶部。在本例中你可以将包名和其他信息放到这一区域中,生成的结果如由面对应代码部分所示。2. 你在这一部分所提供的内容对于文件中的每个语法都是唯一的。这一区域的内容将出现在实际的类定义之前。也就是说,两个 import 仅属于类 CalcParser,而不属于在同一个文件中定义的其他类(如CalcLexer)3. 这里是语法定义部分,你同样可以将它看成是类定义。4. 在 Option 域中,你可以为你的语法提供可选项。例如是否建立缺省的抽象语法树,指定 LL(K)中的参数 k 的值(缺省为 1)等等,更详细的参数请参阅
8、 ANTLR 自带的手册。5. Token 部分用来声明那些在词法分析器中没有被声明的“想象的”token。这些信息通常用在 TreeParser 中指定“想象” 的节点。6. 这是另一个 Action 区,ANTLR 将会忠实地将这一区域内的信息放置到类的定义当中,相当于类的成员方法,主要为用户提供一种在 Parser 种定制可扩展方法的途径。ANTLR 规则( RULE)解析在 ANTLR 的语法文件中,一个规则的定义是与一个由 ANTLR 生成的 Java 源文件相对应的。1,2,3,4:正如你所看到的那样,我们可以在一个规则定义中作与一个函数等价的所有事情。我们可以为规则指定参数(像上
9、面的 int a),制定返回值(int c),甚至抛出一个异常。从右半面我们可以清楚地看到,所有在规则中定义的内容都被忠实而准确的翻译到 Java 源文件的相应位置。5:这一可选的部分为我们提供了指定某些可选参数的能力。例如图中所示代表告诉 ANTLR 在生成代码的时候不要生成缺省的错误处理部分,这部分将由用户自己负责。7:在异常处理部分,我们可以指定自定义的异常处理方法。像这里就仅仅是打印错误栈信息。ANTLR 语法实例SensorSQLSensorSQL 是一个自定义的简化版 SQL 语言,它所支持的语法定义这里就不详细列出了,我只是给出查询的示例:通常,编译一个查询的目的是要把它转化成某
10、种被查询设备可以理解的形式。通常的做法有两种,一种是像在上一节中提到的那样,写好详细的语法规则,在 ANTLR 生成相应的 Java 文件之后,就可以直接使用其运行结果。这样的例子有很多,其中最典型的就是对于算数表达式的解析了。对于形如 1+2-3*4/56 这样的表达式,只要写好语法规则,就可以在解析过程中直接得到运算结果:首先 ANTLR 将其编译成逆波兰结构- ( - ( + 1 2 ) ( / ( * 3 4 ) ( 5 6 ) ) ) ;在生成语法树的过程中,同步计算表达式的值,即类似于 2.3 节中看到的表达式计算。结果如下:不过这样作有一个缺点,就是在很多情况下,你可能并不知道要
11、用什么样的方法来处理。所以当真正要开始写处理代码的时候,就要受限于已有的 Parser/Lexer 中的代码。一旦要有所修改,就要重新编译语法文件,生成新的 Java 代码,不胜繁琐。而且,一旦处理过程有误,就要反复调试修改 Antlr 生成的代。自动生成的代码嘛,结构着实也不怎么样,调试的时候也麻烦。所以如果效率允许的话,就没有必要让 Antlr 作额外的工作,干脆就专心于做他的语法分析也就是了,其他的工作等到生成语法树之后再怎么遍历或者折腾都可以嘛 J。上图就是刚才演示的 SensorSQL 语法分析之后产生的结果。在产生这个结果之后,我需要将每一个语法元素翻译成字节序列打包发送给传感器网
12、络。这时候,为了保证 Where 语句中的优先级,你就可以按照 ANTLR 文档中关于生成语法树的一章,生成类似于这样的结构,然后只需前序遍历这颗语法树的Where 部分就可以达到目的,至于其他部分,顺序遍历一遍就好了。ANTLR Studio有了前面的基础之后,我们就可以开始真正的工作了。不过用“记事本或 Editplus+命令行”或者干脆写个 ANT 脚本也不是不可以,但是总觉得在集成化 IDE 满天飞的时代用这个方式有点过于原始,幸好Placid System 为我们提供了一个 Eclipse 插件来使我们有机会直接走出原始社会。下载地址为:http:/ 1.1.0。唯一令人遗憾的是这个
13、插件虽然功能很完善,却是要收费的,否则只有 11 天的试用期。ANTLR Studio 插件的安装Eclipse 下插件的安装自不必多说,要注意的是从 Placid System 网站上提供的 license 文件,下载之后它的名字为 license.lic.txt,要把它的后缀名 .txt 去掉,然后放到ECLIPSE_DIRpluginsAntlrStudio_x.x.x 目录(这里 x.x.x 是版本号 , 例如 - 1.1.0)。安装成功之后在Eclipse 的工具栏上会出现一个词法分析器的导航按钮: 当右键单点击你的工程时,你会发现控制是否使用 ANTLR Studio 的开关:当打
14、开一个文法文件之后,可以看到如下界面:在右面的大纲窗口,列有所有 Parser 和 Lexer 的元素,可以看到 Protected Token(例如Number)和其他普通的 Token 是不一样的;在左面,不同的区域是用不同的颜色块加亮来区分的。功能介绍ANTLR Studio 在 Eclipse Help 提供了比较详尽的文档描述,所以这里我只介绍一些 1.1.0 版本的新功能。l 完全支持 ANTLR3.0.1,并支持将之前的工程自动升级到 1.1.0 版本。l Syntax Diagram View,可以方便的查看所输入的语法结构。l 改进了 Debug 功能,可以调试比较大的文法文
15、件。而在这之前,如果一个文法文件很大的话,ANTLR Studio 就会抛出异常。l 支持自动的代码补全功能,提供一个 ANTLR 文档的比较全面的提示信息(如下所示)。语法图表视图(Syntax Diagram View)在 Window-Show View-Other 中选择显示这个视图之后,你就可以使用这个很酷的功能了利用这个视图,你可以很容易的看到你定义语法的语法结构,例如,我的 SELECT 语句定义如下你只需要将光标标放到 selectStatement 规则的任意位置,就可以在 Syntax Diagram View 中看到:于是完整的语法结构清晰的显示在了我们面前。这时你只需要
16、将光标放到脱字符号()上面(注:脱字符号用于指明在生成语法树的时候,脱字符号所在的 SubRule 要作为树或子树的根节点):就会看到:对应的 SubRule 被加亮成粉红色,而如果你的光标放到的位置是一个 Token 的话就会变成淡蓝色,简直太酷了。增强的 Debug 功能想要启动或关闭 ANTLR Studio 的 Debug 功能,需要完成以下步骤:l 在工程中启用/取消 ANTLR Studiol 右键单击工程,打开“属性”中的 ANTLR Studio 选项卡。l 选择/取消Enable debugging in grammar files做完这些后,我们就可以痛快的使用其 Debu
17、g 功能了。与调试其他 Java 文件一样,我们可以在语法文件的任意位置插入断点:当程序运行至断点之后,我们同样可以像调试普通应用程序一样使用诸如“跳过” ,“继续”等 Java 应用程序的 Debug 方式来进行,十分的方便和顺手。注:以上资料均来于网络,鄙人收集整理。ANTLR 中文手册06 通讯软件 06382027 郑毅本文主要概括了一些常用的 ANTLR 的使用方法,其中有 Antlr 的主要类,Antlr文法文件形式,生成 Java 类,如何生成 Java 类,如何执行以及元语言词汇表。一、Antlr 的主要类:Antlr 中有主要类有两种(其实还有一种 TreeLexer)Lex
18、er:文法分析器类。主要用于把读入的字节流根据规则分段。既把长面条根据你要的尺寸切成一段一段:)并不对其作任何修改。Parser:解析器类。主要用于处理经过 Lexer 处理后的各段。一些具体的操作都在这里。二、Antlr 文法文件形式:Antlr 文件是*.g 形式,即以 g 为后缀名。例如:t.gclassPextendsParser;startRule:n:NAMESystem.out.println(“Hithere,“ n.getText() ) ;classLextendsLexer;/one-or-morelettersfollowedbyanewlineNAME:(az|AZ ) NEWLINE;NEWLINE:r n/DOS|n/UNIX;具体成分分析:1、总体结构ClassPextendsParserClassLextendsLexer