词法分析器和语法分析器的界线 ANTLR教程

词法分析器和语法分析器的界线

因为词法规则可以使用递归,所以词法解析器在技术上和语法解析器一样强大。那意味着我们甚至可以在词法分析器中匹配语法结构。或者,在另一个极端,我们可以把字符当作记号,使用语法分析器去把语法结构应用到字符流(这种被称为无扫描语法分析器)。这导致什么在词法分析器中匹配和什么在语法分析器中匹配的界线在哪里并不是很明显。幸运的是,有几条经验法则可以让我们做出判断: 在词法分析器中匹配和丢弃任何语法分析...
阅读全文
常用词法结构 ANTLR教程

常用词法结构

编程语言在词法上看起来惊人地相似,无论是函数式、过程式、声明式还是面向对象语言,看起来几乎都是一样的。这很棒,因为我们只需要学习一次如何描述标志符和整数,没有太大的变化,就可以把它们应用到大多数编程语言上。正如语法分析器以及词法分析器使用规则去描述各种语言构造体一样,我们要使用基本相同的表示法。唯一的区别是语法分析器识别在记号流中的语法结构,而词法分析器识别在字符流中的语法结构。 因为词法分...
阅读全文
优先级,左递归以及相关性 ANTLR教程

优先级,左递归以及相关性

用自顶向下的语法指定和通过手工的递归下降语法分析器识别表达式一直是个麻烦。首先是因为大部分自然语法是模糊的,其次是因为大部分自然语法规格使用一种被称为左递归的特殊类型递归。所以自顶向下的语法和语法分析器不能处理传统形式上的左递归。 为了阐明这个问题,设想一个算术表达式语言,它只有乘法和加法运算符以及整数。表达式是自相似的。也就是说,一个乘法表达式是由“*”运算符连接的两个子表达式。同样的,一...
阅读全文
常用语言模式 ANTLR教程

常用语言模式

现在,我们已经有了一个自顶向下的草拟出语法的通用策略,下面我们要专注于一些常用的语言模式。尽管在过去几十年里有大量的语言被发明,但仍然只有较少的基本语言模式需要被处理。这是因为人们趋向于设计遵循自然语言约束的语言,语言也会因为设计者遵循数学上的常用表示法而趋向于相似。甚至在词法级别,语言趋向于重用一些相同的结构,例如标志符、整数、字符串等。这些单词顺序和依赖的约束来源于自然语言,并逐渐演化成为四种...
阅读全文
语法设计 ANTLR教程

语法设计

在聚焦到具体的语法规则内部结构之前,我们要先讨论下语法的整体剖析以及如何形成一套初始的语法骨架。 文法文件通常是由一个命名文法的头和一系列可以彼此调用的规则组成。就像下面的那样: grammar MyG; rule1 : «stuff» ; rule2 : «more stuff» ; ... 设计语法就是要搞清楚«stuff»是什么?哪个规则是开始规则。这要求我们需要知道给定...
阅读全文
使用Listener模式计算结果 ANTLR教程

使用Listener模式计算结果

在上一节中的计算器是以解释的方式执行的,现在我们想要把它转换成以编译的方式执行。编译执行和解释执行相比,需要依赖于特定的目标机器。在这里我们假设有一台这样的机器,它用堆栈进行运算,支持如下表所示的几种指令: 指令 说明 运算元数目 用途 LDV Load Variable 1 变量入栈 LDC Load Constant 1 常量入栈 ...
阅读全文
使用Visitor模式计算结果 ANTLR教程

使用Visitor模式计算结果

为了给前面的算术表达式语法分析器计算出结果,我们还需要做些其它的事情。 ANTLR v4鼓励我们保持语法的整洁,使用语法分析树Visitor和其它遍历器来实现语言应用。不过在接触这些之前,我们需要对语法做些修改。 首先,我们需要用标签标明规则的选项,标签可以是和规则名没有冲突的任意标志符。如果选项上没有标签,ANTLR只会为每个规则生成一个visit方法。 在本例中,我们希望为每...
阅读全文
算术表达式语言 ANTLR教程

算术表达式语言

了解ANTLR最好的方法就是实例。构建一个简单的计算器是个不错的主意。为了使它容易理解且保持简单,我们将只允许基本的算术运算符(加、减、乘、除)、括号表达式、整数和变量。 grammar Calc; prog : stat+ ; stat : expr | ID '=' expr ; expr : expr ('*'|...
阅读全文
发送记号到不同的通道 ANTLR教程

发送记号到不同的通道

对于大多数语法,注释和空格都是语法分析器可以忽略的东西。如果我们不想让注释和空格在语法中到处都是,那么就需要让词法分析器把它们扔掉。不幸的是,这意味着任何后续处理步骤都不能再访问注释和空格。安全地忽略掉注释和空格的方法是把这些发送给语法分析器的记号放到一个“隐藏通道”中,语法分析器仅需要调协到单个通道即可。我们可以把任何我们想要的东西传递到其它通道中。这里是如何实现的语法: COMMENT ...
阅读全文
重写输入流 ANTLR教程

重写输入流

现在准备要构建一个工具,用来把前面idata.txt里的数据按group分行显示,就像这样: 2 9 10 3 1 2 3 我们可以借助语法分析树的Listener机制来对词法分析结束后生成的记号流进行改写,我们不需要实现每一个Listener接口方法,只需要在捕获到group的时候把换行符插到它末尾就行。实现改写的代码如下所示: import org.antlr.v4.runtime...
阅读全文
Loading...