【编译原理】词法分析(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jzyhywxz/article/details/78285722

本文是词法分析的第一篇文章,主要介绍在词法分析过程中需要用到的一些基本概念,包括词法单元、模式和词素以及三者之间的关系,理解这些内容对学习词法分析过程十分重要。

词法分析器的作用

词法分析是编译的第一阶段。词法分析器的主要任务是读入源程序的输入字符,将它们组成词素,生成并输出一个词法单元序列,这个词法单元序列被输出到语法分析器进行语法分析。另外,由于词法分析器在编译器中负责读取源程序,因此除了识别词素之外,它还会完成一些其他任务,比如过滤掉源程序中的注释和空白,将编译器生成的错误消息与源程序的位置关联起来等。总而言之,词法分析器的作用如下:
1. 读入源程序的输入字符,将它们组成词素,生成并输出一个词法单元序列;
2. 过滤掉源程序中的注释和空白;
3. 将编译器生成的错误消息与源程序的位置关联起来;
4. 其它。

词法单元、模式和词素

词法分析涉及到三个重要的相关术语——词法单元、模式和词素:
- 词法单元由词法单元名和可选的属性值组成。词法单元名是一个词法单元的引用(别名),它将作为语法分析器处理的输入符号。当有多个词素的词法单元名相同时,可以附加属性值信息来区别这些词素。词法单元名将影响语法分析过程中的决定,而属性值将影响语法分析之后对这个词法单元的翻译(具体翻译成哪一个词素);
- 模式描述一个词法单元的词素可能具有的形式;
- 词素是一个字符序列(串),它和某个词法单元的模式匹配,并被词法分析器识别为该词法单元的一个实例。

为了进一步说明词法单元、模式和词素之间的关系,我们举一个例子:

20171018_img1

PS:由于词法分析器通常还要和符号表进行交互,因此属性值常常作为一个指针指向符号表中的某个条目。

词法单元的规约

我们知道,每个词法单元都有一个模式来描述它的所有词素,正则表达式正是这样一种用来描述词素模式的重要方法。在真正介绍正则表达式之前,我们还需要了解串和语言以及一些相关的术语和运算,这些内容能帮助我们十分容易地理解正则表达式。

某个符号集合上的一个串是该集合中符号的一个有穷序列。这句话说明了串的两个特点:第一是组成串的符号都来自某个符号集合,第二是串的长度是可数的。举个例子:对集合A={a,b,…,z,A,B,…,Z}来说,它的一个串只能包括大小写字母,并且长度是可数的。

下面定义了一些串相关的术语:

20171018_img2

下面定义了串上的运算:

扫描二维码关注公众号,回复: 3331767 查看本文章

20171018_img3

语言

语言是某个给定的符号集合上一个任意的可数的串集合。这句话稍微有点抽象,我们把这句话拆分开来解释:首先,语言是一个集合;其次,这个集合中的元素是串,并且集合的大小是任意的;最后,这些串是依据某个符号集合生成的。

下面定义了语言上的运算:

20171018_img4

正则表达式

正则表达式可以用来描述词素的模式,一个正则表达式可以由较小的正则表达式递归的构建:

20171018_img5

下面我们举例说明。对于符号集合∑={a,b},有:
- 正则表达式a表示语言{a};
- 正则表达式a|b表示语言{a,b};
- 正则表达式(a|b)(a|b)表示语言{aa,ab,ba,bb};
- 正则表达式a*表示语言{ε,a,aa,aaa,…};
- 正则表达式(a|b)*表示语言{ε,a,b,aa,ab,ba,bb,aaa,…};
- 正则表达式a|a*b表示语言{a,b,ab,aab,aaab,…}。

上面通过基本的并、连接和闭包运算递归定义了正则表达式,为了增强正则表达式描述串模式的能力,也出现了许多针对正则表达式的扩展,下面是一些比较典型的扩展:

20171018_img6

词法单元的识别

上面介绍了如何用正则表达式来表示一个模式,下面我们将介绍如何根据词法单元的模式来识别一个与该模式匹配的词素,为此,我们首先将模式转换成状态转换图。

一个状态转换图由一组表示状态的结点和表示输入字符的边构成,词法分析器在扫描输入字符串的过程中寻找和某个模式匹配的词素,状态转换图中的每个状态代表一个可能在这个过程中出现的情况。一个状态转换图有如下特点:
- 有一个初始状态,该状态由一条无出发结点的、标号为“start”的边指明。在读入任何输入符号之前,状态转换图总位于它的初始状态;
- 有某些最终状态,该状态用双层的圈表示。这些状态表明已经找到一个词素;
- 有某些回退状态,该状态附近有一个“*”标明。在识别“3+4”这个串时,只有当扫描到“+”符号时,才能确定前面的数字符号“3”,此时识别出了词素“3”,并且需要回退一个字符。

下面是词法单元relop的状态转换图,它表示比较运算符<、>、<=、>=、<>和=:

20171018_img7

根据这个状态转换图,我们可以十分容易的编写出一段代码来识别这些比较运算符,这里就不再赘述了。

qrcode

欢迎关注微信公众号fightingZhヾ(๑╹◡╹)ノ”

猜你喜欢

转载自blog.csdn.net/jzyhywxz/article/details/78285722