【编译原理核心知识点总结】第三章、正则文法、NFA、DFA

阅读规范:

  • 本文以重点为主,零碎知识点/相对不够重要的为辅助阅读内容,以脚注形式给出,点击脚注即可快速跳转。
  • 助解题目通常是为了帮助理解给出的题目,考试不考,若已理解可直接跳过。
  • 文中提到的课本是陈火旺的《编译原理第三版》。
  • 习题的答案也统一用脚注给出(脚注位于习题后),点击脚注即可快速跳转,建议先自己思考,再看答案。
  • 每章节后面会有综合题型,涵盖了本章节重点知识及算法,请完全掌握。

脚注使用:单击正文后的脚注标记即可跳转到详细,再次点击脚注详细内容后的返回箭头可以返回至正文阅读处

本文已开启Latex数学公式支持

正则文法:描述单词语法的文法

基本定义
  • 正则文法,3型文法,分为右线性文法左线性文法,重点掌握右线性文法。【快速跳转链接:3型文法1、左线性文法1

    右线性文法:产生式形式为 U → x V ∣ y U→xV|y UxVy U , V ∈ V N , x , y ∈ V T ∗ U,V ∈V_N,x,y∈V_T^* U,VVNx,yVT

  • 右线性文法G[S]的状态转换图(TG)表示

    • G[S]中的非终结符 V N V_N VN作为TG的节点(用⚪表示)
    • G[S]的开始符号S对应状态转换图的开始状态S;(每个TG用 → → 指向开始状态)
    • 增加一个新状态 Z Z Z,作为状态转换图的终止状态(用双圈表示);
    • G[S]中形如 U → x V U→xV UxV的每条产生式,画一条从状态U到状态V的方向弧,弧上的标记为x;
    • 对于G[S]中形如 U → y U→y Uy的每条产生式,画一条从状态U到终态Z的方向弧,弧上的标记为y

    【快速跳转链接:左线性文法的状态转换图表示2

  • 助解题目:给出与正则文法G(S)等价的状态转换图。【图】

正规式与正规集
  • 正规式(正则表达式),对于字符集 ∑ ∑ ,仅在 ∑ ∑ 上包含()、|、*、·四种运算的正规式所表示的集合是 ∑ ∑ 上的正规集

    【快速跳转链接:()、|、*、·四种运算运算规则 3

  • 助解题目: ∑ = a , b ∑={a, b} =a,b,其上的正规式与对应的正规集的例子:

正规式正规集
a ∣ b a|b ab { a , b } \{a, b\} {a,b}
( a ∣ b ) ∗ (a|b)^* (ab) { a , b } ∗ 即 a 和 b 所能构成的所有串的集合, { ϵ , a , b , a a , a b , b a , b b , a a a , . . . } \{a,b\}^*即a和b所能构成的所有串的集合,\{\epsilon, a, b, aa, ab, ba, bb, aaa, ...\} {a,b}ab所能构成的所有串的集合,{ϵ,a,b,aa,ab,ba,bb,aaa,...}
a ∗ a^* a { ϵ , a , a a , a a a , . . . } 即 0 或多个 a 的串组成的集合 \{\epsilon, a, aa, aaa, ...\}即0或多个a的串组成的集合 {ϵ,a,aa,aaa,...}0或多个a的串组成的集合
( a ∣ b ) ( a ∣ b ) (a|b)(a|b) (ab)(ab) { a a , a b , b a , b b } \{aa, ab, ba, bb\} {aa,ab,ba,bb}

【快速跳转链接:等价正规式 & 正规式等价变换 4

  • 例子1: a ∣ b ∗ c a|b^*c abc,它所表示的正规集为:串a或者是零个或多个b后跟随一个c,即 { a , c , b c , b b c , b b b c , . . . } \{a, c, bc, bbc, bbbc, ...\} {a,c,bc,bbc,bbbc,...}
  • 例子2:求“每个1都有0直接跟在右边”的正规式: ( 0 ∣ 10 ) ∗ (0|10)^* (0∣10)
    • 思考方式:上述描述的基本结构是 10 10 10 ( 10 ) ∗ (10)^* (10)表示的是 { ϵ , 10 , 1010 , . . . } \{\epsilon, 10, 1010,...\} {ϵ,10,1010,...},在这个基本结构之上,0的位置是任意的,因此也就变成了“ 10 10 10 0 0 0的所有组合”,即 ( 0 ∣ 10 ) ∗ (0|10)^* (0∣10)
  • 习题:(选择/填空),课本 p64 8(1-4)

根据描述给出正规式

(1)以01结尾的二进制数串 5

(2)能被5整除的十进制整数 6

(3)包含奇数个1或奇数个0的二进制数串 7

(4)英文字母组成的所有符号串,要求符号串中的字母按照字典序排列 8

有限自动机(DFA、NFA)
DFA(确定的有限自动机)
  • 五元组表示法

    • M = ( S , Σ , f , S 0 , Z ) M=(S, \Sigma, f, S_0, Z) M=(S,Σ,f,S0,Z)
    1. S S S是一个非空有限集,它的每个元素称为一个状态
    2. Σ Σ Σ是一个有限的输入字母表,它的每个元素称为一个输入字符
    3. f是转换函数集,形如 f ( k i , a ) = k j ( k i ∈ S , k j ∈ S , a ∈ Σ ) f(k_i,a)=k_j(k_i∈S, k_j∈S,a∈Σ) f(ki,a)=kj(kiS,kjSaΣ):当前状态为 k i k_i ki,输入字符为a时,将转换到下一个状态 k j k_j kj, f f f值唯一
    4. S 0 ∈ S S_0 ∈S S0S唯一的一个初始状态;
    5. Z ⊆ S Z\subseteq S ZS,是终止状态(终态)集合
    • 注意:初始状态只有一个、终态可以多个、f值唯一
  • 状态转换图表示法

  • 状态矩阵表示法

矩阵的行表示当前状态,列表示输入字符,矩阵元素表示相应状态行和输入字符列下的新状态。

  • 助解题目:五元组与状态转换图互换ppt 3.3 23页】
NFA(非确定的有限自动机)
  • 五元组表示法

    • M = ( S , Σ , f , S 0 , Z ) M=(S ,Σ,f,S_0,Z) M=(SΣfS0Z)
    1. S , Σ , Z S,\Sigma,Z S,Σ,Z的意义与DFA相同
    2. f f f与DFA中 f f f的区别在于,对某个当前状态,对于输入字符a,可能有多个次态
    3. S 0 S_0 S0表示的是初态集合 S ⊂ 0 S\subset 0 S0
    • 注意:初始状态可以有多个、终态可以多个,f值不唯一
  • 状态转换图表示法

  • 状态矩阵表示法

NFA与DFA联系与区别
  • 区别:

初态:DFA只有一个,NFA有多个

状态转换函数 f f f:DFA每个 f f f值唯一确定,NFA每个 f f f值可以有多个(次态集合)

有向弧:DFA中无 ϵ \epsilon ϵ弧,NFA中可能存在 ϵ \epsilon ϵ

  • 联系:DFA是NFA的特例
NFA转DFA(NFA确定化)——子集构造法
  • NFA确定化:通过某些操作消除NFA中 f f f的多值性

  • 必须掌握的三种运算,对于状态集 I I I

    ε − c l o s u r e ( I ) ε-closure(I) εclosure(I)——状态集的 ε ε ε闭包

    m o v e ( I , a ) move(I, a) move(I,a)——状态集的 a a a弧转换

    I a = ε − c l o s u r e ( m o v e ( I , a ) ) I_a = ε-closure( move(I, a) ) Ia=εclosure(move(I,a))——状态集的 a a a弧转换的闭包 I a I_a Ia

    • ε − c l o s u r e ( I ) ε-closure(I) εclosure(I)

      • 状态集 I I I中的每个元素经过 0 或 n 条 ϵ 弧 0或n条\epsilon弧 0nϵ 能到达的所有状态集合
      • 注:经过0条 ϵ \epsilon ϵ弧所能到达的状态即自己本身
    • m o v e ( I , a ) move(I, a) move(I,a)

      • 状态集 I I I中的每个元素经过 1 条 a 弧 1条a弧 1a 能到达的所有状态集合
      • 注意:仅经过1条a弧
    • I a = ε − c l o s u r e ( m o v e ( I , a ) ) I_a = ε-closure( move(I, a) ) Ia=εclosure(move(I,a))

      • 先求 m o v e ( I , a ) move(I, a) move(I,a) , 记所得集合为 M M M
      • 再求 ε − c l o s u r e ( M ) ε-closure(M) εclosure(M)
    • 习题:NFA的状态转换图如下,状态集 I = { 2 , 3 } I=\{2, 3\} I={2,3},求 ε − c l o s u r e ( I ) ε-closure(I) εclosure(I) I 2 I_2 I2 I 3 I_3 I3

      • 【图】
      • 答案9
  • 方法论

    • 核心:构造状态转换矩阵, 形如

      I I I I a I_a Ia I b I_b Ib
      T 0 T_0 T0 ε − c l o s u r e ( m o v e ( T 0 , a ) ) ε-closure( move(T_0, a) ) εclosure(move(T0,a)) ε − c l o s u r e ( m o v e ( T 0 , a ) ) ε-closure( move(T_0, a) ) εclosure(move(T0,a))
      T 1 T_1 T1 ε − c l o s u r e ( m o v e ( T 1 , a ) ) ε-closure( move(T_1, a) ) εclosure(move(T1,a)) ε − c l o s u r e ( m o v e ( T 1 , a ) ) ε-closure( move(T_1, a) ) εclosure(move(T1,a))
    • ( 1 ) (1) (1) T 0 = ε − c l o s u r e ( X ) T_0 = ε-closure( X ) T0=εclosure(X) X X X是NFA的唯一初态。NFA的初态可能有多个,因此分以下两种情况讨论:

      • NFA初态唯一,且为 S 0 S_0 S0 X = S 0 X = S_0 X=S0
      • NFA初态不唯一,则构造一个新状态 X X X作为NFA的唯一初态,并通过一条 ϵ \epsilon ϵ弧指向初态集合 S 0 S_0 S0中的任意初态
      • 若NFA终态不唯一,则构造一个新状态 Y Y Y作为NFA唯一终态,并将NFA中任意终态节点通过 ϵ \epsilon ϵ弧指向 Y Y Y
    • ( 2 ) (2) (2)对NFA的状态转换图做如下等价变化:【图】【书p50】

    • ( 3 ) (3) (3) C C C表示新状态集合,开始构造状态转换矩阵时, C = { T 0 } C = \{T_0\} C={T0}

    • ( 4 ) (4) (4)根据上表构造状态转换矩阵,对每个 T j = ε − c l o s u r e ( m o v e ( T i , a ) ) T_j = ε-closure( move(T_i, a) ) Tj=εclosure(move(Ti,a))

      • T j ∉ C T_j\notin C Tj/C,则 C = { T 0 , T j } C = \{T_0, T_j\} C={T0,Tj}, 且 T j T_j Tj作为新状态加入到状态转换矩阵的新行中
      • T j ∈ C T_j\in C TjC,跳过
      • T j = ϕ T_j = \phi Tj=ϕ T j T_j Tj不添加新行(原因: T j T_j Tj属于无关状态中的死状态,具体见DFA的化简
    • ( 5 ) (5) (5)记最后一个状态为 T n T_n Tn,对 T 0 ∼ T n T_0 \sim T_n T0Tn进行状态重命名,并根据新状态名称重写状态转换矩阵,重写规则如下

      • 原初态 X ∈ T i 原初态X \in T_i 原初态XTi T i T_i Ti对应的新状态名就是新DFA的初态 S 0 S_0 S0
      • 原终态 Y ∈ T i 原终态Y \in T_i 原终态YTi T i T_i Ti对应的新状态名加入新DFA的终态集合 Z Z Z
      • 对矩阵中的所有 T i T_i Ti都重命名后,所得的状态转换矩阵就是确定化后的DFA状态矩阵
      • I I I表示当前状态s, I a I_a Ia表示输入字母为 a a a,矩阵 M [ s , i ] M[s,i] M[s,i]的值就是状态s下输入a的次态o
    • ( 6 ) (6) (6)根据新状态转换矩阵画状态转换图,此时的状态转换图就是确定化之后的DFA图(未化简

  • 例题 ppt3.3-35(书p50 ex3.3 书图×,看ppt图)、 ppt3.3-37
    【gif动图–NFA的确定化】

NFA2DFA

DFA的化简

在这里插入图片描述

综合题型 & 课后习题
  • 给出文法求DFA(求NFA–>转DFA–>DFA化简)
  • NFA与正规式的互换

  1. 3型文法 ↩︎ ↩︎

  2. 左线性文法的状态转换图表示 ↩︎

  3. ()、|、*、·四种运算运算规则 ↩︎

  4. 正规式等价&正规式等价变换 ↩︎

  5. 以01结尾的二进制数串: ( 0 ∣ 1 ) ∗ 01 (0|1)^*01 (0∣1)01 ↩︎

  6. 能被5整除的十进制整数: ( 1 ∣ 2 ∣ 3 ∣ 4 ∣ 5 ∣ 6 ∣ 7 ∣ 8 ∣ 9 ) ( 0 ∣ 1 ∣ 2 ∣ 3 ∣ 4 ∣ 5 ∣ 6 ∣ 7 ∣ 8 ∣ 9 ) ∗ ( 0 ∣ 5 ) (1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)^*(0|5) (1∣2∣3∣4∣5∣6∣7∣8∣9)(0∣1∣2∣3∣4∣5∣6∣7∣8∣9)(0∣5) ↩︎

  7. 包含奇数个1或奇数个0的二进制数串: ( 1 ∗ 0 ) ( 1 ∗ ∣ 0 1 ∗ 0 ) ∣ ( 0 ∗ 1 ) ( 0 ∗ ∣ 1 0 ∗ 1 ) (1^*0)(1^*|01^*0)|(0^*1)(0^*|10^*1) (10)(1∣010)(01)(0∣101)。解释:奇数个0与奇数个1的正规式类似,以求奇数个0为例,。。。。 ↩︎

  8. 英文字母组成的所有符号串,要求符号串中的字母按照字典序排列:以a~z为例: a ∗ b ∗ c ∗ . . . z ∗ a^*b^*c^*...z^* abc...z ↩︎

  9. 答案: ↩︎

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
目 录 译者序 前言 第1章 概论 1 1.1 为什么要用编译器 2 1.2 与编译器相关的程序 3 1.3 翻译步骤 5 1.4 编译器中的主要数据结构 8 1.5 编译器结构中的其他问题 10 1.6 自举与移植 12 1.7 TINY样本语言与编译器 14 1.7.1 TINY语言 15 1.7.2 TINY编译器 15 1.7.3 TM机 17 1.8 C-Minus:编译器项目的一种语言 18 练习 19 注意与参考 20 第2章 词法分析 21 2.1 扫描处理 21 2.2 正则表达式 23 2.2.1 正则表达式的定义 23 2.2.2 正则表达式的扩展 27 2.2.3 程序设计语言记号的正则表达式 29 2.3 有穷自动机 32 2.3.1 确定性有穷自动机的定义 32 2.3.2 先行、回溯和非确定性自动机 36 2.3.3 用代码实现有穷自动机 41 2.4 从正则表达式DFA 45 2.4.1 从正则表达式NFA 45 2.4.2 从NFADFA 48 2.4.3 利用子集构造模拟NFA 50 2.4.4 将DFA中的状态数最小化 51 2.5 TINY扫描程序的实现 52 2.5.1 为样本语言TINY实现一个扫描 程序 53 2.5.2 保留字与标识符 56 2.5.3 为标识符分配空间 57 2.6 利用Lex 自动生成扫描程序 57 2.6.1 正则表达式的Lex 约定 58 2.6.2 Lex输入文件的格式 59 2.6.3 使用Lex的TINY扫描程序 64 练习 65 编程练习 67 注意与参考 67 第3章 上下文无关文法及分析 69 3.1 分析过程 69 3.2 上下文无关文法 70 3.2.1 与正则表达式比较 70 3.2.2 上下文无关文法规则的说明 71 3.2.3 推导及由文法定义的语言 72 3.3 分析树与抽象语法树 77 3.3.1 分析树 77 3.3.2 抽象语法树 79 3.4 二义性 83 3.4.1 二义性文法 83 3.4.2 优先权和结合性 85 3.4.3 悬挂else问题 87 3.4.4 无关紧要的二义性 89 3.5 扩展的表示法:EBNF和语法图 89 3.5.1 EBNF表示法 89 3.5.2 语法图 91 3.6 上下文无关语言的形式特性 93 3.6.1 上下文无关语言的形式定义 93 3.6.2 文法规则和等式 94 3.6.3 乔姆斯基层次和作为上下文无关 规则的语法局限 95 3.7 TINY语言的语法 97 3.7.1 TINY的上下文无关文法 97 3.7.2 TINY编译器的语法树结构 98 练习 101 注意与参考 104 第4章 自顶向下的分析 105 4.1 使用递归下降分析算法进行自顶向下 的分析 105 4.1.1 递归下降分析的基本方法 105 4.1.2 重复和选择:使用EBNF 107 4.1.3 其他决定问题 112 4.2 LL(1)分析 113 4.2.1 LL(1)分析的基本方法 113 4.2.2 LL(1)分析与算法 114 4.2.3 消除左递归和提取左因子 117 4.2.4 在LL(1)分析中构造语法树 124 4.3 First集合和Follow集合 125 4.3.1 First 集合 125 4.3.2 Follow 集合 130 4.3.3 构造LL(1)分析表 134 4.3.4 再向前:LL(k)分析程序 135 4.4 TINY语言的递归下降分析程序 136 4.5 自顶向下分析程序中的错误校正 137 4.5.1 在递归下降分析程序中的错误 校正 138 4.5.2 在LL(1)分析程序中的错误校正 140 4.5.3 在TINY分析程序中的错误校正 141 练习 143 编程练习 146 注意与参考 148 第5章 自底向上的分析 150 5.1 自底向上分析概览 151 5.2 LR(0)项的有穷自动机与LR(0)分析 153 5.2.1 LR(0)项 153 5.2.2 项目的有穷自动机 154 5.2.3 LR(0)分析算法 157 5.3 SLR(1)分析 160 5.3.1 SLR(1)分析算法 160 5.3.2 用于分析冲突的消除二义性 规则 163 5.3.3 SLR(1)分析能力的局限性 164 5.3.4 SLR(k)文法 165 5.4 一般的LR(1)和LALR(1)分析 166 5.4.1 LR(1)项的有穷自动机 166
《编译》——复习资料,可适用于课程学习资料、期末复习资料、自主学习资料等等,复习资料共218页,内容丰富,干货十足! 主要内容包括: 一、概述 1 1.1 课程介绍 1 1.2 编译过程 3 1.3 高级语言程序简介 11 二、程序语言概论 14 2.1 程序语言的定义 14 2.2 文法的形式化定义和分类 18 2.3 文法和语言 22 2.4 语法分析树 29 三、词法分析_1 33 3.1 词法分析概述 33 3.2 词法分析程序的设计 38 3.3 正规式与自动机 41 3.3.1 正规式与正规集 41 3.3.2 确定有限自动机(DFA) 44 3.3.3 非确定有限自动机(NFA) 49 3.4 单元测试 51 四、词汇分析_2 52 4.1正则式和有限自动机的等价 52 五、词法分析_3 59 5.1 DFA的化简 59 六、词法分析_4 62 6.1 词法分析器的自动生成 62 6.2 词法分析程序实现实例 64 七、语法分析—自上而下分析_1 71 7.1 词法分析简介 71 7.2 自顶向下分析简介 73 7.3 消除左递归和回溯 76 八、语法分析—自上而下分析_2 80 8.1 LL(1)分析法 80 8.2 FIRST集和FOLLOW集的构造 82 8.3 单元测试 85 九、语法分析—自上而下分析_3 86 9.1 LL(1)分析表的构造 86 9.2 递归子程序的原理 89 9.3 单元测试 95 十、语法分析—自下而上分析_1 96 10.1 自下而上分析方法的基本思想 96 10.2 分析树与规范规约 99 10.3 符号栈的使用 103 10.4 单元测试 105 十一、语法分析—自下而上分析_2 106 11.1 算符优先文法 106 11.2 优先表构造 109 11.3 算符优先分析算法 112 10.4 单元测试 115 十二、语法分析—自下而上分析_3 116 12.1 LR分析器 116 12.2 LR分析过程 119 12.3 单元测试 132 十三、语法分析—自下而上分析_4 133 13.1 构造识别前缀的DFA 133 13.2 LR(0)项目集规范族构造 140 13.3 由DFA构造LR(0)分析表 146 13.4 单元测试 150 十六、属性文法和语法翻译制导 151 16.1 L-属性文法和自顶向下翻译 151 16.2 自下而上计算继承属性 159 十七、语义分析和中间代码产生_1 166 17.1 语义分析的任务 166 17.2 中间代码的生成 168 17.3 算术表达式和赋值语句 175 17.4 单元测试 178 十八、语义分析和中间代码产生_2 179 18.1 布尔表达式的作用和文法描述 179 18.2 做控制用布尔表达式的翻译(回填) 181 18.3 控制流语句的翻译 186 18.4 控制流语句的翻译(回填) 189 十九、代码优化_1 194 19.1 什么是代码优化 194 19.2 基本块及流图 199 19.3 单元测试 202 二十、代码优化_2 203 20.1 基本块的DAG表示及其作用 203 二十一、重要知识点 213 1. 考试内容及分数分布 213 2. 名词解释 214 3. 简答题 215 4. 结语 216
编译原理是学习计算机科学的一门基础课程,主要涉及语言的识别和转化,而正则表达式则是其中一个非常重要的工具。在编译原理中,正则表达式通常用于描述一些模式,比如关键字、标识符等。因此,掌握正则表达式的转换过程对于理解编译原理课程非常重要。 正则表达式的转换过程主要包括以下几个部分:正则表达式NFANFADFADFA最小化。其中,NFA(非确定有限状态自动机)和DFA(确定有限状态自动机)都是描述正则表达式的模型。 正则表达式NFA: 首先,正则表达式中的基本元素是字符、括号和运算符。在转换为NFA的过程中,需要设计出一些状态来描述不同的字符和运算符。 对于字符来说,我们可以为它们设计出一个状态,状态的入口边是字符,出口边为空。 对于括号和运算符来说,可以为它们设计出一些连接状态。例如在括号中的字符可以通过连接状态直接连接到后面的状态,或者通过其他运算符先连接到其他的状态再连接到后面的状态。 最后,需要定义一个起始状态和一个终止状态,起始状态与第一个字符状态相连,最后一个字符状态与终止状态相连。这样,我们就得到了一张NFA图。 NFADFA: 将一个NFA图转换成DFA图的主要目的是为了简化图结构,以便后续对文本进行识别。 首先,需要定义DFA的状态集合,每个集合都对应一个状态。因为DFA是完全确定的有限状态自动机,所以在DFA中只能有一个状态。 然后,需要将NFA图中的每个状态都映射为DFA图中的一个状态,以便对文本进行识别。当NFA图中有多个状态对应于DFA图中的同一状态时,需要将它们合并,并将它们的出口边合并成一个出口边。 DFA最小化: 最后,对DFA进行最小化处理,以便减少状态数,提高运行效率。在最小化处理时需要考虑不同状态之间的等价关系。 可以采用遍历算法,将DFA中的状态按照等价关系划分为若干个等价类,然后构造一个等价类访问表,每个表项对应一个状态集。 最小化后的DFA图是可以识别文本的,可以用于在编译器中进行文本匹配和词法分析等操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdnGuoYuying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值