《ANTLR 4权威指南》——2.2节实现一个语法分析器

2.2 实现一个语法分析器
ANTLR工具依据类似于我们之前看到的assign的语法规则,产生一个递归下降的语法分析器(recursive-descent parser)。递归下降的语法分析器实际上是若干递归方法的集合,每个方法对应一条规则。下降的过程就是从语法分析树的根节点开始,朝着叶节点(词法符号)进行解析的过程。首先调用的规则,即语义符号的起始点,就会成为语法分析树的根节点。在前一节的例子中,就是调用stat()方法作为起始点的。这种解析过程的更广为人知的名字是“自上而下的解析”,递归下降的语法分析器仅仅是自上而下的语法分析器的一种实现。
下面是一个ANTLR根据assign规则生成的方法(稍微经过格式整理),用于展示递归下降的语法分析器的实现细节:

递归下降的语法分析器最神奇的地方在于,通过方法stat()、assign()和expr()的调用描绘出的调用路线图映射到了语法分析树的节点上(请迅速回顾一下图2-1)。调用match()对应了语法分析树的叶子节点。在手工构造的语法分析器中,我们需要在每条规则对应的方法的开始位置插入“增加一个新的子树根节点”这样的操作,在match()方法中插入“增加一个新的叶子节点”这样的操作。
assign()方法仅仅验证所有的词汇符号都存在且顺序正确。当语法分析器进入assign()方法的内部时,仅有一个备选分支(alternative),无须做出选择。一个备选分支指的是规则的右侧定义的多个方案之一。例如,除了assign之外,下面的stat规则还可能对应其他多种语句。

stat()方法必须通过检查下一个词法符号来做出语法分析决策(parsing decision)或者预测(prediction)。做出决策的过程实际上就是判断哪一个备选分支是正确的。在上面的例子中,一个WHILE关键字意味着它选择stat规则的第三个备选分支。因此,stat()方法将调用whilestat()方法。你可能听说过前瞻词法符号(lookahead token)这个术语,它其实就是下一个输入的词法符号。一个前瞻词法符号是指任何一个在被匹配和消费之前就由语法分析器嗅探出的词法符号。有些时候,语法分析器需要很多个前瞻词法符号来判断语义规则的哪个方案是正确的,甚至可能要从当前的词法符号的位置开始,一直分析到文件末尾才能做出判断!ANTLR默默地帮你完成了所有的这些工作,不过,对其决策过程的基本理解将会有助于调试ANTLR自动生成的语法分析器。
为了让语法分析的决策过程可视化,想象一个迷宫,它只有一个入口和一个出口,迷宫的地板上写着单词。每个从入口到出口的路径上的单词序列代表一个语句。这个迷宫的结构就好比是一种语言所定义的全部语法规则。为了测试一个语句是不是合法,我们将这个语句中的单词和迷宫的地板上的单词比较,然后沿着这个语句的单词所描述的路径在迷宫中前进。如果我们能够通过这个语句中的单词序列指定的路径到达出口,那么这个语句就是合法的。
为了到达迷宫的出口,我们必须在每个分岔路口选择一条正确的路径,就好像一个语法分析器要在多个备选分支中做出选择一样。我们必须将语句中接下来的若干个单词与站在路口所看到的不同岔路地板上的单词相比较,从而决定走哪条岔路。我们站在路口所看到的地板上的单词就好像是前瞻词法符号。显然,若每条岔路都以一个独一无二的单词开始,做出选择就会容易许多。在上例中的stat规则中,每个备选分支都是以一个独一无二的词法符号开始的,因此stat()方法可以通过检查第一个前瞻词法符号来区分不同的备选分支。
当每条岔路的起始单词有重复的时候,语法分析器就需要更多地进行前瞻,即通过扫描更多的单词来区分不同的备选分支。在每次语法分析决策中,ANTLR能够根据情况自动调整前瞻的数量。如果通过前瞻,我们能够经多条路径抵达迷宫出口(文件末尾),那就意味着能够用多种语义去解释当前的输入文本。解决这种歧义是我们下一节的任务,之后,我们将会学习如何使用语法分析树来构建语言类应用程序。

时间: 2024-09-27 21:13:36

《ANTLR 4权威指南》——2.2节实现一个语法分析器的相关文章

《ANTLR 4权威指南》——3.1节ANTLR工具、运行库以及自动生成的代码

3.1 ANTLR工具.运行库以及自动生成的代码 在开始前,我们先浏览一下ANTLR的jar包中的内容.在ANTLR的jar包中存在两个关键部分:ANTLR工具和ANTLR运行库(运行时语法分析)API.通常,当说到"对一个语法运行ANTLR"时,我们指的是运行ANTLR工具,即org.antlr.v4.Tool类来生成一些代码(语法分析器和词法分析器),它们能够识别使用这份语法代表的语言所写成的语句.词法分析器将输入的字符流分解为词法符号序列,然后将它们传递给能够进行语法检查的语法分

《ANTLR 4权威指南》——2.4节使用语法分析树来构建语言类应用程序

2.4 使用语法分析树来构建语言类应用程序 为了编写一个语言类应用程序,我们必须对每个输入的词组或者子词组执行一些适当的操作.进行这项工作最简单的方式是操作语法分析器自动生成的语法分析树.这种方式的优点在于,我们能够重回我们所熟悉的Java领域.这样,在语言类应用程序进一步的构建过程中,我们就不需要再学习复杂的ANTLR语法了. 首先,我们来认识一下ANTLR在识别和建立语法分析树的过程中使用的数据结构和类名.熟悉这些数据结构将为我们未来的讨论奠定基础. 前已述及,词法分析器处理字符序列并将生成

《ANTLR 4权威指南 》一导读

前 言 ANTLR是一款强大的语法分析器生成工具,可用于读取.处理.执行和翻译结构化的文本或二进制文件.它被广泛应用于学术领域和工业生产实践,是众多语言.工具和框架的基石.Twitter搜索使用ANTLR进行语法分析,每天处理超过20亿次查询:Hadoop生态系统中的Hive.Pig.数据仓库和分析系统所使用的语言都用到了ANTLR:Lex Machina将ANTLR用于分析法律文本:Oracle公司在SQL开发者IDE和迁移工具中使用了ANTLR:NetBeans公司的IDE使用ANTLR来解

《ANTLR 4权威指南 》一第3章 入门的ANTLR项目

第3章 入门的ANTLR项目 作为我们的第一个ANTLR项目,我们会构造一个语法,它是C语言或其继承者Java语法的一个很小的子集.具体来说,我们将识别包裹在花括号或者嵌套的花括号中的一些整数,像是{1, 2, 3}和{1, {2, 3}, 4}这样.这样的结构可以作为int数组或者C语言中的结构体的初始化语句.在很多情况下,针对这种语法的语法分析器都非常有用.例如,我们可以用它来构建一个对C语言的源代码进行重构的工具,这个工具能够完成这样的工作:如果初始化语句中所有的整数值都能用一个字节表示,

《ANTLR 4权威指南》——第3章 入门的ANTLR项目 3.1 ANTLR工具、运行库以及自动生成的代码

第3章 入门的ANTLR项目 作为我们的第一个ANTLR项目,我们会构造一个语法,它是C语言或其继承者Java语法的一个很小的子集.具体来说,我们将识别包裹在花括号或者嵌套的花括号中的一些整数,像是{1, 2, 3}和{1, {2, 3}, 4}这样.这样的结构可以作为int数组或者C语言中的结构体的初始化语句.在很多情况下,针对这种语法的语法分析器都非常有用.例如,我们可以用它来构建一个对C语言的源代码进行重构的工具,这个工具能够完成这样的工作:如果初始化语句中所有的整数值都能用一个字节表示,

《ANTLR 4权威指南》——导读

前 言 ANTLR是一款强大的语法分析器生成工具,可用于读取.处理.执行和翻译结构化的文本或二进制文件.它被广泛应用于学术领域和工业生产实践,是众多语言.工具和框架的基石.Twitter搜索使用ANTLR进行语法分析,每天处理超过20亿次查询:Hadoop生态系统中的Hive.Pig.数据仓库和分析系统所使用的语言都用到了ANTLR:Lex Machina将ANTLR用于分析法律文本:Oracle公司在SQL开发者IDE和迁移工具中使用了ANTLR:NetBeans公司的IDE使用ANTLR来解

《ANTLR 4权威指南》——2.2 实现一个语法分析器

2.2 实现一个语法分析器 ANTLR工具依据类似于我们之前看到的assign的语法规则,产生一个递归下降的语法分析器(recursive-descent parser).递归下降的语法分析器实际上是若干递归方法的集合,每个方法对应一条规则.下降的过程就是从语法分析树的根节点开始,朝着叶节点(词法符号)进行解析的过程.首先调用的规则,即语义符号的起始点,就会成为语法分析树的根节点.在前一节的例子中,就是调用stat()方法作为起始点的.这种解析过程的更广为人知的名字是"自上而下的解析"

《ANTLR 4权威指南 》一2.2 实现一个语法分析器

2.2 实现一个语法分析器 ANTLR工具依据类似于我们之前看到的assign的语法规则,产生一个递归下降的语法分析器(recursive-descent parser).递归下降的语法分析器实际上是若干递归方法的集合,每个方法对应一条规则.下降的过程就是从语法分析树的根节点开始,朝着叶节点(词法符号)进行解析的过程.首先调用的规则,即语义符号的起始点,就会成为语法分析树的根节点.在前一节的例子中,就是调用stat()方法作为起始点的.这种解析过程的更广为人知的名字是"自上而下的解析"

《ANTLR 4权威指南 》一3.3 将生成的语法分析器与Java程序集成

3.3 将生成的语法分析器与Java程序集成 在语法准备就绪之后,我们就可以将ANTLR自动生成的代码和一个更大的程序进行集成.在本节中,我们将会使用一个简单的Java示例程序的main()方法调用我们的"初始化语句解析器",并打印出和TestRig的"-tree"选项类似的语法分析树.下面是完整的Test.java程序,它体现出了2.1节中的完整的识别流程. 上面的程序使用了很多ANTLR运行库的类,像是CommonTokenStream和ParseTree,我们