编译原理-词法分析与有限自动机

文章详细介绍了正则表达式的基本概念和定义,包括正则文法与正则表达式的等价性,以及正则表达式如何通过有限自动机(DFA和NFA)进行表示和识别。词法分析器的任务是输入源程序并输出单词符号,通常基于DFA或NFA进行设计。DFA和NFA在状态转移和识别字符串上有区别,NFA更灵活但DFA更直观。文章还探讨了DFA和NFA的化简过程以及如何在词法分析阶段处理错误。
摘要由CSDN通过智能技术生成

词法分析与有限自动机

3.0正则表达式

3.0.1概念

  1. 正则表达式 是一种用来描述正则语言的更紧凑的表示方法
  2. 用正则表达式表示的语言叫做正则语言或者正则集合
    比如某个语言L = {a}{a, b} * ( {ε} ∪ ( { . , _ } {a , b} { a, b }* ) )
    利用正则表达式:
    r = a (a | b) * (ε | (. | _) (a | b) (a | b)* )
  3. 正则表达式可以由较小的正则表达式按照特定规则递归地构建 , 每个正则表达式r 定义一个语言, 记为 L (r).这个语言也是根据r的子表达式所表示的语言递归定义的.

3.0.2定义

  • ε 是一个正则表达式(RE) L (ε) = { ε }
  • 如果a ∈ ∑ , 则a是一个RE, L(a) = {a}
  • 假设r 和 s都是RE, 表示的语言分别是 L(r) 和 L (s) , 则:

r | s 是一个RE, L(r | s) = L (r) ∪ L(s)
r s是一个RE, L(rs) = L(r)L(s)
r* 是一个RE, L(r*) = (L(r))*
( r ) 是一个正则表达式 L( (r) ) = L(r)

优先级: * , 连接, |
例:
∑ = {a, b}, 则:

L(a | b) = L(a) ∪ L(b) = {a} ∪ {b} = {a, b}
L( (a | b) (a | b) ) = L(a | b) L (a | b) = {a, b} {a, b} = {aa, ab, ba, bb}

L(a*) = (L(a))* = {a}* = {ε, a, aa, aaa, .....}
L((a | b) *) = (L(a | b))* = {ε, a, b, aa, ab, ba, bb, .......} 

L(a | a* b) = {a, b, ab, aab, aaab , .....}

十进制整数
(1 | … | 9) (0 | … | 9)* | 0

八进制整数:
0 (1 | …| 7) (0 | …| 7)*

十六进制整数:
0x (1 | … | 9 | a | …| f) (0 | …| 9 | a | … | f)*



3.0.3正则文法与正则表达式等价

任何正则文法G 存在定义同一语言的正则表达式r
任何正则表达式r, 存在生成同一语言的正则文法G

3.0.4正则定义

  1. 正则定义是具有以下形式的定义序列
  • 他们给一些RE命名, 并在之后的RE 中像使用字母表中符号一样使用这些名字
    d1 -> r1
    d2 -> r2

    dn -> rn
    每个di都是一个新符号, 他们都不在字母表∑中,并且各不相同
    每个ri是字母表∑∪ {d1, d2, …di-1}上的正则表达式
C语言中的标识符正则定义
digit  -> 0 | 1 | 2 | .... | 9
letter_  -> A | B | ...| Z | a | b | ...| z | _
id -> letter_ (letter_ | dight) *
(整数或者浮点数) 无符号数的正则定义
digit -> 0 | 1 | 2 | … | 9
digits -> digit digit *
小数部分 -> .dights | ε
指数部分 -> ( E(+|-|ε)digits ) | ε
数字 -> digits 小数部分 指数部分

3.0.5有穷自动机FA

FA分为DFA(确定的有穷自动机)以及NFA(不确定的有穷自动机)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.1 词法分析器的设计

3.1.1 词法分析器的任务

  1. 功能:输入源程序,输出单词符号。

3.1.2 词法分析器的输出格式

单词是程序的基本语言单位
通常,输出的单词符号表示成二元式:(单词种类,单词符号的属性值)
单词种类:关于单词种类的整数编码。
单词符号的属性值:反应单词符号特性或特征的值。

  1. 单词的种类
    1)关键字:eg:while、if、else
    2)标识符:eg:变量名、数组名、函数名…
    3)常数:eg:80、1.23、“Hello“…
    4)运算符:eg:算术运算符、逻辑运算符、关系运算符…
    5)界限符:eg:,、:、[、]、{、}…
    除了五类单词,还包括空格符、回车符、换行符等

3.2 词法分析器的手工构造

3.2.1 确定的有限自动机

  1. 定义:一个确定的有限自动机(DFA)
    M是一个五元组:M=(S,Σ,δ,s0,F),其中:
    1)S是一个有限集,它的每一个元素称为一个状态。
    2)Σ是一个有穷字母表(不包含空),它的每个元素称为一个输入字符。
    3)δ是一个从S×Σ到S的单值部分映射。δ(s,a)=s’表示在目前状态s下输入字符为a时,将转换到下一个状态s’。s’被称为s的一个后继状态。
    4)s0∈S,s0是唯一的初态(start)
    5)F ⊆S,F是一个终态集,可以为空

  2. DFA的状态转移矩阵(转换表
    DFA可用一个二维矩阵表示,矩阵的行表示状态,列表示输入字符,矩阵元素表示δ(s,a)的值。

  3. DFA的状态转换图
    若设DFA M含有m个状态和n个输入字符,则这个图含有m个状态结点,每个结点至多有n条箭弧射出与其它的状态结点相连接,每个箭弧用Σ中的一个不同输入字符作为标记。整张图含有唯一的初态结点和若干终态结点

  4. DFA识别字符串
    1)对Σ上的任何符号串w∈Σ*,若存在一条从初态结点到某一终态结点的通路,且该通路上所有弧的标记符连接成的字符串等于w,则称w可被DFA M所识别。若M的初态结点同时又是终态结点,则空字符串ε被M所识别
    2)DFA与语言的关系:DFA M所能识别的符号串的全体记为L(M)。
    eg:设DFA M=({0,1,2,3},{a,b},δ,{3}),其中,δ定义为:
    δ(0,a)=1,δ(0,b)=2,δ(1,a)=3,δ(1,b)=2,δ(2,a)=1,δ(2,b)=3,δ(3,a)=3,δ(3,b)=3。
    在这里插入图片描述

  5. δ的递归扩展定义(递归
    对一个DFA M,其识别的语言L(M)={w|w∈Σ*,若存在Z∈F,使δ(s0,w)=Z},其中:w=ua∈Σ*,则δ(s,ε)=s,δ(s,ua)= δ(δ(s,u),a)。

3.3 有限自动机及其化简

有限自动机包括确定有限自动机和不确定有限自动机。

3.3.1 不确定有限自动机

  1. 定义:一个不确定有限自动机(NFA) M是一个五元组:M=(S,Σ,δ, S 0 S_0 S0,F),其中:
    1)S是一个有限集,它的每一个元素称为一个状态。
    2)Σ是一个有穷字母表,它的每个元素称为一个输入字符。
    3)δ是一个从S×Σ到S的子集的映射,即δ:S×Σ*→ 2 S 2^S 2S即从状态S输入Σ,所能到达的所有状态
    4) S 0 S_0 S0⊆S, S 0 S_0 S0是一个非空初态集。
    5)F ⊆S,F是一个终态集,可以为空。
  2. NFA的状态转换图
    若设NFA M含有n个状态和m个输入符号,则这个图含有n个状态结点,每个结点可射出若干箭弧与其它的状态结点相连接。对于w∈{ε}∪Σ,若δ(q0,a)={q1,q2,…,qk}(k≥0),则从q0出发,分别到q1,q2,…,qk的k条弧,弧上均标记为a。整张图含有唯一的初态结点和若干终态结点。
  3. NFA识别字符串
    1)对Σ上的任何符号串,若存在一条从某一初态结点到某一终态结点的通路,且该通路上所有弧的标记符号依次连接成的字符串等于w,则称w可被NFA M所识别。若M的某些结点同时又是终态结点,则空字符串ε被M所识别。
    2)NFA与语言的关系:Σ
    中所有可被NFA M所识别的符号串的集合记为L(M)。
  4. DFA和NFA的关系
    1)DFA是NFA的特例(确定),NFA是DFA概念的推广。
    2)NFA能识别的语言都能被一个DFA识别。
    3)DFA相对NFA的识别程序更容易实现。
    4)DFA更快复杂且精确,NFA更小简易,一个时间一个空间
    5)DFA:一个状态关于给定的输入符号只有一个转移
    NFA:一个状态关于给定的输入符号可以由任意多个转移

下图NFA与DFA等价,都是接受以abb结尾的串,NFA更加直观,DFA更容易实现
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  1. 从正则表达式到NFA
    在这里插入图片描述

NFA跟DFA的差别

NFA(非确定有限状态自动机)和DFA(确定有限状态自动机)是两种不同类型的有限状态自动机。

下面是NFA和DFA之间的主要差别:

  1. 状态转移规则:

DFA:对于每个状态和输入符号的组合,只能有一个确定的下一个状态。换句话说,DFA的状态转移是确定的。
NFA:对于每个状态和输入符号的组合,可以有多个可能的下一个状态,或者可以没有下一个状态。NFA的状态转移可以是非确定的。

  1. 空转移(ε转移):

DFA:DFA没有空转移,即它不能在不读取输入符号的情况下从一个状态转移到另一个状态。
NFA:NFA可以通过空转移(使用特殊的空输入符号 ε)从一个状态转移到另一个状态,而不读取任何输入符号。

  1. 终止状态:

DFA:对于给定的输入字符串,DFA只有一种可能的终止状态。
NFA:对于给定的输入字符串,NFA可以有多个可能的终止状态。

  1. 状态的数量:

DFA:DFA通常需要更多的状态来表示相同的语言,因为它的状态转移是确定的,不能有多个可能的转移。
NFA:相对于DFA,NFA可能需要较少的状态来表示相同的语言,因为它的状态转移可以是非确定的,允许有多个可能的转移。

总体来说,NFA相对于DFA具有更大的灵活性,但在某些情况下可能更难理解和分析。DFA则相对更简单和直观,但在某些情况下可能需要更多的状态来表示相同的语言

需要注意的是,尽管NFA和DFA有一些差异,但它们具有相等的计算能力,即它们可以表示相同的语言类。也就是说,对于任何可以由一个NFA接受的语言,都存在一个等效的DFA可以接受相同的语言。

3.3.2 不确定有限自动机的化简

  1. NFA的确定化:对任给的NFA M。都能相应地构造一个DFA M‘,使得L(M’)=L(M)。

  2. NFA的化简思路:DFA的每一个状态代表NFA状态集合的某个子集,构造的DFA使用它的状态去记录NFA读入输入符号之后可能到达的所有状态的集合。
    在这里插入图片描述
    在这里插入图片描述

  3. 闭包:若q为一初始状态s0,让a为ε,则δ(s0,a)={q1,q2,…,qk}为所有等价的状态结点构成的集合,这个集合被称为s0的ε闭包。记为ε-Closure(s0)。
    在这里插入图片描述

  4. 推广:集合I的ε-Closure(I)
    设I是NFA M的状态集的子集,定义I的ε闭包ε-Closure(I):
    1)若q∈I,则q∈ε-Closure(I)。
    2)若q∈I,则从q出发经过任意条ε弧而能到达的任何状态q’,有q’∈ ε-Closure(I)。
    在这里插入图片描述
    eg:将下图NFA M确定化。
    在这里插入图片描述

    生成DFA M的初态ε-Closure({0})={0,2,3}。重新命名生成的各个状态:{0,2,3}为0,{1}为1,{2,3}为2,{3}为3。由于{0,2,3}、{2,3}和{3}中均包含M中的终态3,因此0、2、3为M’的终态。
    在这里插入图片描述

3.3.3 确定有限自动机的化简

  1. 化简的目的:去除多余或等价的状态,降低存储代价(状态较NFA多),提高句子识别的效率

  2. 有限自动机的多余状态:从初态出发,任何可识别的输入串也不能到达的状态。

  3. 状态等价:设DFA M=(S,Σ,δ,s0,F),对s,t∈S,若对任何α∈Σ*,均有δ(s,α)∈F当且仅当δ(t,α)∈F,则称状态s和t是等价的。若状态s和t是不等价的,则称状态s和t是可区别的。

  4. DFA M的化简
    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:化简DFA
    在这里插入图片描述
    根据终态和非终态划分为两个子集:Π1={A,B,F},Π2={C,D,E,G}。
    对Π1,输入b,状态A、B经过b可到达终态,而F经过b不能到达终态。因此Π1划分为两个子集Π11={A,B}和Π12={F}。
    对Π11,输入bb,A经过bb可到达终态,而B不能,所以A和B是可区别的两个状态。
    故Π1划分为{A}、{B}、{F}三个子集。
    对Π2,输入b,划分成两个子集Π21={C,E}和Π¬22={D,G}。
    对Π21,输入a,划分成两个子集{C}和{E}。
    故Π2划分成{C}、{E}、{D,G}。
    最终状态集合划分成:{A}、{B}、{F}、{C}、{E}、{D,G}。
    在这里插入图片描述

3.3.4 识别单词的DFA

  1. 识别标识符的DFA

在这里插入图片描述

  1. 无符号数
    在这里插入图片描述

在这里插入图片描述

  1. 无符号整数
    在这里插入图片描述
  2. 注释
    在这里插入图片描述
  3. 识别token
    在这里插入图片描述

3.3.6 词法分析阶段的错误处理

  1. 词法分析阶段可检测错误的类型
  • 单词拼写错误 例:int i = 0x3G; float j =1.05e;
  • 非法字符 例:~ @
  1. 词法错误检测
    如果当前状态与当前输入符号在转换表对应项中的信息为空,而当前状态又不是终止状态,则调用错误处理程序

  2. 错误处理
    查找已扫描字符串中最后一个对应于某终态的字符

  • 如果找到了,将该字符与其前面的字符识别成一个单词。
    然后将输入指针退回到该字符,扫描器重新回到初始状
    态,继续识别下一个单词
  • 如果没找到,则确定出错,采用错误恢复策略
  1. 错误恢复策略
    最简单的错误恢复策略:“恐慌模式 (panic mode)”恢复
    :从剩余的输入中不断删除字符,直到词法分析器能够在剩余输入的开头发现一个正确的字符为止

3.3.5 化简DFA

eg:化简DFA
在这里插入图片描述

根据终态和非终态划分为两个子集:Π1={A,B,F},Π2={C,D,E,G}。

  • 对Π1,输入b,状态A、B经过b可到达终态,而F经过b不能到达终态。因此Π1划分为两个子集Π11={A,B}和Π12={F}。
  • 对Π11,输入bb,A经过bb可到达终态,而B不能,所以A和B是可区别的两个状态。
    故Π1划分为{A}、{B}、{F}三个子集。
  • 对Π2,输入b,划分成两个子集Π21={C,E}和Π¬22={D,G}。
  • 对Π21,输入a,划分成两个子集{C}和{E}。
    故Π2划分成{C}、{E}、{D,G}。
  • 最终状态集合划分成:{A}、{B}、{F}、{C}、{E}、{D,G}。
    在这里插入图片描述

3.4 正规文法、正规式和自动机之间的关系

3.4.1 正规式与正规集

  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)*。

  2. 正规式的运算
    1)种类:或”|”、连接”.”、闭包”*”。
    2)优先级:闭包>连接>或
    3)说明:仅由有限次使用这三种运算而得到的表达式才是Σ上的正规式。仅由这些正规式表示的单词集才是Σ上的正规式。

  3. 正规式的等价:若两个正规式U和V描述的正规集相同,则称正规式U和V等价。

  4. 正规式的性质:令U、V、W均为正规式:
    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.2 正规式与正规文法的关系

  1. 正规式转换为正规文法
    字母表Σ上的正规式U到正规文法G[Z]=(VN,VT,P,Z)的转换方法为:
    1)令VT=Σ,将Z→U加入到P中。
    2)对P中的每条产生式规则V→U,若U=ε或U=a(a∈Σ),则本次转换结束,否则按照如下规则反复执行,直到所有产生式规则最多含有一个终结符号为止:
    i)若U=e1|e2,则将V→U修改为V→A|B,A→e1,B→e2。
    ii)若U=e1e2,则将V→U修改为V→e1B,B→e2。
    iii)若U=(e1)*e2,则将V→U修改为V→e1V,V→e2。
  2. 正规文法转换为正规式
    1)将正规文法中的每个非终结符表示成它的一个正规式方程,获得一个联立方程组。
    2)若x=αx|β(或x=αx+β),则解为x=αβ。
    3)若x=xα|β(或x=xα+β),则解为x=βα

3.4.3 正规文法与有限自动机之间的转换

  1. 右线性文法转换为有限自动机
    设G[Z]=(VN,VT,P,Z)是一个右线性文法,其产生式规则具有形式A→aB|a|ε,由G构成相应的有限自动机M=(S,Σ,δ,s0,F)的步骤为:
    1)令s0={Z},将每个非终结符看作M中的一个状态,并增加一个终态Y且Y∉VN,令F={Y},即可得S=VN∪F。令Σ=VT。
    2)对G中每一形如A→ε的产生式规则,令δ(A,ε)=Y。
    3)对G中每一形如A→a的产生式规则,令δ(A,a)=Y。
    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中的一个状态,并增加一个初态X且X∉VN,令s0={X},即可得S=VN∪{X}。令Σ=VT。
    2)对G中每一形如A→ε的产生式规则,令δ(X,ε)=A。
    3)对G中每一形如A→a的产生式规则,令δ(X,a)=A。
    4)对G中每一形如A→Ba的产生式规则,令δ(B,a)=A。
    构造的M多数情况下为NFA。
  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中。

3.4.4正规式与有限自动机之间的转换

  1. 由正规式构造有限自动机
    设r是字母表Σ上的一个正规式,构造可识别语言L®的NFA M=(S,Σ,δ,s0,F)的方法如下:
    1)引入初始结点s0和终态结点Z,把r表示称广义转化图:
    在这里插入图片描述

    2)若r=ε,或r=Ø,或r=a∈Σ,则构造相应的三个有限自动机:
    在这里插入图片描述

否则,按照转换规则3)执行。
3)针对r中的运算,按下图转换规则对r进行分裂并加进新结点(名字不同于已有的结点),直到每条边上的标记为单个符号或ε为止。
在这里插入图片描述

4)令F={Z},S为所有新增的结点。、初始结点s0、终态结点Z组成的集合。
2. 有限自动机构造正规式
设有一个NFA M=(S,Σ,δ,s0,F),构造可识别语言L®的正规式r的方法如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

VengaZ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值