词法分析

  开篇按规矩先说点没用的,词法分析不愧为编译过程的第一步啊。上来就给了一个下马威,上课的时候听得懵懵的,只有课后慢慢消化。不过它有一个我喜欢的特点:特别有条理,从头连到尾。

  我列举下本章的关键词:词法分析器、状态转换图、正规式、正规集、确定有限自动机、非确定有限自动机。

  希望这篇文章能够成功的梳理清楚各部分的关系。希望这篇文章能讲清楚这么几个问题:

   1. 词法分析器的结构

   2. 状态转换图在后面各个阶段的体现

   3. 正规式和有限自动机之间的关系

   4. 确定有限自动机和非确定有限自动机之间的关系

一、 词法分析器的结构

  要想明白词法分析器的结构,需要首先回想下词法分析是干啥的?通过前两章的知识了解到词法分析是一个检测各个字符是否合法,并对字符进行划分的过程。作用之一就是分类,分哪几类呢?就是前面说的:标识符、保留字、算符、界符、常数这五类。为了更好的规范,对词法分析器中词法分析程序的输出做了一点儿规定:输出以二元组的形式描述(单词种类,单词符号的属性值)。单词种类就是根据四类做了划分,具体规则如下:
在这里插入图片描述
  也许文字有点生涩,还是上图一看便知:

在这里插入图片描述
  这里是将所有标识符归为一种,区分通过后面的属性值(即各个变量在符号表中的位置精确确定)

  在前面第一章介绍了一个“遍”的概念。当初说词法分析最好单独成一遍,后面的各个过程可以共同组成一遍。那为啥把词法分析单拿出来呢?这章做了解释:
在这里插入图片描述
  下面介绍下词法分析器中走过的两个过程:

  1. 预处理

  2. 关键字/标识符/算符/常数的识别

   1. 预处理

   预处理作为简化运算的好手段,在词法分析也自然不能落下。那预处理都干些什么呢?

   预处理做了三件事:

   1)去掉空白格,跳格符(Tab符),换行符等编辑性字符
   2) 去除程序中注释范围内的字符

   3)扫描缓冲区

  前两个都很明白了,与主要内容无关的东西是不需要进行编译的。另外词法分析器在预处理过程中不是直接对整个程序进行预处理,而是先拿一部分放入缓冲区中。那设置缓冲区是干什么呢?
  我们知道在词法分析中,是一个字符一个字符读取。如果不设置缓冲区。字符需要从文件中读取,是比较慢的。缓冲区可设置为数组,一次读取整个数组。以后每次从数组读取一个字符,速度是比较快的。

  2. 关键字/标识符/算符/常数的识别

  要想弄清楚这个问题,还是要先明白怎么去区分这几类。都是一个字符一个字符的进来,怎么偏偏到这里停而且还是识别出类型呢。那自然是有方法滴~

  读一个字符,有几种可能?无非四种:字母/数字/算符/界符

  算符像/,*这种就不用说了,只有一种可能:就是算符。但想+这种,不确定是+还是++,就需要继续往下看。

  由于语言的要求,无论是关键字还是标识符开头的都不能是数字。那么当识别到开头是数字的时候就说明,这会是个常数。再往下就一直读字符,直到不是常数了(空格或者算符)就说明该常数到此结束。实际处理时如果读到字母,应该将其作为一个错误输出。比如123name时可以提示其为标识符错误。

  当识别到开头是字母时,那后面选择就比较多了:可以是字符也可以是数字还可以是下划线。按照之前的方法,到空格或算符处阶段,就分离出了字符串。那如何判断是标识符还是关键字呢?这个就要去和关键字的表进行匹配,匹配有效就是关键字,匹配无效就是标识符了,就把标识符放到该放的位置去。

   设想这种情景,在标识符和关键字之间没有空格:
    IFA=1:

  都知道IF是一个关键字,但按照上文的规则阶段点会发生在=处,那就产生了一个矛盾:IFA是一个整体的标识符还是IF和A之间少写了个空格呢?我们往后看可以知道1后面是个冒号而不是分号,说明这是个写的不太友好的if判断。为了精准的确定,计算机也需要一个往后看的方法:超前搜索。超前搜索就是越过那些字母和数字,直接去观察后面的界符,通常情况下,可以通过界符去进行区分。在各种语言进行识别的过程中,超前搜索都是被多次使用的。(虽然有超前搜索,编程时养成良好的习惯:该空格空格总是好的)。

二、状态转换图

  刚才用文字描述词法分析识别各种字符的过程,用了几百字。永远不忘那句:还是图香。用图去表示过程,就是状态转换图。其实这种思想在很多门课上都遇到过了。用圆圈表示状态,满足一定条件就实现状态间的跳变。放张图说明状态转换图的标准概念:
在这里插入图片描述  注意每个箭头上只有一个条件并且初态使用双线箭头表示,终态用双圈表示。一不注意,意思就全变了

  那用状态转换图表示上面各类的识别过程是怎样的呢?
在这里插入图片描述
  这种方法,简单直观,所以后面涉及到变换的都会用这种形式表示。至此,我想你应该能够想象到状态转换图在后面应用的多么普遍了。慢慢体现 慢慢体现~

三、正规式和有限自动机之间的关系

  正规式,正规集

在这里插入图片描述  我理解的正规式就是一个字符串,字符串的组成来自字母表的元素及正规式的算符。这个字符串特殊情况有两种:包含空字和为空集。正规集就是正规式表示的符号串的集合。(下面会举个例子说明)。

  正规式有几个运算符号,常用的有三个:或(I),并,闭包(*),三者的优先级依次升高。

  还有几个扩展

  1) r+(代表右上角,以下都表示该含义):不包含空字的闭包

  2) · :表示任意字符

  3) [a-z]:表示a-z范围内的所有字符

  4) /[^a]:不存在给定集合。例如a不存在a的集合

  5) ?:可选符号,可有可无。例如r?

  正规式存在以下几个数学运算:
在这里插入图片描述
  现在举个例题来解释下为啥说正规集是正规式表示字符串的集合:
在这里插入图片描述
  还有另外一种方式定义正规式,但我觉得没有第一种直观。是从操作符的数量角度,贴一张图以供了解:
在这里插入图片描述

  有限自动机(FA M)

  有限自动机是表示词法分析的工具。有限自动机有三种表示方法:公式表示法、转换矩阵表示、状态转换图表示。因为状态转换图表示最为常用,下面的表示都将使用状态转换图来实现。

  分为两类:确定性有限自动机和非确定有限自动机。下面来分别介绍一下。

  1)确定性有限自动机(DFA M)

在这里插入图片描述
  需要注意的是第三个代表自动机的转换状态(转换规则)。对于确定性有限自动机来说初态唯一

  2)非确定有限自动机(NFA M)

在这里插入图片描述
  需要特别注意的是对于非确定性有限自动机。初态可以不单单是一个了。还有第三条映射关系从单值映射变为了对应子集。其余各种与确定性有限自动机相同。

  确定性有限自动机和非确定性有限自动机的区别:

   1. 确定性初态唯一,非确定性初态可以不唯一

   2. 确定性是单值映射,非确定性不是单值映射

  第二条具体啥意思呢?很简单就是对于确定性状态A来说,通过x只能变成状态B。但是对于非确定性状态a来说,通过x可以变成b,也可以变成c。用状态转换图来说就是确定性箭头上相同标识的只能有1个,但是非确定性可以有n个。

  其实在确定性和非确定性之间是可以相互转化的,转化的方法在下文详细介绍。

  说到这里,应该明白了什么是正规式,什么是有限自动机。那么二者的关系是否清楚了呢?

  正规式表示字符串,有限状态机表示一个又一个状态的变换。如果把每一个字符看作一个状态,字符串中的顺序看作状态变换的条件。那么就可以使用有限自动机来描述正规式

  通常情况下,正规式直接转换的非确定有限自动机。下面介绍下正规式如何转换成非确定性有限自动机吧

  正规式转换成非确定有限自动机

  本质上就是如何用状态转换图把正规式表示出来。没有确定的规则步骤,做题多了,自然会有一些经验。

  从正规式的三个运算符出发

  并:

  正规式:AB

  有限机状态转换图:

在这里插入图片描述
  或(|):

  正规式:A|B

  有限机状态转换图:
在这里插入图片描述
  闭包(*):

  正规式:A*

  有限机状态转换图:
在这里插入图片描述
  以上介绍了三个基本单元,复杂的正规式都是由着三个基本单元组成的,这就需要具体情况具体分析啦!

  正规式和有限自动机的等价性

  正规式和有限自动机的等价分为两部分:正规式->有限自动机和有限自动机->正规式

  1)有限自动机转正规式

  其实从上面三个运算符中就可以看出其等价性,不过为了突出其过程中的等价性(初态和终态不是我们主要研究的对象)。假定正规式也有初态和终态,但只有这两种状态。两种转换的条件就是正规式。如图所示(需要符合状态转换图一个箭头一个条件的要求):

在这里插入图片描述
  2)正规式转有限自动机

  正规式转有限自动机的方法叫Thopmson方法,采用的思想是运算符的累加。当0个运算符时以及当k个运算符时(又包括并、闭包、或三种)。因篇幅过长,不在此说明。需要可差相关资料(P54)。

  非确定性有限自动机和确定性有限自动机的转化

  两种自动机之间的转化可以理解为状态图的转化,转化过后状态图不再存在一个状态同一条件多个结果。这种方法叫做子集法。

  放几张图,步骤性的描述一下:
在这里插入图片描述

在这里插入图片描述
  简单的说就是先完成一个表格,再根据表格画图。

  表格的构造方法是选取一个初态集合(初态的选择是起始状态以及通过起始点加空字ε可到达的状态),有几种条件就几列。集合中所有的状态依次经过每个条件后会形成一个状态集合作为结果集合的第一部分呢,下面对第一部分的结果(注意是每一个状态)以空字ε为条件能够到达的状态加入结果。最后形成的结果作为该初态经过该条件的结果。并将该结果作为表格的下一项。直到不再有新的状态出现就大功告成啦。

  下面举一个例题吧,说明上面的整个流程:

在这里插入图片描述
在这里插入图片描述
  构造状态转换矩阵的时候有一种特殊情况:经过某一条件后集合为空集。解决办法是将空集也作为一种状态加入状态转换矩阵中并且空集经过任意条件后均为空集

  空字的情况说明

  对于有限自动机识别空字ε有两种情况,直接使用图表示了:
在这里插入图片描述

  第一种情况通过空字可从初态到达终态,第二种情况初态即终态。

  对于确定及非确定的选择有件事情必须要清楚,同样也可以解释为什么需要进行向确定型的转化。

  其实从状态数目来看,非确定是小于确定的。因为在非确定中多个后继情况下只需两个状态就可以表示,但在确定性中需要n个状态表示(n代表后继个数)。但这也恰恰解释了非确定的弊端:在程序中,程序无法确定哪一个是正确的后继,只有后继唯一程序才能正常运行。

  确定性有限自动机的化简

  首先文字性的叙述下化简得步骤:

在这里插入图片描述
  举个例子,说明确定性有限自动机的化简:
在这里插入图片描述

  步骤1:区分初态集和终态集
   结果为{0,1,2},{3,4,5,6};

  步骤2:对整个集合的经过同一条件看结果是否落在相同集合
   {0,1,2}a = {1,3,1} 由于1,3位于不同集合可拆分其为{0,2},{1}(注意:集合中只存在一个即为最小单元,不可再分

  步骤3:换用另一条件测试

   {0,2}b = {2,5}。由于2,5位于不同集合可拆分其为{2},{5}。

  步骤4:对所有集合重复上述步骤直至不可再分

  注意:如果集合A经过某一条件后得到结果同时位于集合B,不可以直接说集合A等价。应当先确认集合B中的结果是否等价。

  到此为止,各个关系已经讲述完毕。下面小结一下,把整条线穿起来。

  有三个顺次的等价性:正规式和非确定有限自动机的等价性,非确定有限自动机和确定有限自动机的等价性,确定自动机化简前后的等价性。基于三种等价性,会出现给定一个正规式的求解最小确定有限自动机。

  判断两个正规式之间是否等价可构造最小化确定有限自动机看是否等价。

  词法分析的理论部分学习到此结束,下面还会有实践的上机。如果上机后有新的感悟,还会来继续补充的。继续加油~

  感谢编译原理课程谢老师对本文章的耐心修改,同样感谢各位博主的优秀文章作为参考!

  因为作者水平有限,如有错误之处,请在下方评论区指正,谢谢!

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值