编译原理——正规表达式与有限自动机(笔记)

一、正规式和正规集

正规集:程序设计语言的单词表、词汇集构成的集合,即是的集合。它有一定特殊性,我们称之为正规集。用来代表程序语言的单词表

正规式:可以说是正规集名称

  1. 正规集可以用正规表达式(简称正规式)表示
  2. 正规表达式是表示正规集一种方法
  3. 一个字集合是正规集当且仅当它能用正规式表示

比如,冯诺依曼构造自然数的方案,使用集合来定义(正规集),表达式来表达(正规式):

集合 表达式
\varnothing 0
\{\varnothing \} 1
\{\varnothing ,\{\varnothing \}\} 2
\{\varnothing ,\{\varnothing \},\{\varnothing,\{\varnothing \}\}\} 3

再比如:

DIM单独来说是一个正规式,也可以表达含有DIM和空集的正规集,即{DIM,\O}。

DIM,IF可以当作一个正规式,则{DIM,IF,\O}为其对应的正规集。

编译原理——正规表达式与有限自动机(笔记)_第1张图片

二、正规式和正规集的递归定义

对给定的字母表(\Sigma为字母表):

  1. 和都是\Sigma上的正规式,它们所表示的正规集为和
  2. 任何, 则是\Sigma上的正规式,它所表示的正规集为
  3. 假定e_1e_2都是\Sigma上的正规式,它们所表示的正规集为和,则:

                1)(e_1|e_2)为正规式,它所表示的正规集为L(e_1) \cup L(e_2)

                2)(e_1\cdot e_2)为正规式(做连接),它所表示的正规集为L(e_1)L(e_2)(连接)

                3)(e_1)^*为正规式,它所表示的正规集为(L(e_1))^*(闭包)

优先级:‘\cdot’比‘|’高

仅由有限次使用上述三步骤而定义的表达式才是\Sigma上的 正规式,仅由这些正规式表示的字集才是\Sigma上的正规集。


所有词法结构一般都可以用正规式描述

若两个正规式所表示的正规集相同,则称这两个正规式等价。如 b(ab)*=(ba)*b

证明

左侧:

L(b(ab)*)

        = L(b)L((ab)*)

        = L(b)(L(ab))*

        = L(b)(L(a)L(b))*

        = {b}{ab}*

        = {b}{\varepsilon,ab, abab,ababab,…}

        = {b,bab,babab,bababab,…}

右侧:

L((ba)*b)

        = L((ba)*)L(b)

        = (L(ba))*L(b)

        = (L(b)L(a))*L(b)

        = {ba}*{b}

        = {\varepsilon,ba,baba,bababa,...}{b}

        = {b,bab,babab,bababab,...}

由于:L(b(ab)*) = L( (ba)*b)

因此:b(ab)*=(ba)*b

等价成立式 

e_1|e_2 = e_2|e_1                                  交换律

e_1|(e_2|e_3) = (e_1|e_2 )|e_3                 结合律 

e_1(e_2e_3 ) =( e_1e_2 )e_3                   结合律  

e_1(e_2|e_3 ) = e_1e_2|e_1e_3                 分配律 

(e_1|e_3 )e_1 = e_2e_1|e_3e_1                 分配律

e_\varepsilon= \varepsilon e = e                         e_1e_2 != e_2e_1

三、有限自动机(Finite Automata)

确定与非确定统称为有限自动机。

1.确定有限自动机(DFA,Deterministic Finite Automata)

对状态图进行形式化,则可以下定义:

确定有限自动机 (DFA) M 是一个五元式

此处M是指其DFA实例: DFA M

M=(S, \Sigma, f, S_0 , F),其中:

        1.S:有穷状态集,即包含起点重点在内的,各个状态

        2.\Sigma:输入字母表(有穷),即状态改变的条件

        3.f:状态转换函数,为 S\times \Sigma \rightarrow S单值部分映射,即由A状态到B状态的改变

                f(s,a) = s’ 表示:当现行状态为s ,输入字符为a时,将状态转换到下一状态s’,s’称为s的一个后继状态

        4.S_0\in S:是唯一的一个初态,即起点唯一

        5.F\subseteq S终态集(可空),即最终状态,不唯一。

比如

DFA M=({0,1,2,3},{a,b},f,0,{3}),

其中,f 定义如下:

f(0,a) = 1,   f(0,b) = 2

f(1,a) = 3,    f(1,b) = 2

f(2,a) = 1,    f(2,b) = 3

f(3,a) = 3,    f(3,b) = 3

编译原理——正规表达式与有限自动机(笔记)_第2张图片

如上图所示,DFA 可以表示为状态转换图

  • 假定 DFA M含有m个状态n个输入字符
  • 这个图含有m个状态结点,每个结点顶多含有 n 条箭弧射出,且每条箭弧用 Σ 上的不同的输入字符来作标记

对于Σ * 中的任何字\alpha,若存在一条从初态到某一终态的道路,且这条路上所有弧上的标记符连接成的字等于\alpha,则称\alpha为DFA M 所识别(接收)

DFA M 所识别的的全体记为 L(M)


换言之,从初态到终态的字符,构成了一个字(一个字符也可以定义为一个字)。而所有的初态到终态可形成的字的集合就是字符集。

字与字的组合(或者单个字)可以作为一个正规式,其所代表的就是正规集。

2.非确定有限自动机 (NFA,Nondeterministic Finite Automata)

一个非确定有限自动机 (NFA) M

是一个五元式 M=(S, \Sigma, f, S_0 , F) ,其中:

1.S: 有穷状态集

2.\Sigma:输入字母表(有穷)

3.f: 状态转换函数S\times \Sigma ^{* \to} 2^S为的部分映射

4.S_0\subseteq S :是非空的初态集

5F\subseteq S :终态集 ( 可空 )

对于\Sigma * 中的任何字\alpha,若存在一条从初态 到某一终态的道路,且这条路上所有弧上 的标记字连接成的字等于\alpha ( 忽略那些标记为\varepsilon的弧 ) ,则称\alpha为 NFA M 所识别 ( 接 收 )

NFA M 所识别的字的全体记为 L(M)

 NFA示例:

编译原理——正规表达式与有限自动机(笔记)_第3张图片

3.区别

 编译原理——正规表达式与有限自动机(笔记)_第4张图片编译原理——正规表达式与有限自动机(笔记)_第5张图片

DFA

  • 如有后继状态,则其后继状态是唯一
  • 只有一个初态
  • 弧上标记仅能为长度为1的字或单个字符
  • 易于程序实现

NFA

  • 给定当前状态,其后继状态不是唯一的。
  • 可有多个初态。
  • 弧上的标记可以是字符、字,还可以是正规式。
  • 同一个字可以出现在同状态的多条弧
  • 易于人工设计

 DFA是NFA的特例

4.NFA与DFA

定义:对于任何两个有限自动机M和M’ ,如果L(M)=L(M’),则称 M 与 M’ 等价

自动机理论中一个重要的结论:判定两个自动机等价性的算法是存在的

对于每个NFA M 存在一个DFA M’,使得L(M)=L(M’)

DFA 与 NFA 描述能力相同

5.将NFA等价转换为DFA

1.假定 NFA M=<S,\Sigma ,\delta ,S_0,F>,我们对M的状态转换图进行以下改造:

        1) 引进新的初态结点X和终态结点Y,X,Y\notinS,从X到S_0中任意状态结点连一条\varepsilon箭弧,从F中任意状态结点连一条\varepsilon箭弧到 Y 。

(即,我们给一个NFA M多个初态前加了一个状态,使得其有唯一初态,末态同理)

编译原理——正规表达式与有限自动机(笔记)_第6张图片

        2) 对M的状态转换图进一步施行替换,其中k是新引入的状态。

(即,我们将aa,bb这样的换位下图3,4过程)

编译原理——正规表达式与有限自动机(笔记)_第7张图片

                替换方法 

编译原理——正规表达式与有限自动机(笔记)_第8张图片

编译原理——正规表达式与有限自动机(笔记)_第9张图片


通过上述过程,逐步把这个图转变为每条弧只标记为\Sigma上的 一个字符或\varepsilon

最后得到一个 NFA M’ , 显然 L(M’)=L(M)


 2.接着我们再把把上述 NFA 确定化——采用子集法

概念

I 是的状态集的一个子集,定义 I\varepsilon - 闭包,\varepsilon - closure(I) 为 :   

        i) 若 s\inI ,则 s\in \varepsilon-closure(I) ;

        ii) 若 s\inI ,则从 s 出发经过任意条\varepsilon弧而能到达的任 何状态 s’ 都属于\varepsilon -closure(I) 即 

         \varepsilon-closure(I)=I\cup{s’| 从某个 s‘| 出发经过任意条\varepsilon弧 能到达 s’


        设 \alpha\Sigma中的一个字符,定义

I_a= \varepsilon-closure(J)

        其中, J 为 I 中的某个状态出发经过一条 \alpha 弧而到达的状态集合。 

比如

编译原理——正规表达式与有限自动机(笔记)_第10张图片

\varepsilon-closure({1}) = {1 , 2} = I(从1出发,看与它距离一个\varepsilon的状态,就为I

J = {5 , 4 , 3}(从 \varepsilon-closure({1}) 出发,需要经过一个\alpha距离的状态就是J)

I_a = \varepsilon-closure(J) = \varepsilon-closure({5 , 4 , 3}) = {5 , 4 , 3 , 6 , 2 , 7 , 8}

编译原理——正规表达式与有限自动机(笔记)_第11张图片

编译原理——正规表达式与有限自动机(笔记)_第12张图片

编译原理——正规表达式与有限自动机(笔记)_第13张图片

编译原理——正规表达式与有限自动机(笔记)_第14张图片

6.正规式与有限自动机的等价性

  1. 对任何 FA M ,都存在一个正规式 r , 使得 L(r)=L(M) 。
  2. 对任何正规式 r ,都存在一个 FA M , 使得 L(M)=L(r) 。

证明:

1.对\Sigma上任一 NFA M ,构造一个\Sigma上的正规 式 r ,使得 L(r)=L(M) 。

编译原理——正规表达式与有限自动机(笔记)_第15张图片

  • 首先,在 M 的转换图上加进两个状态 X 和 Y ,从 X 用\varepsilon弧连接到 M 的所有初态结点,从 M 的所有终态结点用\varepsilon弧连接到 Y ,从而形成一 个新的 NFA ,记为 M’ ,它只有一个初态 X 和一个终态 Y ,显然 L(M)=L(M’) 。
  • 然后,反复使用下面的一条规则,逐步消去的 所有结点,直到只剩下 X 和 Y 为止
  • 最后, X 到 Y 的弧上标记的正规式即为所 构造的正规式 r
  • 显然 L(r)=L(M)=L(M’)

替换方式即为之前的相反方向。

编译原理——正规表达式与有限自动机(笔记)_第16张图片

 注意,要保留下每一个状态。比如下图,我们将1.左上的图变换至右上的图,2.再将右上的图变为最下面的图。

编译原理——正规表达式与有限自动机(笔记)_第17张图片

证明:

2.对于\Sigma上的正规式r,构造一个 NFA M,使 L(M)=L(r),并且 M 只有一个终态,而且没有从该终态出发的箭弧

下面使用关于 r 中运算符数目的归纳法证明上述结论。

1)若 r 具有零个运算符,则 r=\varepsilon 或 r=\varnothing 或 r=a ,其中 a\in \Sigma 。此时下图所示的三个有限自动机显然符合上述要求。

左:识别\varepsilonM_i

中:识别空

右:长度为1的字符

 2)假设结论对于少于 k(k\geq1) 个运算符的正规式成立。当 r 中含有 k 个运算符时, r 有三种情形:

情形 1 : r =r_1|r_2

r_1r_2中运算符个数少于k 。从而,由归纳假设,对 r_i 存在Mi=<S_i,\Sigma _i, \delta _i,q_i,\{f_i\}>,使得 L(M_i) = L(r_i), 并且 M_i 没有从终态出发的箭弧( i=1,2 )。 不妨设 S_i\cap S_2=\varnothing ,在 S_1\cup S_2 中加入两个新 状态q_0,f_0

编译原理——正规表达式与有限自动机(笔记)_第18张图片

 情形 2 : r = r_1r_2

M_i 同情形 1(i=1,2)

编译原理——正规表达式与有限自动机(笔记)_第19张图片

 情形 2 :r = r_1^*

M_1同情形1

编译原理——正规表达式与有限自动机(笔记)_第20张图片

7.将正规表达式转换为有限自动机的算法

 1)构造\Sigma上的 NFA M’ 使得 L(V)=L(M’)

把 V 表示成

 一样的替换逻辑

 2)逐步把这个图转变为每条弧只标记为\Sigma上的 一个字符或\varepsilon,最后得到一个 NFA M’ , 显然 L(M’)=L(V)

比如:

编译原理——正规表达式与有限自动机(笔记)_第21张图片

 

四、确定有限自动机的化简

是指:对DFA M的化简 : 寻找一个状态数比 M 少的 DFA M’ ,使得 L(M)=L(M’)

假设 s 和 t 为 M 的两个状态,称 s 和 t 等价:如果从状态 s 出发能读出某个字(任意)\alpha而 停止于终态,那么同样,从 t 出发也能读出\alpha而停止于终态;反之亦然

两个状态不等价,则称它们是可区别的(存在一个\alpha,使得从状态 s 出发能读出某个字(任意)\alpha停止于终态,从 t 出发读出\alpha停止于非终态,或者反过来)

DFA M 最少化的基本思想

把 M 的状态集划分为一些不相交的子集, 使得任何两个不同子集的状态是可区别的 ,而同一子集的任何两个状态是等价的。 最后,让每个子集选出一个代表,同时消去其他状态

按照上述原则,对 DFA 的状态集合 S 进行第 一次划分,将集合分为:终态和非终态。即找到一个字,划分连个状态(比如空字)

对 M 的状态集进行划分

1 首先,把 S 划分为终态非终态两个子集 ,形成基本划分\Pi

2 假定到某个时候,\Pi已含 m 个子集,记为\Pi = \{ I^{(1)}, I^{(2)} ,...,I^{(m)}\},检查\Pi中的每个子集看是否能进一步划分:

  • 对某个I^{(i)},令I^{(1)} = \{ S_1,S_2,...,S_k\} ,若存在 一个输入字符 a 使得I_a^{(i)} 不会包含在现行\Pi的某个子集I^{(j)}中,则至少应把I^{(i)} 分为两个部分。

2.1 如何划分为两个部分:

  • 假定状态 S_1 和 S_2 经 a 弧分别到达 t_1t_2:  t_1t_2属于现行\Pi中的两个不同子集。说明有一个字 \alpha , t_1 读出 \alpha 后到达终态,而 t_2 读出\alpha后不能到达终态,或者反之。
  • 那么对于字 a\alphaS_1 读出 a\alpha 后到达终态 ,而 S_2 读出 a\alpha 不能到达终态,或者反之
  • 所以 S_1S_2 不等价
  • 将 I (i) 分成两半,使得一半含有 S_1 :,且 s 经 a 弧到达 t, 且 t 与 t_1 属于现行 \Pi 中的同一子集 \} ;另一半含有 S_1:
  •  一般地,对某个 a 和 I^{(i)} ,若 I_a^{(i)} 落入现行 \Pi 中 N 个不同子集,则应把 I^{(i)} 划分成 N 个不相交的组,使得每个组 J 的 J_a 都落入的 \Pi 同 一子集。这样构成新的划分。

编译原理——正规表达式与有限自动机(笔记)_第22张图片

3 重复上述过程,直到 \Pi 所含子集数不再增长。

4 对于上述最后划分 \Pi 中的每个子集,我们选取每个子集 I 中的一个状态代表其他状态, 则可得到化简后的 DFA M’ 。

5 若 I 含有原来的初态,则其代表为新的初态 ,若 I 含有原来的终态,则其代表为新的终态

我们使用上述算法,对下图优化:

编译原理——正规表达式与有限自动机(笔记)_第23张图片

首先把其分为两个集合:非终态和终态集合:

随后,我们判断非终态集合:识别a时,发现3不在当前子集中:

 于是将抵达1的与抵达3的分开:

在此判断第一个集合,判断识别a时,抵达状态是否在子集;判断识别b时,状态是否在子集中,发现不在:

编译原理——正规表达式与有限自动机(笔记)_第24张图片

于是将抵达2的和抵达4的分开:

 在此判断,发现非终态集合划分完毕。判断终态,发现均在子集中:

由此可以画出: 

编译原理——正规表达式与有限自动机(笔记)_第25张图片

 

 

五、词法分析器的自动产生 --LEX

编译原理——正规表达式与有限自动机(笔记)_第26张图片

 

编译原理——正规表达式与有限自动机(笔记)_第27张图片

 

编译原理——正规表达式与有限自动机(笔记)_第28张图片

编译原理——正规表达式与有限自动机(笔记)_第29张图片

编译原理——正规表达式与有限自动机(笔记)_第30张图片 

Yacc 与 Lex 快速入门

        http://www.ibm.com/developerworks/cn/linux/sdk/lex/index.html

        UNIX, LINUX

The Lex & Yacc Page

        http://dinosaur.compilertools.net/

Flex (The Fast Lexical Analyzer):

        http://flex.sourceforge.net/

        for Windows:

                http://gnuwin32.sourceforge.net/packages/flex.htm

 六、正规文法与有限自动机的等价性

对于正规文法 G 和有限自动机 M ,如果 L(G) = L(M) ,则称 G 和 M 是等价

关于正规文法和有限自动机的等价性,有以下结论:

1. 对每一个右线性正规文法 G左线性正规文法 G ,都存在一个有限自动机 (FA) M ,使得 L(M) = L(G)

2. 对每一个 FA M ,都存在一个右线性正规文法 G_R左线性正规文法 G_L ,使得 L(M) = L(G_R) = L(G_L)

例子:

右线性文法->NFA:

推导:

编译原理——正规表达式与有限自动机(笔记)_第31张图片

编译原理——正规表达式与有限自动机(笔记)_第32张图片

左线性文法->NFA 

推导:

编译原理——正规表达式与有限自动机(笔记)_第33张图片 

 编译原理——正规表达式与有限自动机(笔记)_第34张图片编译原理——正规表达式与有限自动机(笔记)_第35张图片

 

证明:

1.对每一个右线性正规文法 G 或左线性正规文法 G ,都构造一个有限自动机 (FA) M ,使得 L(M) = L(G) 。

(1) 设右线性正规文法 G = <V_T,V_N,S,P>。将 V_N 中的每一非终结符号视为状态符号, 并增加一个新的终结状态符号 ff\notin V_N 。 令 M = <V_N\cup \{f\},V_T,\delta,S,\{f\}>,其中状态转换函数\delta由以下规则定义:

                    (a)若对某个 A\in V_Na\in V_T\cup \{\varepsilon \} , P 中有产生式 A→a ,则令\delta (A,a)=f

                    (b) 对任意的 A\in V_Na\in V_T\cup \{\varepsilon \} ,设 P 中左端为 A ,右端第一符号为 a 的所有产生式为: A→aA_1|…|aA_k (不包括 A→a ), 则令\delta (A,a)={aA_1 ,…,aA_k } 。

显然,上述 M 是一个 NFA 。


(2) 设左线性正规文法  G = <V_T,V_N,S,P>。将 V_N中的每一非终结符号视为状态符号,并 增加一个初始状态符号q_0q_0\notin V_N。 令 M=M = <V_N\cup \{q_0\},V_T,\delta,q_0,\{S\}>,其中状 态转换函数\delta由以下规则定义:

                 (a) 若对某个 A\in V_Na\in V_T\cup \{\varepsilon \} ,若 P 中有产生式 A→a,则令\delta (q_0 ,a)=A 

                 (b) 对任意的   A\in V_Na\in V_T\cup \{\varepsilon \},若 P 中所有右端第一符号为 A ,第二个符号为 a 的产生式为: A_1\rightarrow A_a,...,A_k \rightarrow A_a 则令\delta (A,a)=\{A_1,...,A_k\} 。

与 (1) 类似,可以证明 L(G) = L(M)  


2.对每一个 DFA M ,都存在一个右线性正规文法 G_R 和左线性正规文法 GL , 使得 L(M) = L(G_R) = L(G_L) 。

设 DFA <S,\Sigma, \delta ,s_0,F>

(1)若 s_0\notin F ,我们令 G_R = <\Sigma ,S,s_0,P> ,其中 P 是由以下规则定义的产生式集合:

对任何 a\in \Sigma 及 A,B\inS ,若有\delta (A,a)=B ,则:

                    (a)当 B\inF 时,令 A→aB

                    (b) 当 B\inF 时,令 A→a|aB 。

对任何 w\in \Sigma ^* ,不妨设 w = a_1,...,a_k ,其中 a_i\in \Sigma (i=1,…k) 。若 s_0 \overset{+}{\Rightarrow} w ,则存在一个最左推导 :

s_0 \Rightarrow a_1A_1 \Rightarrow a_1a_2A_2 \Rightarrow ...\Rightarrow a_1...a_iA_i \Rightarrow a_1...a_i+1A_i+1\Rightarrow...a_1...a_k

因而,在 M 中有一条从 s_0 出发依次经过 A_1,...,A_{k-1} 到达终态的通路,该通路上所有箭弧的标记依次为 a_1,...,a_k 。反之亦然。所 以, w\inL(GR ) 当且仅当 w\inL(M) 。

 

(2)现在考虑 s_0\in F 的情形,

因为\delta = \{s_0,\varepsilon \} ,所以\varepsilon \in L(M) 。但\varepsilon不属于上面构造的 G_R所产生的语言 L(G_R) 。不难发现, L(G_R)=L(M)-{\varepsilon} 。

所以,我们在上述 GR 中添加新的非终结符号 s_0' , (s_0'\notin S )和产生式 s_0'\rightarrow s_0|\varepsilon ,并用 s_0' 代替 s_0作开始符号。这样修正 G_R后得到的文法 G_R' 仍是右线性正规文法,并且 L(G_R')=L(M) 。

(2) 类似于 (1) ,从 DFA M 出发可构造左线性正规文法 G_L,使得 L(G_L)=L(M) 。 最后,由 DFA 和 NFA 之间的等价性,结论 2 得证明。

 

 

小结

编译原理——正规表达式与有限自动机(笔记)_第36张图片

 

 

 

 

你可能感兴趣的:(编译原理(笔记),编译原理)