2026春《编译原理》笔记(第1~3章:引论、文法和语言、词法分析)
先修课程:《计算理论》(第 5 学期)。
第一章 引论
1.1 术语解释
- 编译程序:编译程序是把一种(高级)语言编写的程序(称为源程序)翻译成等价的另一种(低级)语言程序(成为目标语言)的程序。
- 源程序:用户用高级语言书写的原始程序,即编译前输入给编译程序的程序。
- 目标程序:程序经过编译后得到的结果程序。
- 前端:由与源语言有关而与目标机器无关的部分组成,通常包括词法分析、语法分析、语义分析、中间代码生成、符号表的建立以及与机器无关的代码优化工作、相应的符号表管理和错误处理。
- 后端:由编译程序中与目标机器有关的部分组成。一般来讲这些部分与源语言无关而仅仅依赖于中间语言。后端包括目标代码生成、与机器有关的代码优化、相应的符号表管理和错误处理。
- 遍:对源程序或中间表示形式从头到尾扫描一次,并在扫描过程中作相关的加工处理,生成新的中间表示形式或目标程序。
1.2 编译程序的构成
- 词法分析程序。扫描字符串表示的源程序,根据词法规则识别出具有独立意义的单词符号,输出单词符号流。
- 语法分析程序。根据语法规则,把单词符号流分解成语法短语,可表示成语法树。
- 语义分析程序。对语法成分的类型、含义进行检查,以保证程序各部分能有机地结合在一起,并为以后生成目标代码收集必要的信息,如类型、目标地址等。
- 中间代码生成程序。将源程序转换为一种结构简单、含义明确的中间表示形式,以便进一步转换为目标代码。
- 代码优化程序。对中间代码进行改进以获得高效的代码,占用空间少、运行速度快。
- 目标代码生成程序。将中间代码转换成特定机器上的目标代码。
- 符号表管理程序。编译过程中的各种信息被保留在不同符号表里,编译各阶段都涉及符号表的构造、查找和更新。
- 出错处理程序。报告编译各阶段发生的错误性质和发生错误的语句,并将错误造成的影响限制在尽可能小的范围内,使编译程序能继续处理源程序的余下部分。
1.3 解释程序
解释程序是解释、执行高级语言源程序的程序。
与编译程序的不同:
- 编译程序把源程序翻译成等价的目标程序(只翻译,不执行),此后目标程序的运行不再依赖于编译程序。
- 解释程序则边翻译(解释)边执行,不产生目标代码,直接输出源程序的运行结果。源程序的每一次运行都离不开解释程序。
1.4 例题
分析以下错误信息,指出是哪个编译阶段报告的?
- else没有匹配的if。【语法分析】
- 数组下标越界。【语义分析/运行期】
- 使用的函数未定义。【语法分析】
- 在数字中出现非数字字符。【词法分析】
尚未复习到的
编译工具链;PL/0语言。
第二章 文法和语言
语言(语法、语句、语义)的相关概念,文法-语法-语句的关系。巴科斯范式(BNF,Backus–Naur Form)。
文法(Grammar): 描述语言的语法结构的形式规则。
2.1 符号和符号串
字母表:元素的非空有穷集合,其元素称为符号,因此也成为符号表,一般记作\(∑\)。
符号串:由字母表中的符号组成的任何有穷序列称为(该字母表上的)符号串。特别地,不含任何符号的有穷序列称为空串,记为\(ε\)。单词和源程序都是符号串。
- 符号串的有关运算:符号串的长度、头、尾、固有头、固有尾、或(|或者+,PPT中采用前者)、连接、方幂、集合、闭包(字母表上所有有穷长的串的集合)、正闭包。符号串集合的和(并)、乘积(交)、方幂、闭包。
2.2 文法和语言的形式化定义
规则:也称重写规则、产生式、生成式,是形如 \(\alpha→\beta\) 或 \(\alpha:==\beta\) 的有序对,其中 \(\alpha\) 称为规则的左部,\(\beta\) 称为规则的右部。这里使用的符号 \(→\) (\(:==\)) 读作“定义为”。其实例也说成一条关于其左部的规则(产生式)。
文法:文法 \(G\) 定义为一个四元组 \((V_N,V_T,P,S)\),记为 \(G = (V_N,V_T,P,S)\)。其中,
- \(V_N\) 是非空有穷集合,称为非终结符集,其元素称为非终结符;
- \(V_T\) 是有穷集合,称为终结符集,其元素称为终结符;
- \(P\) 是非空有穷集合,称为规则集,其元素是字母表 \(V_N∪V_T\) 上形如 \(\alpha→\beta\) 的规则,其中 \(\alpha∈(V_N∪V_T)^*\) 且至少包含一个非终结符,\(\beta∈(V_N∪V_T)^*\)。\(V_N∪V_T\) 称为文法的字母表 \(V\),且 \(V_N ∩V_T = Φ\);
- \(S ∈ V_N\),称为开始符或识别符,至少在一条规则中作为左部出现。
(查阅资料,\(V_T\) 一般总是被约定为非空有穷集合,而课件中把 \(V_T\) 约定为有穷集合,相差的是终结符集为空集的情形,此时生成的语言只能为 \({\epsilon}\) (对应规则中存在 \(S→\epsilon\) 的情形)或 \(\Phi\)。)
例如,定义文法 \(G =(V_N,V_T,P,S)\),其中 \(V_N = \{S\}\), \(V_T = \{a, b\}\), \(P = \{S → aSb, S → ab\}\), \(S = S\)。
推导与规约:直接(一步)推导/规约,间接(多步)推导/规约,0步或0步以上推导与归约。
句型:设文法 \(G =(V_N,V_T,P,S)\), 对于 \(β ∈ V* = (V_N∪V_T)*\) ,如果 \(S\) 能够经过0步或0步以上推导出 \(β\),则称 \(β\) 是文法 \(G\) 的句型。
句子:如果 \(β\) 是 \(G\) 的句型,且 \(β ∈ (V_T)*\),则称 \(β\) 是 \(G\) 的句子。
语言:文法 \(G =(V_N,V_T,P,S)\) 能够产生的所有句子的集合称为 \(G\) 的语言,记为 \(L(G) = \{β︱S 经过0步或0步以上推导出 β,β ∈ V_T*\}\)。
对于两个文法 \(G_1\), \(G_2\),如果 \(L(G_1) = L(G_2)\),则称文法 \(G_1\) 和 \(G_2\) 是等价的。
文法设计。递归思想。
2.3 文法的类型
所有介绍都是基于乔姆斯基(Chomsky)体系的。
0 型文法(短语文法、无限制文法、递归可枚举文法)
即上文对文法的定义,对于文法的每个产生式 \(\alpha → \beta\),如果
其中 \(\beta∈(V_N∪V_T)^*\),则该文法为 0 型文法,该文法产生的语言称为 0 型语言。
在 Chomsky 体系中,所有文法都是 0 型文法,其能力相当于图灵机(Turing Machine),或者说任何 0 型语言都是递归可枚举的,反之递归可枚举集必定是一个 0 型语言。(在 Chomsky 体系外尽管找得到形式上的非 0 型文法,但根据丘奇-图灵论题,不存在能力上强于 0 型文法的文法。)
1 型文法(上下文有关文法)
对于文法的每个产生式 \(\alpha → \beta\),如果
仅仅 \(S→\epsilon\) 除外(此时规定 \(S\) 不出现在生成式的右部,即该生成式仅用于生成空串而不会在推导的过程中缩短串),则该文法为 1 型文法该文法产生的语言称为上下文有关语言,其能力相当于线性界限自动机。此定义表现了 1 型文法的非缩短性质,容易知道这使得判断一个串是否可以由 1 型文法生成的命题是可判定的,而此问题对于 0 型文法则等价于停机问题,不可判定。
另一种等价的形式描述是
其中 \(\alpha_1, \alpha_2, \beta ∈ (V_N∪V_T)^*\), \(\beta ≠ \epsilon\), \(A ∈ V_N\)。此定义体现了上下文有关性质,即只有 A 出现在上下文中才能被取代。以下是粗略的证明。后推前比较容易,由 \(\beta ≠ \epsilon\) 可以知道是非缩短的。前推后的一个思路是,对于非增长的产生式,考虑长度不增加的情况,诸如 \(AB→CD\), 可以使用 \(AB→XB, XB→XD, XD→CD\) 等价(注意不能用 \(A→C,B→D\),如果这样不仅会作用于 \(AB→CD\),诸如 \(AE→FG\) 的产生式也会被影响。我们也能从这个例子中体会到上下文有关的含义),每个都满足上下文有关规则(例如 \(AB→XB\),可以看作 \(\alpha_1 = \epsilon, \alpha_2 = B, \beta = X\)),即通过引入新符号让原来的产生式等价转换到符合上下文有关规则的产生式,而对于增长的产生式,则在上述例子中转换后的最后一个产生式中加上多余的符号即可。如此操作之后非缩短形式的产生式能够转换为符合上下文有关规则的产生式。则得证。
2 型文法(上下文无关文法)
对于文法的每个产生式 \(\alpha → \beta\),如果
其中 \(\beta ∈ (V_N∪V_T)^*\),则该文法为 2 型文法(上下文无关文法),该文法产生的语言称为上下文无关语言。类似于 1 型文法,其等价的上下文无关形式为
这里说明文法与其产生语言的关系。上下文无关文法生成的语言一定是上下文无关语言,但生成上下文无关语言的文法不一定是上下文无关文法。(一个文法的产生式形式决定了它能力的上限,它实际生成的语言复杂度不会超过这个上限,但可以低于它。)对于一个语言,只要存在至少一个上下文无关文法能够生成该语言,它就被称为上下文无关语言。
对于几层定义的包含关系,严格上是对语言来说的。对于 \(S→aSb|ε\),在 \(S\) 生成空串这一产生式存在的同时, \(S\) 还存在于其它产生式的右部,所以该文法形式上并不是上下文有关文法(只是 0 型文法),但能生成上下文有关语言(更精确地,其生成的语言 \(\{a^nb^n | n ≥ 0\}\) 是上下文无关语言)。生成相同语言的文法是等价的,该文法可以等价转化为上下文无关文法 \(S_0 → S | ε, S → aSb | ab\)。
3 型文法(正规文法、正则文法)
对于文法的每个产生式,其形式如果都是
则该文法为右线性 3 型文法(正规文法,正则文法),其中 \(A→aB\) 变为 \(A→Ba\) 时为左线性 3 型文法,统称为 3 型文法,该文法产生的语言称为正规语言(正则语言)。(在课本中把右线性正则文法称作正则文法。实际上左、右线性语言的其中一种即可生成全部正则语言集,但是两种表示都是对的(只要不混用),即左线性和右线性都属于正则文法。课本上的定义没有允许空规则(任意非终结符产生空串),导致空串 \(\epsilon\) 不能进入所生成的语言,这样的文法只能生成不含空串的正则语言,比如无法表示一个初始态即接受态的 DFA。综合以上,课件的说法更为完善。)
在《编译原理》里,仅仅涉及到 2 型文法和 3 型文法的使用。后面也仅仅继续讨论 2 型文法(或 3 型文法)的有关内容。
2.4 上下文无关文法及其语法树
上下文无关文法的简洁描述方法:上下文无关文法一个显著特征是规则左部一定有且仅有一个非终结符。利用这个特征,可以不列出 \(V_N\) 和 \(V_T\) ,给出一个上下文无关文法的简洁描述方法如下。
- ①文法名 \(G\) 改写成 \(G[S]\),其中,\(S\) 表示开始符;
- 规则集 \(P\),仅书写其具体规则。
最左推导、最右推导:如果在推导的每一步总是选择当前句型的最左(最右)边非终结符进行推导,则称这种推导过程为最左(最右)推导。最右推导也叫规范推导。由规范推导所得的句型,叫做规范句型。规范推导的逆过程,叫做规范归约。
语法树:文法 \(G\) 的语法树是一个满足下列条件的多叉树。
- 以文法开始符 \(S\) 做为树根;
- 以终结符号或非终结符号做为树的其他结点,且子树根和其孩子结点(按序)分别是某规则的左部和右部。(课本中还规定了非叶结点的标记必须是非终结符,因为是对于上下文无关文法讨论的,所以实际上是隐含的可推出的条件。)
子树:由某一结点连同所有分支组成的部分。
简单子树:仅具有单层分支的子树。
文法的二义性(ambiguity):如果一个文法对应存在某个句子对应两个不同的语法树,或者说有两个不同的最左(最右)推导,则说这个文法是二义的。注意文法和语言的二义性不同,可能有两个不同的文法,其中一个是二义的一个不是二义的,但是它们生成同一种语言。如果产生上下文无关语言的每一个文法都是二义的,则说此语言是先天二义的。对于程序设计语言来说,常常希望它的文法是无二义的,因为希望对它的每个语句的分析是唯一的。
要判定任给的一个上下文无关语言是否为二义的,或它是否产生一个先天二义的上下文无关语言,这两个问题是递归不可解的,即不存在一个算法能在有限步骤内判定任给的一个文法是二义的。我们能做的是为无二义性寻求一组充分条件,比如规定优先级与结合性。
句型分析,分析程序(识别程序),分析算法(识别算法)。自顶向下的(“匹配”)和自底向上的(“归约”)分析方法。回溯。
短语:设文法 \(G =(V_N,V_T,P,S)\),如果有 \(\alpha \beta \theta\) 是文法 \(G\) 的一个句型,如果 \(S\) 能够 0 步或 0 步以上推导出 \(\alpha A \theta\) 且 \(A\) 能够 1 步或者 1 步以上推导出 \(\beta\),则称 \(\beta\) 是句型 \(\alpha A \theta\) 相对于非终结符 \(A\) 的短语。任一子树的树叶全体(具有共同祖先的叶节点符号串)皆为短语。若其中 \(A\) 能够直接推导出 \(\beta\),则称 \(\beta\) 是句型 \(\alpha \beta \theta\) 相对于规则 \(A→\beta\) 的简单短语(直接短语)。任一简单子树的树叶全体(具有共同父亲的叶节点符号串)皆为简单短语。(课件中的定义为 \(S\) 能够 1 步或 1 步以上推导出 \(\alpha A \theta\),实际上是过于严格的,例如忽略了当 \(S\) 直接推导出串 \(\beta\) 时,\(\beta\) 是句型 \(\beta\) 关于非终结符 \(S\) 的短语。从语法树的角度看,可以理解为整个树也可以看作一个子树。)
句柄:一个右句型的直接短语称作句柄。(在最右推导(每一步都替换当前句型里最右边那个非终结符)中出现的句型就叫右句型。对称地,最左推导中出现的句型叫左句型。)句柄的概念只适用于右句型。如果所考虑的文法是无二义的,那么每个右句型有唯一的最右推导,因而其句柄是唯一的,此时该句型的最左直接短语即是它的句柄。对于二义文法,右句型就可能有多个句柄。
2.5 有关文法实际应用的说明
文法的使用限制:不得含有有害规则(一个产生式中的左部和右部完全一样,该产生式显然没有必要,只会引起文法的二义性)和多余规则(不可到达的非终结符和不可终止的非终结符,相对应地,为了保证非终结符在句子推导中出现,至少满足其必须在某句型中出现且必须能够从其推导出终结符号串)。
算法:文法的化简
文法的化简即删除有害规则和多余规则。
算法:删除有害规则
略。
算法:删除多余规则之不终结的产生式
构造能推导出终结符号串的非终结符集 \(V_{VT}\)。
- 若有 \(A→\alpha\) 且 \(\alpha∈V_T*\) ;则令 \(A∈V_{VT}\) ;
- 若有 \(B→\beta\) 且 \(\beta∈(V_T+ V_{VT})*\) ;则令 \(B∈V_{VT}\) ;
- 重复步骤 1 和 2,直到 \(V_{VT}\) 不再扩大为止。
删除不在 \(V_{VT}\) 中的所有非终结符(连同其产生式)。
算法:删除多余规则之不可用的产生式
构造可用的非终结符集 \(V_{US}\):
- 首先令 \(S∈V_{US}\) ; (S为文法开始符号)
- 若有 \(S\) 经过 1 步或 1 步以上推导出 \(…A…\),则令 \(A∈V_{US}\);
- 重复步骤 2,直到 \(V_{US}\) 不再扩大为止。
(2) 删除不在 \(V_{US}\) 中的所有非终结符(连同其产生式)。
上下文无关文法的 \(\epsilon\) 规则:\(\epsilon\) 在不在语言中不是什么本质问题,因为可以经过 \(\epsilon\)-消除去掉而不改变语言。
算法:删除 \(\epsilon\) 产生式
- 首先构造可以推出空串的非终结符集 \(V_\epsilon\);
(1) 若有 \(A→\epsilon\); 则 令 \(A∈V_\epsilon\);
(2) 若有 \(B→A_1…A_n\) 且全部 \(A_i∈V_\epsilon\) ;则令 \(B∈V_\epsilon\);
(3) 重复步骤 (1)(2),直到 \(V_\epsilon\) 不再扩大为止。 - 删除 \(G(S)\) 中的 \(A→\epsilon\) 形式的产生式;
- 依次改写 \(G[S]\) 中的产生式 \(C→X_1X_2…X_n\)。
若有 \(X_i∈V_\epsilon\) 则用 \((X_i|\epsilon)\) 替换之(一个分裂为两个)。
(若有 \(j\) 个 \(X_i∈V_\epsilon\),则一个产生式将分裂为 \(2^j\) 个。)
此处注意,(1)是对右部全为非终止符且每个都能产生空串的产生式来说的,(3)是对所有右部全为非终止符且存在至少一个能够产生空串的产生式来说的。
第三章 词法分析
词法分析的任务:从左至右逐个字符地对源程序进行扫描,从基于字符理解的源程序中分离出符合源语言词法的单词。
词法分析器(Lexical Analyzer):又称扫描器(Scanner),即执行词法分析的程序,输入源程序、输出单词符号。
单词符号:关键字(保留字),标识符,常数,运算符,界符。
单词符号的输出表示:(单词种别, 单词自身的值)。当单词为标识符时,一般是 (标识符,指向该标识符所在符号表中位置的指针)。
单词种别的表示:通常用整数编码表示。
- 若一个种别只有一个单词符号,则种别编码就代表该单词符号。假定关键字、运算符和界符都是一符一种。
- 若一个种别有多个单词符号,则对于每个单词符号,给出种别编码和自身的值。标识符单列一种,自身的值表示成按机器字节划分的内部码;常数按类型分种,常数的值则表示成标准的二进制形式。
将词法分析工作分离的考虑:
- 使整个编译程序的结构更简洁、清晰和条理化。
- 编译程序的效率会改进。
- 增强编译程序的可移植性。
- 可以完成一些其它的任务。
词法分析器可以用状态转换图描述。
3.1 状态转换图
状态转换图是一张有限方向图。结点代表状态,用圆圈表示;状态之间用箭弧连结,箭弧上的标记(字符)代表射出结状态下可能出现的输入字符或字符类。一张转换图只包含有限个状态,其中有一个为初态,至少要有一个终态。
状态转换图可用于识别(或接受)一定的字符串。若存在一条从初态到某一终态的道路,且这条路上所有弧上的标记符连接成的字等于α,则称α为该状态转换图所识别(接受)。
对于状态转换图的实现,思想是每个状态结点对应一小段程序。
- 对不含回路的分叉结点,可用一个 CASE 语句或一组 IF-THEN-ELSE 语句实现;
- 对含回路的状态结点,可对应一段由 WHILE 结构和 IF 语句构成的程序;
- 终态结点表示识别出某种单词符号,因此对应语句为 RETURN (C,VAL)。其中 C 为单词种别,VAL 为单词自身值。
3.2 正规文法和正规表达式
单词可以用正则文法或正则表达式(正则式)描述。
正则文法的定义见第 2 章。
正规式和正规集的递归定义:
对给定的字母表 \(\Sigma\):
- \(\epsilon\) 和 \(\Phi\) 都是 \(\Sigma\) 上的正规式,它们所表示的正规集为 \(\{\epsilon\}\) 和 \(\Phi\),即 \(L(ε)= {ε}\),\(L(Ф)=Ф\);
- 任何 \(a∈\Sigma\) ,\(a\) 是 \(\Sigma\) 上的正规式,它所表示的正规集为 \(L(a)={a}\);
- 假定 \(e_1\) 和 \(e_2\) 都是 \(\Sigma\) 上的正规式,它们所表示的正规集为 \(L(e_1)\) 和 \(L(e_2)\),则
(1) \((e_1|e_2)\) 为正规式,它所表示的正规集为 \(L(e_1|e_2)=L(e_1)∪L(e_2)\);
(2) \((e_1·e_2)\)为正规式,它所表示的正规集为 \(L(e_1·e_2)=L(e_1)L(e_2)\);
(3) \((e_1)*\) 为正规式,它所表示的正规集为 \(L((e_1)*)=(L(e_1))*\)。
仅由有限次使用上述三步骤而定义的表达式才是 \(\Sigma\) 上的正规式,仅由这些正规式表示的符号串集才是 \(\Sigma\) 上的正规集。
正规式的等价:若两个正规式所表示的正规集相同,则称这两个正规式等价。如 \(b(ab)^*=(ba)^*b\)。
正规式的运算:或的交换律和结合律,连接的结合律,前后分配律,恒等律。
正规式和正规文法的等价:如果正规式 \(r\) 和文法 \(G\) 有 \(L(r)=L(G)\),则称正规式 \(r\) 和文法 \(G\) 是等价的。
算法:正规式转换成正规文法
设\(∑\)上正规式\(r\),则等价文法\(G=(V_N, V_T, P, S)\)。其中,\(V_T=∑\);从形如产生式 \(S→r\) 开始,按下表规则进行转换,直到全部形如产生式,符合正规文法之规则形式为止,可得到\(P\)和\(V_N\)。
| 规则 | 转换前 | 转换后 |
|---|---|---|
| 规则 1 | \(A→xy\) | \(A→xB, B→y\) |
| 规则 2 | \(A→x*y\) | \(A→xB, A→y, B→xB, B→y\) |
| 规则 3 | \(A→x︱y\) | \(A→x, A→y\) |
算法:正规文法转换成正规式
基本上是正规式到正规文法的逆过程,按下列规则将文法处理成只剩下一个开始符号定义的正规式。
| 规则 | 转换前 | 转换后 |
|---|---|---|
| 规则 1 | \(A→xB, B→y\) | \(A→xy\) |
| 规则 2 | $A→xA | y$ |
| 规则 3 | \(A→x, A→y\) | \(A→x︱y\) |
注意,对于规则 2,从正规式到文法必须用一个新非终结符 \(B\) 把 \(x*\) 隔离开,否则会出错,因为此时 \(A\) 往往还有别的产生式(例如正规式是 \(a*b|c\),对应 \(S→a*b|c\),若不采用新的非终止符,只得到 \(S → aS|b|c\),此时有 \(S→aS→ac\),但原语言根本没有串 \(ac\)。问题出在 \(a\) 这个循环前缀本该只能接到 \(b\) 上,但由于没有用新的非终止符隔离,让它接到了 \(S\) 的另一条出口 \(c\) 上);从文法到正规式则只需把 \(A→xA|y\) 转换为 \(x*y\)。两者不是互逆的。由正则文法的自循环 → 正则式的星号总是安全的,而由正则式的星号 → 正则文法的自循环是不安全的。
注意,凡是文法里有互相引用的环,可以将一方整理后整体带入另一方。
3.3 有穷自动机
本质上和状态转换图相同。
分为两类:不确定的有穷自动机(Nondeterministic Finite Automata/NFA),边上的标号没有限制,一个符号可出现在离开同一个状态的多条边上,\(ε\) 可以做标号;确定的有穷自动机(Deterministic Finite Automata/DFA),对于每个状态以及每个符号,有且只有一条边(或最多只有一条边)。
两种自动机都识别正则语言,对于每个可以用正则表达式描述的语言,均可用某个NFA或DFA来识别;反之亦然。
确定有限自动机(DFA) \(M\) 是一个五元式 \(M=(K, \Sigma, f, S, Z)\),其中:
- \(K\): 有穷状态集;
- \(\Sigma\): 输入字母表(有穷);
- \(f\): 状态转换函数,为\(K×\Sigma→K\)的单值部分映射,\(f(k_i,a)=k_j\)表示:当现行状态为\(k_i\),输入字符为\(a\)时,将状态转换到下一状态\(k_j\),\(k_j\)称为\(k_i\)的一个后继状态;
- \(S∈K\):唯一的一个初态;
- \(Z⊆K\):终态集(可空),也称可接受状态集或结束状态集。
转换函数\(f\)可以扩充为\(f’: K×\Sigma*→K\)映射,并以\(f\)替代\(f’\)使用。
对于\(\Sigma*\)中的任何符号串\(\alpha\),若存在一条从初态到某一终态的道路,且这条路上所有弧上的标记符连接成的符号串等于\(\alpha\),则称\(\alpha\)为DFA \(M\)所接收(或识别);DFA \(M\)所识别的字的全体记为\(L(M)\)。
设DFA \(M=(K, \Sigma, f, S, Z)\),如果\(α∈\Sigma*\), \(f’(S, α)∈Z\),则称符号串\(α\)是DFA \(M\)所接受(或识别)的。DFA \(M\)所接受的符号串的集合记为\(L(M)\),即\(L(M)={α|α∈\Sigma*, f’(S, α)∈Z}\)。
不确定有限自动机(NFA) \(M\) 是一个五元式 \(M=(K, \Sigma, f, S, Z)\),其中:
- \(K\): 有穷状态集;
- \(\Sigma\): 输入字母表(有穷);
- \(f\): 状态转换函数,为\(K×\Sigma∪{ε}→2^K\)的单值部分映射,其中\(2^K\)表示\(K\)的幂集(全部子集的集合);
- \(S⊂K\):非空的初态(也可以为非空集合);
- \(Z⊂K\):终态集。
NFA转换函数\(f\)也可以进行类似的扩充。
NFA和DFA一个重要区别在于NFA中存在多个转移后的状态,即NFA中\(f\)的返回值为多个状态。
对于\(\Sigma*\)中的任何字\(\alpha\),若存在一条从初态到某一终态的道路,且这条路上所有弧上的标记字连接成的字等于\(\alpha\)(忽略那些标记为\(\epsilon\)的弧),则称\(\alpha\)为NFA \(M\)所识别(接收),NFA \(M\)所识别的字的全体记为\(L(M)\)。
设NFA \(M=(K, \Sigma, f, S, Z)\),如果\(α∈\Sigma*\),\(f’(S, α)∩Z≠Φ\),则称符号串\(α\)是NFA \(M\)所接受(或识别)的。NFA \(M\)所接受的符号串的集合亦记为\(L(M)\),即\(L(M)={α|α∈\Sigma*,f’(S, α)∩Z≠Φ}\)。
自动机的等价性:对于任何两个有限自动机\(M\)和\(M’\),如果\(L(M)=L(M’)\),则称\(M\)与\(M’\)等价。
- 判定两个自动机等价性的算法是存在的。
- 对于每个NFA \(M\)存在一个DFA \(M’\),使得 \(L(M)=L(M’)\)。
- DFA与NFA描述能力相同。
(课件中“1,即 2”的表述存疑。)
正规式和有穷自动机的等价性:
对于正规式\(r\)和有限自动机\(M\),如果\(L(r)=L(M)\),则称\(r\)和\(M\)是等价的。
- 对任何FA \(M\),都存在一个正规式\(r\),使得\(L(r)=L(M)\)。
- 对任何正规式\(r\),都存在一个FA \(M\),使得\(L(M)=L(r)\)。
正规文法和有限自动机的等价性:
对于正规文法\(G\)和有限自动机\(M\),如果\(L(G)=L(M)\),则称\(G\)和\(M\)是等价的。
- 对每一个右线性正规文法G或左线性正规文法G,都存在一个有限自动机(FA) \(M\),使得\(L(M)=L(G)\)。
- 对每一个FA \(M\),都存在一个右线性正规文法\(G_R\)和左线性正规文法\(G_L\),使得\(L(M)=L(G_R)=L(G_L)\)。
算法:NFA 转 DFA ——子集构造法

算法:DFA 的最小化——分割法
状态\(p\)和\(q\)等价的二个条件:
- 一致性条件:\(p\)和\(q\)同时是可接受状态或不可接受状态。所以,对于\(∀p∈Z\),\(∀q∈K-Z\),\(p\)和\(q\)是不等价的。
- 蔓延性条件:对所有输入符号,\(p\)和\(q\)必须转换到等价的状态中。

算法:NFA 到正规式



算法:正规式到 NFA

算法:右线性正规文法到 NFA

算法:左线性正规文法到 NFA

算法:DFA 到右线性正规文法

正规文法、正规表达式、DFA、NFA、最小化 DFA 的转换图

【自学部分】词法分析程序的自动构造工具 LEX
在 Windows 中是 FLEX,实现词法分析程序的自动生成。Lex源程序组成如下。
%{
说明部分
%}
%%
转换规则
%%
辅助过程(用户子程序部分)
三个部分都是可选的,没有辅助过程时,第2个%%可以省略。
浙公网安备 33010602011771号