上次课主要内容 正规式的简化形式与辅助定义; 记号的识别:有限自动机 NFA的定义:M =(S,∑,move,s0,F)

Slides:



Advertisements
Similar presentations
天然 養生 樂活 年貨集錦 田森館 - 艾草之家. ‧環保健康生活小常識 : 日常使用的家中日用品,包含各種各樣的化學物質,這些化學物質,有些頗具 毒性,有些雖然沒有急毒性,但暴露日久卻會造成慢性中毒,導致健康受損, 甚至致命。 環境荷爾蒙會影響人類或其他生物的生殖能力與發育,其中一類的「壬基酚 (
Advertisements

大學入學考試中心 九十六學度學科能力測驗試題 國文科 -哈利波特番外篇-
高端楼盘工程招(议) 标管理方案 成本管理中心
第三章 養分 3-4 動物如何獲取養分.
C语言程序设计 主讲教师 :张群燕 电话:
第一部分 微专题强化练.
『外食謹慎選、健康輕鬆來 上班族健康挑食小撇步』
欧洲西部 要点·疑点·考点 欧洲西部 1. 自然环境 位置:欧洲西半部,北临北冰洋,西临大西洋,南临地中海
第4章 條件判斷與迴圈 Java 2 程式設計入門與應用.
每节一经典 用系统的观点观察问题 总体设计,逐步求精 计算机科学学院 王小明 (博士/教授/博士生导师)
第一章 C语言概述 计算机公共教学部.
高澱粉蔬菜是主食 文字取材: 蘇逸晴.
计算机硕士专业基础—C语言 赵海英
<<广东省中小学生体能素质评价标准>>
第4章 JavaScript脚本语言基础 4.1 JavaScript简介 4.2 JavaScript语法基础
单元辅导(二)   词法分析与有穷自动机.
第 5 章 流程控制 (一): 條件分支.
第13章 游戏中的人工智能.
新员工职业化培训课程 主讲人 人力资源部 二零零五年六月.
编译原理与技术 课程总结.
第三章 控制结构.
Part5语法分析 授课:胡静.
程式設計實作.
Class 2 流程控制-選擇敘述與迴圈.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
编译原理与技术 词法分析(1) 2018/11/28 《编译原理与技术》讲义.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第三章 C++中的C 面向对象程序设计(C++).
编译原理 第三章 词法分析.
條件判斷指令 -if 指令 -switch 指令 迴圈指令 - for 迴圈 - while迴圈 - break、continue 指令
编译原理与技术 词法分析 (2) 2018/12/30 《编译原理与技术》讲义.
第3讲 C++程序控制结构 3.1 顺序结构 3.2 分支结构 3.3 循环结构 3.4 转向控制 3.5 综合案例分析.
第五章 语法分析——自下而上分析 自上而下分析法(Top-down) 自下而上分析法(Bottom-up) 国防科技大学计算机系602教研室.
程序的三种基本结构 if条件分支语句 switch多路开关语句 循环语句 循环嵌套 break,continue和goto语句
语法分析 本章内容 语法分析器:把词法分析生成的词法单元流翻译成语法分析树(parse tree)
陳維魁 博士 儒林圖書公司 第五章 控制結構 陳維魁 博士 儒林圖書公司.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第2章 C++流程控制语句 if 语句 switch语句 for语句 while语句 do - while语句 break语句
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
第4讲 C++程序控制结构(二) 4.1 循环结构 4.2 转向控制 4.3 综合案例分析.
第二章 词法分析4 词法分析程序实现 构造词法分析器步骤 单词的形式化描述 词法分析程序的实现.
软件测试 (四)静态测试与动态测试.
班級:財金一A 姓名:吳佩玲 學號:4990S024 指導老師:蔡享翰 老師
程式結構&語法.
第二章 词法分析3 非确定有限自动机NFA 非确定有限自动机(NFA)的定义 NFA的确定化:NFA到DFA的转换(子集法)
4 條件選擇 4.1 程式基本結構 循序式結構 選擇式結構 重複式結構 4-3
第三章 C++的语句和简单的程序设计 主要内容:
第2章 算法与C语言程序 程序 (1)数据的描述:数据的类型和组织形式(数据结构) (2)操作的描述:操作步骤(算法) 沃思指出:
第二章 Java基本语法 讲师:复凡.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
C/C++基礎程式設計班 C++: 物件的使用、參考、重載函式 講師:林業峻 CSIE, NTU 3/28, 2015.
目标 流程控制 字符串处理 C# 的类和对象 C# 访问修饰符 C# 构造函数和析构函数.
問題解決與流程圖 高慧君 台北市立南港高中 2006年12月22日.
挑戰C++程式語言 ──第9章 函數.
程序设计基础.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
第2章 Java语言基础.
多重條件選擇敘述
序偶及直角坐標系統.
数学建模示例 椅子能在不平的地面上放稳吗 问题分析 模型假设 通常 ~ 三只脚着地 放稳 ~ 四只脚着地
C语言基本语句 判断循环.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
第二章 Java基础语法 北京传智播客教育
编译原理实践 7.PL/0的词法分析程序构造.
编译原理 第一章 编译程序概述 第二章 PL/0编译程序的实现 第三章 文法和语言 第四章 词法分析 第五章 自顶向下语法分析方法
Presentation transcript:

上次课主要内容 正规式的简化形式与辅助定义; 记号的识别:有限自动机 NFA的定义:M =(S,∑,move,s0,F) 直观表示:状态转换图与状态转换矩阵 NFA识别记号:从初态到终态路径上的标记 NFA的不确定性:反复试探,大量回溯 DFA:对NFA施加两条限制,消除了不确定因素 模拟DFA的算法:算法2.1 自动机的等价:识别同一个正规集

2.4 从正规式到词法分析器 构造词法分析器的一般方法和步骤: 用正规式对模式进行描述; 为每个正规式构造一个NFA,它识别正规式所表示的正规集; 将构造的NFA转换成等价的DFA,这一过程也被称为确定化; 优化DFA,使其状态数最少,这一过程也被称为最小化; 从优化后的DFA构造词法分析器。 问题: 我们是从DFA构造词法分析器,为何不直接从正规式构造DFA,而要先构造NFA,然后转换为DFA? 原因: 机器构造需要规范的算法; 正规式→NFA:有规范的一对一的构造算法 DFA→分析器:有便于记号识别的算法

2.4.1 从正规式到NFA 算法2.2 Thompson 算法 输入 字母表∑上的正规式r 输出 接受L(r)的NFA N <1> 对ε,构造NFA N(ε)如下。其中,s0为初态,f为终态,此NFA接受{ε}; <2> 对∑上的每个字符a,构造NFA N(a)如右上,它接受{a} ; <3> 若N(p)和N(q)是正规式p和q的NFA,则 (a) 对正规式p|q,构造NFA N(p|q)如下。其中,s0为初态,f为终态,此NFA接受L(p)∪L(q);

2.4.1 从正规式到NFA(续1) (b) 对正规式pq,构造NFA N(pq)如右。其中s0为初态,f为终态,此NFA接受L(p)L(q); (c) 对正规式p*,构造NFA N(p*)如右。其中,s0为初态,f为终态,此NFA接受L(p*); <4> 对于正规式(p),使用p本身的NFA,不再构造新的NFA。 ■

2.4.1 从正规式到NFA(续2) 正规式与NFA的对应关系: 正规式 NFA ε表示集合L(ε)={ε} a表示集合L(a)={a} P|Q表示集合L(P)∪L(Q) PQ表示集合L(P)L(Q) P*表示集合(L(P))* (r) 仍然表示集合L(r)

例2.11 用Thompson算法构造正规式r=(a|b)*abb的NFA N(r) <1> 分解正规式 <2> 自下而上构造NFA 强调: 算法的构造与正规式一一对应 构造一个新的NFA最多增加两个状态 先板书后播放

2.4.2 从NFA到DFA <1> NFA识别记号的“并行”方法 例2.12 从甲地到乙地,可以乘小轿车也可以骑自行车,具体路线如右图。其中c表示乘车,b表示骑自行车。现在要求从甲地到乙地,只许乘车而不许骑自行车,该如何走? 问题抽象:识别是否有从甲到乙标记为全c的路径 试探(串行): 甲 c 2 无路可走,退回 甲 c 1 c 3 无路可走,退回 甲 c 1 c 乙 到达乙地,成功 假设有足够多的小汽车,每次均到达小汽车可能到达的全体 并行: 甲 c {1, 2} c {3, 乙} 到达乙地,成功

2.4.2 从NFA到DFA(续1) 由于并行的方法在每试探一步时,考虑了所有的下一状态转移,因此所走的每一步都是确定的。 用NFA识别记号,并不采用串行的方法(算法不易构造,复杂度高且回溯),而是采用并行的方法,核心思想是将不确定的下一状态确定化。 NFA上识别记号的确定化方法 确定化的两个步骤(回顾DFA定义) 计算下一状态转移时: <1> 消除ε 状态转移:ε-闭包(T) <2> 消除多于一个的下一状态转移:smove(S, a)

2.4.2 从NFA到DFA(续2) smove(S, a):从状态集S出发,标记为a的下一状态全体。与move(s, a)的唯一区别:用状态集取代状态 ε-闭包(T):从状态T出发,不经任何字符达到的状态全体。 定义2.6 状态集T的ε-闭包(T)是一个状态集,且满足: (1) T中所有状态属于ε-闭包(T); (2) 任何smove(ε-闭包(T),ε)属于ε-闭包(T); (3) 再无其他状态属于ε-闭包(T)。 ■ 根据定义,ε-闭包({s2})应包括: 1. s2自身 {s2} (1) 2. s4 {s2, s4} (2) 3. s5 {s2, s4, s5}(2) 算法2.4

2.4.2 从NFA到DFA(续3) 算法2.3 模拟NFA 输入 NFA N,x(eof), s0, F 输出 若N接受x,回答“yes”,否则“no” 方法 用下边的过程对x进行识别。S是一个状态的集合 S := ε-闭包({s0}); -- 所有可能初态的集合 a := nextchar; while a ≠ eof loop end loop; if then return “yes”; else return “no”; end if; ■ S:=ε-闭包(smove(S,a)); -- 所有下一状态的集合 a := nextchar; S∩F≠Φ 与算法2.1的三点区别:模拟DFA 模拟NFA 1. 开始 初态(s0) 初态集(S) 2. 下一状态转移 下一状态 下一状态集 3. 结束 s is in F S∩F≠Φ 算法2.1 算法2.5

例2.13 在NFA上识别输入序列abb和abab 2.4.2 NFA到DFA(续4) 例2.13 在NFA上识别输入序列abb和abab 识别abb: 1 计算初态集: ε-闭包({0}) ={0,1,2,4,7}, A 2 A出发经a到达:ε-闭包(smove(A,a))={3,8,6,7,1,2,4}, B 3 B出发经b到达:ε-闭包(smove(B,b))={5,9,6,7,1,2,4}, C 4 C出发经b到达:ε-闭包(smove(C,b))={5,10,6,7,1,2,4},D 5 结束且D∩{10}={10},接受。 识别的路径为:A a B b C b D 算法2.3的三个关键步骤(写在黑板上): 初态: S := ε-闭包({s0}) a := nextchar; 循环: S:=ε-闭包(smove(S,a)); -- 所有下一状态的集合 判断: S∩F≠Φ 算法2.3

A出发经a到达:ε-闭包(smove(A,a))={3,8,6,7,1,2,4} B 2.4.2 NFA到DFA(续5) 识别abab: 初态集:ε-闭包(s0)={0,1,2,4,7} A A出发经a到达:ε-闭包(smove(A,a))={3,8,6,7,1,2,4} B B出发经b到达:ε-闭包(smove(B,b))={5,9,6,7,1,2,4} C C出发经a到达:ε-闭包(smove(C,a))={3,8,6,7,1,2,4} B 识别路径为:A a B b C a B b C。 因为C∩{10}=Φ所以不接受

2.4.2 NFA到DFA(续6) <2> “子集法”构造DFA “并行”模拟NFA的弱点:每次动态计算下一状态转移的集合,效率低。 改进方法:将NFA上的全部路径均确定化并且记录下来,得到与NFA等价的DFA。 回顾从甲地到乙地的路径,它的数学模型实质上是一个NFA (左下) 。 可以找到一个等价的DFA(右下)。 它们识别的路径均是:cc ccb cbb

2.4.2 NFA到DFA(续7) 例2.14 用DFA识别cc和cbc: 甲 c {1,2} c {3,乙}, 接受 甲 c {1,2} b {3} c ?,不接受 优点: 消除了不确定性(将NFA的下一状态集合并为一个状态) 无需动态计算状态集合(针对模拟NFA的算法)

2.4.2 NFA到DFA(续8) 算法2.3 算法2.5 从NFA构造DFA(子集法) 两个数据结构:Dstates(状态),Dtran(状态转移) 输入 NFA N 输出 等价的DFA D。初态含有NFA初态,终态集是含有NFA终态的 状态集合 方法 用下述过程构造DFA : ε-闭包({s0})是Dstates仅有的状态,且尚未标记; while Dstates有尚未标记的状态T loop 标记T; for 每一个字符a -- T中向外转移边的标记 loop end loop; end loop; ■ U := ε-闭包(smove(T,a)); if U非空 then Dtran[T,a] := U; if U不在Dstates中 then U作为尚未标记的状态加入Dstates; end if; 与算法2.3比较: 记录了所有状态 与状态转移 保留此屏,构造(a|b)*abb的DFA ,然后进入下一屏 算法2.3

2.4.2 NFA到DFA(续9) 例2.15 用算法2.5构造(a|b)*abb的DFA 问题:用哪个DFA识别输入序列? ε-闭包(smove(A, a))={3,8,6,7,1,2,4}* B ε-闭包(smove(A, b))={5,6,7,1,2,4}* C ε-闭包(smove(B, a))={3,8,6,7,1,2,4} B ε-闭包(smove(B, b))={5,9,6,7,1,2,4}* D ε-闭包(smove(C, a))={3,8,6,7,1,2,4} B ε-闭包(smove(C, b))={5,6,7,1,2,4} C ε-闭包(smove(D, a))={3,8,6,7,1,2,4} B ε-闭包(smove(D, b))={5,10,6,7,1,2,4}* E ε-闭包(smove(E, a))={3,8,6,7,1,2,4} B ε-闭包(smove(E, b))={5,6,7,1,2,4} C 问题:用哪个DFA识别输入序列? 识别abb和abab: A a B b D b E 接受 A a B b D a B b D 不接受

结束(2007年3月 日)

上次课主要内容 DFA的构造 正规式-NFA:Thompson 算法(算法2.2) NFA-DFA:子集构造法 确定化的两个步骤: 消除多于一个的下一状态转移:smove(S, a) NFA的模拟算法(算法2.3)-并行方法 从NFA构造DFA(算法2.5) 其中算法2.3和算法2.5: 共同点:确定化,即ε-闭包(smove(S, a)) 区别:一条路径的确定化与全部路径的确定化 注意:深刻理解算法的实质,而不是死记几个干条文!

2.4.3 最小化DFA 正规式-NFA-DFA 引入一个“可区分”的概念: 定义2.7 对于任何两个状态t和s,若从一状态出发接受输入字符串ω,而从另一状态出发不接受ω,或者从t出发和从s出发到达不同的接受状态,则称ω对状态t和s是可区分的。 ■ 反方向思考定义2.7: 设想任何输入序列ω对s和t均是不可区分的,则说明从s出发和从t出发,分析任何输入序列ω均得到相同结果。 因此,s和t可以合并成一个状态。

输入 DFA D={S,∑,move,s0,F}。 输出 等价的D’={S’,∑,move’,s0’,F’}(D’状态数最少) 方法 执行如下步骤: 1. 初始划分Π={S-F,F1,F2,..}, 其中,Fi是F的子集,接受不同记号; 2. 应用下述过程构造新的划分Πnew: for Π的每一个组G loop 划分G,G的两个状态s和t在同一组中的充要条件是: a.(move(s,a)∈Gi∧move(t,a)∈Gi);-- Gi是Π中的组 用新划分的组替代G,形成新的划分Πnew; end loop; 3.若 Πnew=Π 则 Πfinal:=Π且转4; 否则 Π=:Πnew 且转2;

2.4.3 最小化DFA(续1) 4. 在Πfinal每个组Gi中选一个代表si’,使得D中从Gi所有状态出发的状态转移在D’中均从si’出发,D中所有转向Gi中的状态转移在D’中均转向si’。 含有D中s0的状态组G0的代表s0'称为D'的初态,D中所有含F中状态的Gj的代表sj'构成D'的终态集F'; 5. 删除死状态,即不是终态且对所有输入字符均转向其自身,或从初态不可到达的状态。 ■ D D'

2.4.3 最小化DFA(续2) 最小化DFA算法的主要步骤 初始划分:终态与非终态; 利用可区分的概念,反复分裂划分中的组Gi,直到不可再分裂; 由最终划分构造D',关键是选代表和修改状态转移; 消除可能的死状态和不可达状态。

2.4.3 最小化DFA(续3) 例2.17 用算法2.6化简DFA 1.初始化划分Π1={ABCD,E} 2.根据算法中步骤2,反复分裂划分中的组: ① ∵ m(D, b)=E ∴ Π2={ABC,D,E} ② ∵ m(B, b)=D ∴ Π3={AC,B,D,E} ③ Π3? 于是:Πfinal={AC,B,D,E} m(A,a)=B, m(A,b)=C m(B,a)=B, m(B,b)=D m(C,a)=B, m(C,b)=C m(D,a)=B, m(D,b)=E m(E,a)=B, m(E,b)=C 4.根据Πfinal构造D': ① 选代表,用A代表AC组; ② 修改状态转移: 用0、1、2、3 代替A、B、D、E: m(A,a)=B, m(A,b)=A m(B,a)=B, m(B,b)=D m(D,a)=B, m(D,b)=E m(E,a)=B, m(E,b)=A

2.4.4 由DFA构造词法分析器 <1> 表驱动型的词法分析器 其中,需要: 1. 有适当的数据结构存放DFA; 2.修改算法2.1,适应实际输入: 识别整个文件,而不是一个记号; 满足最长匹配原则。 对于输入序列: result := a + b 正确的识别:id := id + id 错误的识别: 1. 仅识别一个: id (result) 2. 不满足最长匹配:id id ...(r或re或res ... )

<2> 直接编码的词法分析器 在表驱动的词法分析器中,DFA是被动的,需要一个驱动器来模拟DFA的行为,以实现对输入序列的分析。 直接编码的词法分析器,将DFA和DFA识别输入序列的过程合并在一起,直接用程序代码模拟DFA识别输入序列的过程。 问题: 如何用程序模拟DFA识别输入序列的过程?即如何用程序模拟DFA的状态和它的状态转移? 1. 状态和状态转移与语句的对应关系 ① 初态→程序的开始; ② 终态→程序的结束(不同终态return不同记号); ③ 状态转移→分情况或者条件语句(case/if); ④ 环→循环语句(loop); ⑤ return满足最长匹配原则。

<2> 直接编码的词法分析器(续1) 2. 识别(a|b)*abb的程序框架 void main(){ char buf[]="aba#", *ptr=buf; while (*ptr!='#' ) { l0: while (*ptr=='b') ptr++; // state 0 l1: while (*ptr=='a') ptr++; // state 1 switch (*ptr) { case 'a': goto l1; case 'b': ptr++; switch (*ptr) // state 2 switch (*ptr) // state3 case 'b': goto l0; case '#': cout<<"yes"<<endl; return; default: break; } default: break; break; // 遇到非法字符 cout << "no" << endl; } // 看实例运行

2.4.5 词法分析器生成器简介(上机课再介绍) <3> 两类分析器的比较 表驱动 直接编码 分析器的速度 慢 快 程序与模式的关系 无关 有关 分析器的规模 较大 较小 适合的编写方法 工具生成 手工编写 2.4.5 词法分析器生成器简介(上机课再介绍) <1> 构造词法分析器的全过程均有算法: 正规式-NFA-DFA-最小化DFA-词法分析器(分析表) <2> LEX的基本结构 根据正规式构造的分析表+驱动器框架(不变的) <3> 利用LEX构造词法分析器的关键 ① 用LEX提供的正规式集合设计记号的模式; ② 用LEX提供的语义支持识别记号或指出输入中的错误。

2.5 本章小结 词法分析的两个重要环节:规定所有合法输入+识别合法输入 重要内容: <1> 记号、模式与单词 <1> 记号、模式与单词 <2> 记号的说明:模式的形式化描述-正规式 <3> 记号的识别:有限自动机 NFA:与正规式有对应关系,易于构造,状态数少; DFA:确定性便于记号识别,不易构造,状态数可能多; 记号识别的方法: 模拟DFA: 模拟NFA(特殊情况下):需要动态计算状态子集。

2.5 本章小结(续) <4> 从正规式到词法分析器(等价变换的过程) 正规式描述模式 由正规式构造NFA NFA的确定化(子集法:smove, ε-闭包) DFA的最小化(可区分概念) 词法分析器:表驱动(自动生成)与直接编码(手工编写)

第二章 结束(3月28日) 下次课介绍第一次上机题

算法2.4 求ε-闭包 返回 两个数据结构: 闭包U和模拟递归的stack 输入 状态集T。 输出 状态集T的ε-闭包 方法 用下边的函数计算ε-闭包 用算法计算ε-闭包({s2}): U stack 1. {s2} s2 2. {s2, s4} s4 3. {s2, s4, s5} s5 4. {s2, s4, s5} function ε-闭包(T) is begin for T中每个状态t loop end loop; while 栈不空 return U; endε-闭包; 加入t到U; push(t); pop(t); for 每个u=move(t, ε) loop end loop; 问题:试将函数直接写为递归的 if u不在U中 then 加入u到U; push(u); end if; 返回

算法2.1 模拟DFA 输入 DFA D和输入字符串x(eof)。D的初态为s0,终态集为F。 输出 若D接受x,回答“yes”,否则回答“no”。 方法 用下述过程识别x: s:=s0; ch:=nextchar; -- 初值 while ch≠eof -- 循环 loop end loop; if -- 返回 then return “yes”; else return “no”; end if; ■ s:=move(s,ch); ch:=nextchar; s is in F 算法2.3