目录
第一章编译概述
1.1翻译程序的三种方式
1编译 将高级语言编写的源程序翻译成等价的机器语言或汇编语言。
2.解释:将高级语言编写的源程序翻译一句执行一句,不生成目标文件,直接执行源代文件
3汇编:用汇编语言编写的源程序翻译成与之等价的机器语言。
1.2计算机思维---在编译原理中使用了
1抽象 抽象就是将具体事务的特点和本质抽取出来,是从具体到一般
在计算机中抽象有图零机这个概念
在编译原理中使用到抽象概念的有有限自动机和形式文法等
2自动化
在编译原理中使用自动化的有有限自动机,预测分析程序,算符优先分析,LR分析等
3分解
在算法中这是一种非常重要解决问题的方法
在编译原理中,层次化管理中体现了分解
4 递归
编译原理中递归思想
5权衡
编译原理中的权衡思想
1.3编译程序的五个阶段
编译程序就是能将将源语言程序翻译成目标语言
拿一个英语翻译成汉语的过程举例子
1.词法分析:对源程序的字符串进行扫描和分解,识别出每个单词符号。遵循构词规则
在高级语言中有关键字,标识符,常量,运算符,界限符这些词,首先就要要知道程序的每个单词的含义,就像翻译英文时,知道每个单词的中文意思和他是动词还是形容词。
2.语法分析:根据语言的语法规则,把单词符号分解成各类语法单位。经过分析1 0.618*y是一个算数表达式 2 x+(0.618*y)是一个算数表达式 3 z=(x+(0.618*y))是一个赋值语句
3.语义分析与中间代码生成:对各种语法范畴进行静态语义检查如变量是否定义,类型是否正确等,若正确则进行中间代码翻译。遵循语义规则T1 T2是编译期间引进的临时工作变量
4.代码优化:遵循程序的等价变换规则。有机器无关优化和机器有关优化一样的效果,前一段代码需要300次加法和200次乘法,而后者只需要做300次加法
5.目标代码生成:将中间代码变换成特定机器上的低级语言代码。
1.4编译程序的逻辑结构
总框架
出错处理
一个编译程序不仅只是去翻译正确的源程序,也要能去对出现在源程序的错误进行处理
分遍处理
前面的的五个工作阶段只是逻辑功能的一种划分,通常每一遍的工作就是从外存上获得前一遍的中间结果开始(对于第一遍而言),是从外存获得源程序,完成所含的有关工作,再把结果记录于外存中
前端与后端
表格管理
编译程序再工作时需要保持一系列的表格,以登记源程序的各类信息和编译各阶段的进展状况,其中最重要的是符号表,它是用来登记源程序出现的每个标识符以及名字的各种属性,例如一个名字是常量名,还是变量名,如果是变量名,它的类型是什么,所占内存多大,地址是多少
第二章文法
2.1符号和符号串
2.1.1字母表
1.定义:字母表是有穷非空的符号集合。
2.表示:通常用字母表大写字母A,B,…Z和希腊字母Σ表示。
eg:A={0,1},Σ={a,b,c,d}
3.说明
1)字母表包含了语言中所允许出现的一切符号。
2)字母表中的符号也称字符。
2.1.2符号串
1定义:是由任何符号组成的有限序列
2表示:通常由t,u,v,w,x,y,z等小写英文字母来表示。
3.说明1)符号串由构成的符号的种类、数量、顺序共同决定。
2)不包含任何符号的符号串称为空符号串,简称空串,用ε表示。
4.子符号串:一个非空符号串中若干连续符号组成的部分。
5符号串的运算
1)连接:符号串x,y的连接xy就是把符号串y写在x后面得到的字符串。规定εa=a=aε
eg:若x=ab,y=cd,则xy=abcd,yx=cdab
2)方幂:若x是符号串,xn表示n个按顺序连接。当n=0时,x0是空符号串ε。a3) 长度 :符号串的长度指符号串所含的符号个数,符号串S的长度记为|S|
6.对于给定的字母表Σ,符号串的递归定义如下:
1)ε是Σ上的一个符号串。
2)若x是Σ上的符号串,a是Σ的符号,则xa是Σ上的符号串。并规定εa=a,aε=a。
3)y是Σ上的符号串,当且仅当y由1)和2)导出7.字符串的前缀和后缀
z=abd是字母表Σ={a,b,c,d}上的符号串,则ε,a,ab,abd都是z的前缀;ε,d,bd,abd都是z的后缀。
2.1.3符号串集合
1.定义:由字母表上的一些符号串组成的集合。
2.说明
空集Ø是一个字符串集合,仅含一个空符号串的集合{ε}也是一个语言。Ø和{ε}是不同的语言3符号串集合的运算
1)并集
设A和B是符号串的集合,则A和B的并集定义为
A∪B = {x | x∈A or x∈B}。
2)乘积
设A和B是符号串的集合,则A和B的乘积定义为
AB = {xy | x∈A and y∈B}。
eg:若A={a,b},B={b,c},则AB = {ab,ac,bb,bc}。
对任意符号串集合A,有{ε}A = A{ε} = A。
3)幂运算
设A是符号串的集合,则A的幂运算定义为
A0 = {ε}
A1 = A
An = AAn-1(n>0)
eg:若A={0,1},则A0={ε},A1={0,1},A2={00,01,10,11}。
4)正闭包与闭包
设A是符号串的集合,则集合A的正闭包A+和闭包A*定义为
A+ = A1∪A2∪…∪An∪…
A* = A0∪A1∪…∪An∪…
eg:若A={0,1},则A+={0,1,00,01,10,11,000,001,…}, A*= {ε,0,1,00,01,10,11,000,001,…}。
2.2文法和语言的形式定义
2.2.1 文法的形式化定义
1产生式规则
1)定义:一个产生式规则是一个有序对(A,α)。通常写作A→α或A::=α。
”→"或”::=”表示“定义为”、“由…组成”、“生成”。
2)含义: A→α表示左部符号A生成右部符号串α。
3)若A→α;A→β,则可以写成A→α|β。”|”表示“或”。
4)非终结符号:产生式规则左部出现的符号。
5)终结符号:不是非终结符号的符号。
6)非终结符号既可以出现在产生式规则的左部,也可以出现在产生式规则的右部。终结符号不能出现在产生式规则的左部。
7)非终结符号通常用大写字母或尖括号括起来的部分表
2文法
1)定义:产生式规则的非空有穷集合。由四元组G=(VN,VT,P,S)组成。
2)VN:是一个非空有穷集合。它的每个元素称为非终结符号。且VN∩VT=Ø。
3)VT:是一个非空有穷集合。它的每个元素称为终结符号。
4)P:是文法规则(产生式规则)的非空有穷集合,每个产生式规则的形式是A→α或A::=α,其中A∈VN,α∈(VN∪VT)*。
5)S:是一个非终结符号。称为开始符号或识别符号。它至少要在一条产生式规则的左部出现。有它开始识别定义的语言。
6)通常不必将文法的四元组显式地表示出来,而仅需给出文法的产生式规则集。
7)对于两个不同的文法G[S]和G’[E],若这两个文法生成的语言相同,则称这两个文法是等价的。句子这个就是个非终结符,上面每个转换就是一个产生式,a book gave这种就是终结符,不能转换成其他东西了
2.2.2推导和语法分析树
1.直接推导与推导
1)直接推导:令G=(VN,VT,P,S),若A→γ∈P,且α,β∈(VN∪VT)*,则称αAβ直接推导出αγβ,表示成αAβ ⇒ αγβ。
2)推导:若存在一个直接推导序列:α0⇒α1⇒α2⇒…⇒αn,则称这个序列是一个从α0至αn的长度为n的推导。
当n>0时,α0至αn的推导记为α0 ⇒+ αn,表示从α0出发,经过1步或者若干步可推导出αn。
当n≥0时,α0至αn的推导记为α0 ⇒* αn,表示从α0出发,经过0步或者若干步可推导出αn。3)最左推导和最右推导((规范推导))
例子
推导的过程就是从文法的开始符号到句子的变换过程
规范句型:由规范推导得到的句型。
最左归约(规范归约):规范推导的逆过程。
2 语法分析树
1.语法分析树:一个句型推导过程的树形表示称为语法分析树,简称语法树。
2.满足条件:设G=(VN,VT,P,S)。
1)根节点的标记为S。
2)每个结点有一处标记X,并且X∈(VN∪VT)*
3)若结点X有后续,则X∈VN
4)若某个节点标记为X,其孩子节点的标记从左到右分别为X1,X2,…,Xn,则A→X1X2…Xn必为P中的一条产生式规则。
例子
2.2.3 句子,句型,语言
1.句型和句子
设有文法G[S],S是文法G的开始符号。
1)句型:若S ⇒* x,x∈(VN∪VT)*,则称符号串x为文法G[Z]的句型。
2)句子:若S ⇒* x,x∈VT*,则称符号串x为文法G[Z]的句子。句子就是不含有有非终结符
3)句子一定是句型,句型不一定是句子。He gave me a book就是一个句子
He gave me a <名词>j就是一个句型,因为存在名词这个非终结符
2.语言
1)定义:文法G[Z]产生的所有句子的集合称为文法G所定义的语言,记为L(G[S]),简写为L(G)。L(G)={x| S ⇒+ x且x∈VT*}。
2)语言L(G)是VT*的子集。
3)L(G)中的每一个符号串均由终结符号组成,且该符号串能由开始符号Z推导出来。
3递归规则(直接递归)
1)定义:一个产生式规则中,出现在左部的非终结符也出现在其右部。
2)种类:左递归、右递归、递归。
3)左递归:A→A…
4)右递归:A→…A
5)递归:A→…A…如果存在αAβ ⇒ αAβ1的推导,就称为间接递推文法
4文法递归
1)定义:对于文法中的任一非终结符,若能建立一个推导过程,在推导所得的符号串中又出现该终结符本身,则称文法是递归的。
2)种类:左递归、右递归、递归。
3)左递归:A ⇒+ A…
4)右递归:A ⇒+ …A
5)递归:A ⇒+ …A…
2.3Chomsky 文法分析
2.3.1 0型文法(短语文法)
1)定义:若文法G[S]=(VN,VT,P,Z)中的每个产生式规则的形式为:α→β,其中α∈(VN∪VT)*且至少含有一个非终结符号,而β∈(VN∪VT)*,则G[S]为0型文法。
2)特点:0型文法的能力相当于图灵机,识别能力最强。L(G)={a的i次方|i为2的正整次方}
2.3.2 1型文法(上下文有关文法)
1)定义:若文法G[S]=(VN,VT,P,Z)中的每个产生式规则的形式为:αAβ→αvβ,其中α,β∈(VN∪VT)*,A∈VN,v∈(VN∪VT)+,则G[S]为1型文法。L(G)={a的i次方b的i次方c的i次方| i>=1}
2.3.3 2型文法(上下文无关文法)
1)定义:若文法G[S]=(VN,VT,P,S)中的每个产生式规则的形式为:A→v,其中A∈VN,v∈(VN∪VT)*,则G[S]为2型文法。
2)特点:语法结构上下文无关,一般用于识别程序设计语言的语法结构。L(G)={a的i次方b的i次方|i>=1}
2.3.4 3型语言(正规文法)
1)种类:右线性文法、左线性文法
2)右线性文法:若文法G[S]=(VN,VT,P,S)中的每个产生式规则的形式为:A→αB或A→α,其中A,B∈VN,α∈(VN∪VT)*,则G[S]为右线性文法。
3)左线性文法:若文法G[S]=(VN,VT,P,S)中的每个产生式规则的形式为:A→Bα或A→α,其中A,B∈VN,α∈(VN∪VT)*,则G[S]为左线性文法。
4)特点:作为定义程序设计语言规则的文法
5)正规语言:3型文法定义的语言。L(G)={ a (ab)的n次方 a |n>=0}
2.4文法和语言的二义性
2.4.1 文法的二义性
1.定义:若一个文法存在某个句子对应两棵不同的语法树,则称这个文法是二义的。
2.特点:为编译程序的执行带来不确定性。一个语言二义性说明所有产生这个语言的文法都是二义的,文法是二义性的,其描述的语言未必是二义性的
2.4.2 二义性的消除
1.不改变文法:通过附加限制性条件消除二义性。
寻找充分不必要条件,当文法满足这些条件时可确保文法是无二义性的。就是设置一个规则,在改规则可在每个二义性情况下指出哪个语法树是正确的
2.改变文法:改写原有文法,把排除二义性的规则合并到原文法消除二义性。
2.5 文法的化简
1.若一个非终结符不能推导出终结字符串,则该非终结符是无用的,删除所有包括该非终结符的产生式规则。
2.若一个符号不能出现在文法的任何句型中,则该符号是无用的,删除所有包括该符号的产生式规则。
第三章词法分析器和有限自动机
3.1词法分析器的设计思想
3.1.1词法分析器的任务
主要任务就是从左至右逐个字符对源程序进行扫描,然后按照词法规则识别出并输出单词符号
3.1.2词法分析器的输出格式
单词符号是程序语言的基本语法单位和最小语义单位通常
- 输出的单词符号表示成二元式:(单词种类,单词符号的属性值)。
- 单词种类:关于单词种类的整数编码。
- 单词符号的属性值:反应单词符号特性或特征的值。
单词符号的种类
- 1)关键字:又称保留字或者基本字 eg:while、if、else for 个数确定,可全体编为一类(不同的关键字靠内部码值区分),也可一字一类
- 2)标识符:由字母,数字,下划线组成,且只能以字母或者下划线开头 eg 变量名,数组名,函数名 个数不确定,作为一类
- 3)常数:整型,实型常量等eg:80、1.23、“Hello“… 各种类型的常数,个数不确定,按类型分类(整型、浮点型)
- 4)运算符:eg:算术运算符、逻辑运算符、关系运算符… 个数确定,一符一类
- 5)界限符:eg:,、:、[、]、{、}… 个数确定,一符一类
- 除了五类单词,还包括空格符、回车符、换行符等。
例子
3.1.3词法分析器的地位
- 一种作为编译器的独立的一遍任务,词法分析器读取整个源程序,它的输出作为语法分析器的程序的输入
- 将词法分析器作为语法分析器的一个独立的子程序,这里就是将语法分析器作为核心
3.2词法分析器的设计
总体架构
工作过程
源程序首先被分批读入缓冲区,然后词法分析器调用预处理程序对缓冲区中的源程序进行相应的预处理操作,得到一串的输入字符,再将其放入扫描缓冲区,词法分析器就在这个扫描缓冲区逐一识别单词符号
3.2.1输入缓冲区和预处理程序
因为在一个有限的内存空间满足各种规模的源程序一次性全部输入是困难的,所以采用从磁盘上的源程序分批读入缓冲区,然后词法分析器从输入缓冲区读取字符进行扫描和分析
预处理程序的任务
- 建立缓冲区
- 过滤掉源程序的注释
- 剔除源程序的无用字符,eg 空格
- 进行宏定义 eg define
- 实现文件包含的嵌入 eg #include<stdio.h> 和条件编译的嵌入 #if #endif
3.2.2如何扫描缓冲区
- 一个指向当前正在识别单词的开始位置,称为起点指示器
- 一个用于向前搜索,寻址单词的终点
- 无论缓冲区设置为多大不能保持单词符号不会被它的边界打断,所以使用一分为二的的缓冲区,并设置单词的最大长度为N(总长度是2N)
3.2.3超前搜索
超前搜索就是向前读取字符,并判断该字符是扫描,当情况明了之后,再返回处理已读的字符
如何才能不需要超前搜索
3.2.4状态转换图和单词的识别
状态转换图就是一种有限方向图
- 结点表现一种状态,用圆圈表示
- 状态之间用箭弧连接,箭弧上的标记代表在射出结点可能出现的输入字符或者字符串
- 一张状态转换图只能包含有限个状态,最少有一个初态和最少有一个终态(用双圈表示)
识别标识符的状态转换图
- 箭头指向的是初态,所以1是初态,从初态出发
- 如果在初态的状态下,输入字符是一个字母,读进它,并转入状态2
- 在状态2下,若输入的字符是一个字母或者是数字,读进它,并重新进入状态2,一直重复这个过程,直到输入的字符是其他,则进入状态3
- 状态3是终止终态,意为着至此已经识别出一个标识符,识别过程结束
- 在终态上打了一个*号,表示多读进了一个不属于标识符的部分的字符,应该退回给输入串
L(G)={c,adm次方b|n>=0}
利用状态转换图识别单词的步骤
- 从开始状态出发
- 读入一个字符
- 根据当前字符转入下一个状态
- 重复2和3,直到无法继续进行状态转换
3.2.5状态转换图的代码实现
拿实现各类单词符号的来举例子
1写出单词表
2画出相对应的状态转换图
将关键字都作为标识符判断,在2的状态下要用单词符号去查关键字表,以确定该字母串或数字串是用户自己定义的标识符还是关键字
3状态图转换为代码
- 一个结点对应一个程序段
- 对于不含回路的分支结点,可让之对应一个switch或者一组if语句
- 对于含回路的分支结点,可让之对应一个while和if语句组成的程序段
- 终态结点表示识别出了某种单词符号,因此对应一个形如return(code,value)语句,code为单词的种别编码,value为单词符号的属性或无定义
- 当程序执行到错误处理,意味着现行状态和当前面临的输入串不匹配,如果后面还有状态图,代码应为搜索指示器回退一个位置,并令下一个状态图开始工作,若后面没有状态图,代码应为进行真正的错误
- 带*号的终态结点意为着多读进一个不属于现行单词的字符,该字符需要退回
不需要超前搜索的约定
- 除标识符,常数外,均为一符一种
- 关键字均作为保留字,不可作为用户标识符
- 设保留字符表识别标识符,查改表确定标识符是否为关键字
- 相邻单词之间至少存在一个界符,运算符或者空格
int code,value; strToken=" "; Getchar(); GetBC(); if(IsLetter()) { while(IsLetter()orIsDigit()) { Concat(); GetChar(); } Retrect();//回退一个字符 code=Reserve();//判断是不是关键字 if(code==0)//如果是标识符 { value=InsertId(strToken); return($ID,value); } else return (code,——);//如果是关键字 } else if(IsDigit()) { while(IsDigit()) { Contact(); Getchar(); } Retrect(); value=InsertConst(strToken); return ($INT,value); } else if(ch=='=') return ($ASSIGT,——); else if(ch=='+') return ($PLUS,——); else if(ch=='*') { Getchar(); if(char=='*') return($POWER,——); Retrect(); return ($STAR,——); } else if(ch==';') return ($SEMICOLON,——); else if(ch=='(') return ($LPAR,——); else if(ch==')') return ($RPAR,——); else ProcError();
状态转换图的一般化代码
3.3正规式和正规集
3.3.1定义
正规集是字母表Σ上一个特殊字集,通常我们用正规式去表述它
- 正规集可以用正规式表述
- 正规式是表述正规集的一种方法
- 一个字集合是正规集,当且仅当这个它能用正规式表达出来
定义
- 设字母表Σ:
1)ε和Ø都是Σ上的一个正规式,它们所表示的正规集为{ε}和Ø。
2)任何a∈Σ,a是Σ上的一个正规式,它所表示的正规集为{a}。
3)假设e1和e2是Σ上的正规式,它们所表示的正规集分别为L(e1)和L(e2),正规式和正规集的递归定义
- i)e1|e2是Σ上的正规式,它所表示的正规集为L(e1|e2)= L(e1)∪L(e2)。
- ii)e1e2是Σ上的正规式,它所表示的正规集为L(e1e2)= L(e1)L(e2)。
- iii)(e1)*是Σ上的正规式,它所表示的正规集为L((e1)*)= L(e1)*。
仅由上面的有限定义的表达式才是正规式,且由这些正规式表达的字集合才是Σ上的正规集
3.3.2正规式的运算
- 1)种类:或”|”、连接”.”、闭包”*”。
- 2)优先级:闭包>连接>或
- 3)说明:仅由有限次使用这三种运算而得到的表达式才是Σ上的正规式。仅由这些正规式表示的单词集才是Σ上的正规式。
3.3.3正规式的性质
U V W 均为正规式
- 若两个正规式U和V描述的正规集相同,则称正规式U和V等价。
- 1)U|V=V|U 或的交换律
- 2)U|(V|W)=(U|V)|W 或的交换律
- 3)U(VW)=(UV)W 乘的结合律
- 4)U(V|W)=UV|UW 或的结合律
- 5)(V|W)U=VU|WU 或的结合律
- 6)εU=Uε=U 乘的交换律的唯一实现方式
eg:令Σ={a,b},则有:
1)正规式a|b表示的正规集为{a,b}。
2)正规式(a|b)(a|b)表示的正规集为{aa,ab,ba,bb}。
3)正规式a*表示的正规集为{ε,a,aa,aaa,…}。
4)正规式(a|b)*表示的正规集为{ε,a,b,aa,ab,ba,bb,aaa,…}。
5)正规式a|a*b表示的正规集为包含字符串a和包含0个或多个a后跟随一个b的所有的符号串。
3.4有限自动机
3.4.1确定有限自动机(DFA)
一个确定的有穷自动机(DFA)D是一个五元组:
- D = ( S,∑,M,S0,F) 其中:
- S:有穷非空的状态集合
- ∑:有穷非空的输入符号字母表
- M:转换函数,是在S×Σ→S上的映像
- 即,M ( Si,a ) = Sj,(Si ∈ S,Sj ∈ S)就意味着,当前状态为Si,输入符为a时,将转换为下一个状态Sj,我们把Sj称作Si的一个后继状态;
- S0:S0 ∈ K,是唯一的一个初态
- F:S ⊃= F,终态集合(),可是是一个空集
eg
3.4.2非确定有限自动机
定义
一个不确定有限自动机(NFA) M是一个五元组:M=(S,Σ,δ,S0,F),其中:
- 1)S是一个有限集,它的每一个元素称为一个状态。
- 2)Σ是一个有穷字母表,它的每个元素称为一个输入字符。
- 3)δ是一个从S×Σ到S的子集的映射,即δ:S×Σ*→2S
- 4)S0⊆S,S0是一个非空初态集。
- 5)F ⊆S,F是一个终态集,可以为空。
NFA与DFA的区别和关系
- NFA可以有多个初态,而DFA只能有一个初态
- NFA弧上的标记可以是Σ*上的一个字,不一定是一个字符(甚至可以是一个正规式),但是DFA只能是Σ上的字符
- 同一个字可能出现在同状态的射出的不同弧上
- 可以说DFA是NFA的特例
NFA的识别
3.4.3NFA与DFA转换
我们知道对于一个NFA,肯定存在一个与之等价的DFA,NFA更加符合人类的思想,更加容易写出来,但是DFA更加的简便,更加容易用程序实现,所以我们设计出一个NFA,我们最好可以找出等价的DFA
主要思路———找出不同,是不同的地方相同
- 将NFA的初始状态唯一
- 将NFA弧上的标记将字变成字符
- 将NFA的转换关系变成确定的
eg(这是一个识别有两个连续的a或者两个连续b的字)
将这个NFA转换为DFA
1引入新的初始状态——解决初始状态唯一性
2简化弧上的标记——解决标记为字符
按照下列规则一步步简化
3NFA确定化(子集法)——解决ε和转换关系
设I是NFA M的状态集的子集,定义I的ε闭包ε-Closure(I):
- 1)若q∈I,则q∈ε-Closure(I)。
- 2)若q∈I,则从q出发经过任意条ε弧而能到达的任何状态q’,有q’∈ ε-Closure(I)。
- 假定I是M状态集的子集,a∈Σ,定义Ia= ε-Closure(J),其中J是从I某一状态结点出发经过一条a弧而到达的状态结点的全体
eg
转换方法
构造出状态转换表
当形成Ia和Ib都在I中,那么就不需要再继续求Ia和Ib了
给这些闭包都编号,然后画出转换图
3.4.4DFA的化简
- 1)定义:对一个DFA M,若能找到一个状态比M少的DFA M’,使得L(M)=L(M’),且M’满足两个条件:i)M’中没有多余的状态。ii)M’的状态集中,没有两个状态是互相等价的。则称DFA M‘是一个最小化的DFA。也称DFA M的化简。
- 2)最小化的方法:把DFA M的状态Q划分成一些不相交的子集,使每个子集中任何两个状态是等价的,而任何两个属于不同子集的状态是可区别的。然后在每个子集中任取一个状态作为代表,删除子集中的其余状态,并把射向其余状态的箭弧都改为射向代表的状态。
- 3)最小化的具体步骤:
- i)将DFA M的状态集S划分为两个子集;终态集F和非终态集F ̃,形成初始划分Π。(因为终态集接收一个ε还是终态,非终态集接收一个ε还是非终态)
- ii)对Π建立新的划分Πnew。对Π中的每个状态子集G进行如下变换:
- a)把G划分成新的子集,使G的两个状态s和t属于同一个子集,当且仅当对任何输入符号a,状态s和t转换到的状态都属于Π的同一子集。
- b)用G划分出的所有新子集替换G,形成新的划分Πnew。
- iii)若Πnew和Π相等,则执行第iv)步,否则,令Π=Πnew,重复第ii)步。
- iv)划分结束后,对划分中的每个状态子集,选出一个状态作为代表,删去其它一切等价的状态,并把射向其它状态的箭弧改为射向这个代表的状态。
eg
3.5正规文法,正规式和有限自动机的等价性
3.5.1 正规式与有限自动机的等价性
- 对于任何一个有限自动机M,都存在一个正规式r,使得L(r)=L(M)
- 对于任何一个正规式r,都存在一个有限自动机M,使得L(M)=L(r)
为有限自动机构造正规式
1先将这个有限自动机加上一个初态结点X 和一个终态结点Y
2通过下面的公式,不断地将一个有限自动机的状态结点减少,直到只剩了X和Y结点
X和Y弧上的正规式就是我们想要的为这个有限自动机构造的正规式
eg
为正规式构造一个有限自动机
三个转换的等价关系
三个转换式的证明
三个转换式的结论
先将一个正规式r转换为有限自动机
然后对这个r经过下面三条规则不断地分裂
eg
通过我们上面学的知识,可以将这个NFA转换为DFA,然后将DFA化简
3.5.2正规式和正规文法的转换
1正规式转换为正规文法
字母表Σ上的正规式U到正规文法G[Z]=(VN,VT,P,S)的转换方法为:VN是非终结符,VT是终结符,P是产生式的集合,S是开始符合
- 令VT=Σ,将Z→U加入到P中。
- 对P中的每条产生式规则V→U,若U=ε或U=a(a∈Σ),则本次转换结束,否则按照如下规则反复执行,直到所有产生式规则最多含有一个终结符号为止:
- i)若U=e1|e2,则将V→U修改,V→e,V→e2。
- ii)若U=e1e2,则将V→U修改为V→e1B,B→e2。B∈VN
- iii)若U=(e1)*e2,则将V→U修改为V→e1V,V→e2。 V∈VN
eg
2.正规文法转换为正规式
- 如果文法产生式 A->xB B->y则转换为A=xy
- 如果文法产生式 A->xA|y 则转换为A=x*y
- 如果文法产生式 A->x A->y则转换为A=x|y
eg
3.5.3正规文法与有限自动机的转换
1.右线性文法转换为有限自动机
设G[Z]=(VN,VT,P,Z)是一个右线性文法,其产生式规则具有形式A→aB|a|ε,由G构成相应的有限自动机M=(S,Σ,δ,s0,F)的步骤为:
1)令s0={Z},将每个非终结符看作M中的一个状态,并增加一个终态f且f∉VN,令F={f},即可得S=VN∪f。令Σ=VT(自动机的字母表等于终结符)。
2)对G中每一形如A→ε的产生式规则,令δ(A,ε)=f。
3)对G中每一形如A→a的产生式规则,令δ(A,a)=f。
4)对G中每一形如A→aB的产生式规则,令δ(A,a)=B。
构造的M多数情况下为NFA。
2.左线性文法转换为有限自动机
设G[Z]=(VN,VT,P,Z)是一个左线性文法,其产生式规则具有形式A→Ba|a|ε,由G构成相应的有限自动机M=(S,Σ,δ,s0,F)的步骤为:
1)令F={Z},将每个非终结符看作M中的一个状态,并增加一个初态f且f∉VN,令s0={f},即可得S=VN∪{f}。令Σ=VT。
2)对G中每一形如A→ε的产生式规则,令δ(f,ε)=A。
3)对G中每一形如A→a的产生式规则,令δ(f,a)=A。
4)对G中每一形如A→Ba的产生式规则,令δ(B,a)=A。
构造的M多数情况下为NFA。eg
3.有限自动机转换为正规文法
对给定的有限自动机M=(S,Σ,δ,s0,F),可构造相应的正规文法G[Z]=(VN,VT,P,Z),使得L(G)=L(M),构造方法的主要步骤如下:
1)令VT=Σ,VN=S,Z=s0.
2)若Z是一个终态,则将产生式规则Z→ε加到P中。
3)对δ(A,a)=B,若B∉F,则将产生式规则A→aB加到P中。否则,将产生式规则A→aB|A→a或A→aB,B→ε加到P中。特别的,若δ(A,a)=A,则将A→aA|ε加到P中。eg