编译原理期末复习--词法分析

93 阅读5分钟
前言

ok也是很快地开始第二章的复习,这部分就会稍微有一点点地上难度了,不过依旧是洒洒水所以快速过一遍.

要点
  1. 词法分析的任务
  2. 高级语言的单词
  3. 单词识别
  4. 手动实现词法分析程序
  5. 正则表达式和有穷自动机
  6. 词法分析程序的自动生成
  7. 词法分析的错误处理
  8. 用状态转换图识别单词
  9. 正则式和有穷自动机的转换
主要任务

从左往右逐字符地扫描源程序并识别出每一个单词,并且对其编码(种别码、token值),并最后输出一串token串提交给语法分析程序如果识别过程中发现错误或无法识别报告错误.

单词分类
  1. 关键字:在语言中有特殊意义,如while int
  2. 标识符:变量名,对象名
  3. 运算符:算术运算符,逻辑运算符,关系运算符
  4. 界符:如,;(){}
  5. 常数:数字,字符串都是
种别码

每个单词在词法分析时对应的编码值.

状态转换图
组成
  1. 有限个节点,用圆圈表示,称为状态
  2. 状态之间用带箭头的弧线连接,称为边
  3. 边上的字符表示状态转移所接收的字符或字符类;同一状态出发的边,其边上标记不能相同或包含
  4. 一个初态(开始状态),用双箭头=>表示.
  5. 至少一个终态(接受状态),用双圈表示

f9e4870d279a4a09ed308d0bf8e1f92.jpg

该状态转换图表示表示符的构成规则,必须是字母开头,后跟若干个字母数字,最后以其他字符表示标识符的结束

各类符号识别的转换图和转换图的合并

c4de5f116dfd04e94cbe0a1c63bc4d6.jpg

cb80f41220ca63b21bd1747b385bf27.jpg

a9d12be2830699b01623e26b01d0c69.jpg

5976dd459d3f406835c4152d069905f.jpg

符号和符号串的集合运算
运算表示定义
U∪VU并V={s|s∈U或者s∈V}
连接UVUV={αβ|α∈U并且β∈V}
方幂VnVn=Vn-1V(n>0),V0={ε}
闭包V*V*=V0∪V1∪...∪Vn
正闭包V+V+=V*V
正则表达式的运算
  1. ε是一个正则表达式,表示正规集L(ε)={ε},即只包含空串

  2. 对任何a∈字母表,其正规集L(a)={a}

  3. 设e1,e2是字母表上的正则表达式,所表示的正规集为L(e1)L(e2)则:

    1. (e1)是正则表达式,代表L(e1)
    2. e1|e2是正则表达式,代表L(e1)∪L(e2)
    3. e1·e2,代表L(e1)L(e2)
    4. e1,代表(L(e1))* 运算顺序为先* 再 · 最后 |

若两个正则表达式的正则集相同则二者等价

有穷自动机

可以不了解其他,但是不能不懂这个

有穷自动机可以准确地识别正规集,通过构造有穷自动机可以把正则表达式编译成识别器.

DFA--确定的有穷自动机

DFA是一个由五元组定义的数学模型:M=(S,Σ,δ,s0,F)

  1. S是一个有穷状态集
  2. Σ是一个有穷输入字母表
  3. δ是一个状态转换函数,SXΣ->S的一个单值部分映射,δ(s,a)=s'(s∈S,s'∈S,a∈Σ)
  4. s0是初始状态
  5. F是接受状态集合

DFA有三种表示方式

  1. 用给定状态转移函数的方式表示
  2. 用状态转换图的方式表示,直观
  3. 用状态转换表的方式表示,更直观但是容易有空间浪费 挺好理解的就不给例子了,打累了.

DFA的状态转移函数是单值函数,即每一个状态在面临一输入字符的时候有一个确定的后继状态.

如果某字符串从DFA的初态出发能到达终态,则称该字符串被该DFA所接受.

NFA

NFA是一个由五元组定义的数学模型:M=(S,Σ,δ,S0,F)

  1. S是一个有穷状态集
  2. Σ是一个有穷输入字母表
  3. δ是一个状态转换函数,SX(Σ∪ε)->2S(表示S的幂集,即S的所有自己组成的集合)
  4. S0是初始状态,可以有多个初始状态
  5. F是接受状态集合,可以为空 和DFA的区别在于其初态不唯一,转换字符可以是空,后继节点不唯一.
NFA确定化

首先对于一个NFA必定存在一个DFA使得NFA和DFA等价

构造DFA的方法很多最重要的一种是子集法,即一个DFA的状态对应多个NFA的状态.

状态集合I的闭包记作ε_Closure(I):指集合中的状态,经过数次ε边所到达的所有状态的集合与自身的并集 Ia=ε_Closure(move(I,a)),move(I,a)指状态集合I进过a所能到达的状态集合.

确定化的步骤:

  1. 增加状态X和Y使得有唯一的初始态和结束态,再用ε连接X->原初始态,原终结态->Y
  2. 对改造后的NFA使用子集法:
    1. 构造一个k+1列的表格,k为字符表字符数
    2. 计算初始状态的闭包,填入第一行第一列
    3. 若某行状态I未填满,则对字符表每一个未填满字符a执行Ia,填入若Ia未出现在第一列,则补充在最下面.
    4. 重复3直到无新增表项.
    5. 对所有不同的状态重命名,构造DFA