标签:
由于毕设会使用到ANTLR这个工具来实现一个关于出租车领域指标计算的语言,所以就开始学习ANTR这个工具,使用的是ANTLR4,做一些简单的翻译和体会的记录吧。
ANTLR是一个强大的语法生成器,你可以使用它来阅读,处理,执行或者翻译结构化的文本或者二进制文件。它在研究和工程中被广泛使用,来建立各种语言、工具和框架。
ANTLR自动为你所描述的语言创建语法树,用来展示输入的语句如何与语法匹配,并且自动生成语法树的追踪器用来对树的节点执行特定的代码。
为了实现一门语言,我们需要建立一个可以读句子并且对于输入的符号和短语有正确的反应的应用程序。如果应用程序是计算并执行语句,我们称之为解释器,例如计算器,配置文件读取器,Python解释器。如果我们只是将句子从一种语言转换为另一种语言,我们称之为编译器,例如java到C#的转换器和编译器。为了准确的反应,解释器和编译器必须识别某一特定语言所有合法的句子(sentence),词组(phrase),字词组(subphrase)。识别一个词组(phrase)意味着我们可以定义不同的组分并且加以区别。识别之后,应用程序需要进行正确的操作。
识别语言的程序叫做解析器或者语法分析器。语法是指管理语言的成员的规则,我们通过建立ANTLR的语法文件去指定语言的语法。一个语法文件是规则的集合,每一个规则表示一个词组(phrase)的结构。语法文件本身需要遵循一种语言的语法:ANTLR的元语言。
如果我们把解析分成两个相似但是功能不同的阶段,会变得容易许多。这两个分开的阶段反应了我们大脑阅读文本时的情景。首先是将字符流处理成一个个的单词,这被称为词法分析(lexical analysis),我们可以将做词法分析的程序为词法分析器(lexer)。词法分析器可以讲相关的单词组成一个单词类型,例如INT、ID、FLOAT等。词法分析器将单词标以类型后,语法分析器只需关注类型。
其次则是通过一系列单词识别句子的结构,被称为语法分析。ANTLR语法分析器建立了一个数据结构,被称为语法树,来记录语法分析器如何识别一个输入语句的结构以及句子的短语组分,如图 所示。
通过建立语法树,语法分析器通过语法树这样便利的数据结构向程序传递语法分析器是如何将单词组成一个个的词组的信息。需要识别相同语言的不同的应用程序可以复用语法树。语法树对于需要编译多遍的编译器也是十分便利的。
同时,ANTLR通过在语法文件中加入属性(attributes)和动作(actions)来支持将程序代码直接集成在语法文件中,直接在语法分析时完成。
ANTLR工具通过语法规则生成一个递归下降的语法分析器(recursive-descent parsers)。递归下降的语法分析器是一个递归方法的集合,解析过程则是从根开始向叶子递归。在解析时, 当一个规则存在多个选项时,则需要检查接下来输入的一个或者多个单词来做出预测判断,在规则的多个选项中选择一个,这样的工作由ANTLR自动完成。
ANTLR在它的运行库中提供了两种树的遍历机制(tree-walking mechanisms)。默认情况下,ANTLR生成一个语法树的监听器(Listener)来响应遍历语法树触发的事件。监听器是自动按照深度优先完成树的遍历,我们只需完成在每个节点需要触发的各种事件;而访问器(visitor)提供了可控的遍历方式,我们自行控制遍历,决定是否调用子结点的访问方法。由于本课题使用了监听器的方式来实现,所以详细阐述监听器的机制。
语法树监听器(Parse Tree Listener)
为了能够遍历语法树并在监听器中触发事件的调用,ANTLR的运行时提供了一个类ParseTreeWalker。在语言的应用程序中,我们创建ParseTreeListener类的子类来包含应用程序特定的代码。ANTLR为每一个条规则生成一个进入和退出的方法,当遍历进入到这个节点是会触发进入的方法,当遍历完这个节点所有的子节点后,会触发退出的方法。监听器的机制为会自动完成语法树的遍历,无需再写语法树的遍历过程,监听器会提供一个类,包含每个规则的输入输出函数,我们只需继承这个类并复写这些函数即可。
标签:
原文地址:http://blog.csdn.net/lasiali/article/details/51330792