词法分析

    科技2022-07-10  124

    参考《龙书》

    目录

    词法分析程序的设计词法分析器剔除空白和注释预读常量识别关键字和标识符 正则表达式 R E RE RE正规表达式与正规集正规文法 和 正规式正则文法构造正则式正则式构造正则文法 有穷状态自动机 F A FA FA (finite automata)有穷自动机的三种表示形式根据 F A FA FA 编写词法分析程序 有穷自动机及其与正则文法的等价性有穷自动机的形式化定义 D F A DFA DFA 的仿真算法(伪代码描述) N F A NFA NFA 的确定化算法(不带 ε ε ε 转换) ε — N F A ε—NFA εNFA(带有空转换的 F A FA FA)确定化 F A FA FA 与正则文法的转化正则文法 → F A →FA FA F A → FA→ FA 正则文法 正则式与 F A FA FA 的等价性 D F A DFA DFA 的化简 ( D F A DFA DFA 的最小化)词法分析器的自动生成模型

    词法分析程序的设计

    词法分析器

    词法分析器从输入中读取字符,并将它们组成 “词法单元对象” 。除了用于语法分析的终结符号之外,一个词法单元对象还包含属性值;词法分析器使得语法分析器不需要考虑词法单元的词素表示方式 ( 词 类 符 号 , 单 词 的 属 性 值 ) (词类符号,单词的属性值) () 词类符号供语法分析程序使用;单词自身的属性值供语义分析程序使用构成一个词法单元的输入字符序列称为词素 ( l e x e m e lexeme lexeme)

    需要识别的程序语言单词的分类:

    关键字 (保留字或基本字):if, else…标识符字面常数运算符分界符:,, :, ;…

    词法分析器的接口设计

    词法分析可作为单独一遍来实现 (多遍编译程序) 简化设计;改进编译效率 (词法分析只需要分析3型文法,而语法分析分析的是上下文无关文法);增加编译系统的可移植性 词法分析程序作为语法分析程序的子程序 (单遍编译程序) 每当语法分析需要一个新的单词符号时,就调用词法分析子程序,词法分析子程序从字符串源程序中识别出一个具有独立意义的单词,将其单词符号返给语法分析

    剔除空白和注释

    遇到 空白 (空格、制表符或换行符),注释 时不断读取输入字符,从而跳过了空白部分 注意:在错误消息中加入行号和上下文有助于定位错误。下面的代码使用 l i n e line line 统计输入中的换行符个数

    预读

    在决定向语法分析器返回哪个词法单元之前,词法分析器可能需要预先读入一些字符 例如, 词法分析器在遇到>之后必须预先读入一个字符。如果下一个字符是=,那么>就是字符序列>=的一部分,这个序列是代表>=运算符的词法单元的词素。否则>本身形成了> 运算符,词法分析器就多读了一个字符
    一个通用的预先读取输人的方法是使用输入缓冲区。词法分析器可以从缓冲区中读取一个字符,也可以把字符放回缓冲区。同时,读取一块字符要比每次读取单个字符更加高效。我们可以用一个指针来跟踪已被分析的输入部分,向缓冲区放回一个字符可以通过回移指针来实现因为通常只需预读一个字符,所以一种简单的解决方法是使用一个变量,比如 peek, 来保存下一个输入字符;当词法分析器遇到不需要预读就能识别的字符时,peek就被设置为空白符。词法分析器在寻找下一个词法单元时会跳过这个空白符。我们假定,当词法分析器返回一个词法单元时,变量peek要么保存了当前词法单元的词素后的那个字符,要么保存空白符 例如,在读入一个数字的数位或一个标识符的字符时,词法分析器会预读一个字符。它在 1 1 1 后面预读一个字符来区分 1 1 1 10 10 10, 在 t t t 后预读一个字符来区分 t t t t r u e true true

    常量

    将字符组成整数并计算它的数值的工作通常是由词法分析器完成的 因此在语法分析和翻译过程中可以将数字当作一个单元进行处理例如,输入 31 + 28 + 59 31+28+59 31+28+59 就被转换成序列 < n u m , 31 > < + > < n u m , 28 > < + > < n u m , 59 > <num, 31><+><num, 28><+><num, 59> <num,31><+><num,28><+><num,59>

    识别关键字和标识符

    识别关键字和标识符的任务也由词法分析器完成;因此,语言的文法通常把标识符当作终结符号进行处理 例如,在处理输入 c o u n t = c o u n t + i n c r e m e n t ; count = count + increment; count=count+increment; 时,词法分析器将其转换为词组单元序列 < i d , " c o u n t " > < = > < i d , " c o u n t " > < + > < i d , " i n c r e m e n t " > < ; > <id, "count"><=> <id, "count"><+><id, "increment"><;> <id,"count"><=><id,"count"><+><id,"increment"><;> 而语法分析器处理的就是终结符号序列 i d = i d + i d id=id+id id=id+id

    区分关键字和标识符

    关键字通常也满足标识符的组成规则,因此可以将关键字作为保留字。只有当一个字符串不是关键字时它才能组成一个标识符

    具体实现方法:用符号表保存字符串 (关键字和已经识别出的标识符)

    单一表示。一个字符串表可以将编译器的其余部分和表中字符串的具体表示隔离开,编译器后面的步骤可以只使用指向表中字符串的指针或引用保留字。要实现保留字,可以在初始化时在字符串表中加入保留的字符串以及它们对应的词法单元。当词法分析器读到一个可以组成标识符的字符串或词素时,它首先检查这个字符串表中是否有这个词素。如是,它就返回表中的词法单元,否则返回带有终结符号 i d id id 的词法单元;如果不存在对应的条目,那么由 i d id id 和属性值 s s s (词素) 组成的词法单元将被加入到字符串表中,并被返回

    正则表达式 R E RE RE

    正规表达式与正规集

    正规式 / 正则表达式 正规表达式(regular expression)是说明单词的模式(pattern)的一种重要的表示法(记号),是定义正规集的数学工具。我们用以描述单词符号程序设计语言的单词都能用 正规式 来定义.

    下面是正规式和它所表示的正规集的递归定义:

    设字母表为 ∑ \sum ,辅助字母表 ∑ ′ = { ∅ , ε , ∣ , • , ∗ , ( , ) } \sum'=\{\varnothing, ε,|,•,*,(,)\} ={,ε,,,,(,)} ε ε ε ∅ \varnothing 都是 ∑ \sum 上的正规式,它们所表示的正规集分别为 { ε } \{ε\} {ε} {   } \{\ \} { }任何 a ∈ ∑ a\in \sum a a a a ∑ \sum 上的一个正规式,它所表示的正规集为 { a } \{a\} {a}假定 e 1 e_1 e1 e 2 e_2 e2 都是 ∑ \sum 上的正规式,它们所表示的正规集分别为 L ( e 1 ) L(e_1) L(e1) L ( e 2 ) L(e_2) L(e2),那么, ( e 1 ) , e 1 ∣ e 2 , e 1 • e 2 , e 1 ∗ (e_1), e_1|e_2,e_1•e_2, e_1^* (e1),e1e2,e1e2,e1 也都是正规式,它们所表示的正规集分别为 L ( e 1 ) , L ( e 1 ) ∪ L ( e 2 ) , L ( e 1 ) L ( e 2 ) , ( L ( e 1 ) ) ∗ L(e_1), L(e_1)\cup L(e_2), L(e_1)L(e_2),(L(e_1))^* L(e1),L(e1)L(e2),L(e1)L(e2),(L(e1))仅由有限次使用上述三步骤而定义的表达式才是 ∑ \sum 上的正规式,仅由这些正规式所表示的集合才是 ∑ \sum 上的正规集

    其中: ∣ | 读为“或”(也有使用 + + + 代替 ∣ | 的) • • 读为“连接”,一般可省略不写 ∗ * 读为“闭包”(即,任意有限次的自重复连接) 优先顺序: ∗ * • • ∣ |

    ∑ = { a , b } \sum=\{a, b\} ={a,b} ∑ \sum 上的正规式和相应的正规集的例子有: 正规式正规集 a a a { a } \{a\} {a} a a a | b b b { a , b } \{a,b\} {a,b} a b ab ab { a b } \{ ab\} {ab} a ∗ a^* a { ε , a , a a , . . . } \{ε,a,aa,... \} {ε,a,aa,...} ( a (a (a| b ) ( a b)(a b)(a| b ) b) b) { a a , a b , b a , b b } \{ aa,ab,ba,bb\} {aa,ab,ba,bb} ( a (a (a| b ) ∗ b)^* b) { a , b } \{ a,b\} {a,b}上的任意串 ( a (a (a| b ) ∗ b)^* b) ( a a (aa (aa| b b b ) ( a bbb)(a bbb)(a| b ) ∗ b)^* b) ∑ ∗ \sum^* 上所有含有两个相继的 a a a 或三个连续的 b b b a 、 b a、b ab ( a (a (a| b ) ∗ a b b b)^*abb b)abb a b b abb abb 结尾的 a 、 b a、b ab

    ∑ = { l , d } \sum=\{l,d\} ={ld} l l l 代表字母, d d d 代表数字。正规式 r = l ( l ∣ d ) ∗ r=l(l |d)^* r=l(ld) 表示标识符

    ∑ = { d , . , e , + , − } \sum=\{d,.,e,+,-\} ={d,.,e,+,} d d d 表示 0 0 0 ~ 9 9 9 的数字。正规式 d ∗ ( . d d ∗ ∣ ε ) ( e ( + ∣ − ∣ ε ) d d ∗ ∣ ε ) d^*(.dd^*|ε)(e(+|-|ε)dd^*|ε) d(.ddε)(e(+ε)ddε) 表示无符号整数 例如: 3.6 e 2 ,     471.88 e − 1 3.6e2,\ \ \ 471.88e-1 3.6e2,   471.88e1
    若两个正规式 e 1 e_1 e1 e 2 e_2 e2 所表示的正规集相同,则说 e 1 e_1 e1 e 2 e_2 e2 等价,记为 e 1 = e 2 e_1=e_2 e1=e2 例如: e 1 = b ( a b ) ∗ , e 2 = ( b a ) ∗ b e_1= b(ab)^*, e_2 =(ba)^*b e1=b(ab),e2=(ba)b e 1 = ( a ∣ b ) ∗ , e 2 = ( a ∗ ∣ b ∗ ) ∗ e_1= (a|b)^*, e_2 =(a^*|b^*)^* e1=(ab),e2=(ab)

    r , s , t r,s,t r,s,t 为正规式,正规式服从的代数规律有:

    r ∣ s = s ∣ r r|s=s|r rs=sr 交换律 r ∣ ( s ∣ t ) = ( r ∣ s ) ∣ t r|(s|t)=(r|s)|t r(st)=(rs)t 结合律 ( r s ) t = r ( s t ) (rs)t=r(st) (rs)t=r(st) 结合律 r ( s ∣ t ) = r s ∣ r t r(s|t)=rs|rt r(st)=rsrt 分配律 ( s ∣ t ) r = s r ∣ t r (s|t)r=sr|tr (st)r=srtr ε r = r , r ε = r εr=r, rε=r εr=r,rε=r ( ε ε ε为连接运算的幺元) r ∣ r = r r|r=r rr=r ”或“的抽取律 r ∗ = ε ∣ r ∣ r r ∣ … r^*=ε|r|rr|… r=εrrr

    正规文法 和 正规式

    正规文法 即 3型文法 / 右线性文法

    正则式(正规式)与正则文法的等价性,即 正则语言可以由正则式定义,也可以由正则文法定义

    对任一正则文法,存在一个定义同一个语言的正则式对每个正则式,存在一个生成同一语言的正则文法

    正则文法构造正则式

    正则文法正则式 A → x B       B → y A→xB\ \ \ \ \ B→y AxB     By A = x y A=xy A=xy A → x A A→xA AxA| y y y A = x ∗ y A=x^*y A=xy A → x       A → y A→x\ \ \ \ \ A→y Ax     Ay A = x A=x A=x| y y y

    求下列正则文法对应的正则式 G [ S ] : S → a S ∣ a B       ① B → b C       ② C → a C ∣ a       ③ \begin{aligned} G[S]:S →aS | aB \ \ \ \ \ ① \\B→bC \ \ \ \ \ ② \\C→aC | a \ \ \ \ \ ③\end{aligned} G[S]:SaSaB     BbC     CaCa     

    从活符号 C C C 开始 由 ③ 得       C = a ∗ a 代 入 ② 得       B = b a ∗ a 代 入 ① 得       S → a S ∣ a b a ∗ a ∴       S = a ∗ a b a ∗ a \begin{aligned} 由③得\ \ \ \ \ C&=a^*a\\ 代入②得\ \ \ \ \ B&=ba^*a\\ 代入①得\ \ \ \ \ S&→aS|aba^*a\\ \therefore\ \ \ \ \ S&=a^*aba^*a\end{aligned}      C     B     S     S=aa=baaaSabaa=aabaa

    求下列正则文法对应的正则式 G [ S ] : S → b S ∣ a A ① A → a A ∣ b B ② B → a A ∣ b C ③ C → b S ∣ a A ∣ ε ④ \begin{aligned}G[S]: S&→bS|aA①\\ A&→aA|bB②\\ B&→aA|bC③\\ C&→bS|aA |ε④\end{aligned} G[S]:SABCbSaAaAbBaAbCbSaAε

    ① 、 ④ ①、 ④ C → S ∣ ε C →S | ε CSε 所以 B → a A ∣ b S ∣ b , B = S ∣ b B→aA|bS|b,B=S|b BaAbSb,B=Sb 所以 A = a A ∣ b ( S ∣ b ) = a A ∣ b S ∣ b b , A = S ∣ b b A=aA|b(S|b)=aA|bS|bb, A=S|bb A=aAb(Sb)=aAbSbb,A=Sbb 所以 S = b S ∣ a ( S ∣ b b ) = ( a ∣ b ) S ∣ a b b S=bS|a(S|bb)=(a|b)S|abb S=bSa(Sbb)=(ab)Sabb 因此 S = ( a ∣ b ) ∗ a b b S=(a|b)^*abb S=(ab)abb 即:以 a b b abb abb 结尾的 a 、 b a、b ab

    正则式构造正则文法

    首先对任意给定的正则式,生成产生式 S → γ S→\gamma Sγ S S S 是文法的开始符号) 若有规则为重写为 A → x y A→xy Axy A → x B       B → y A→xB\ \ \ \ \ B→y AxB     By A → x ∗ y A→x^*y Axy A → x A A→xA AxA| y y y A → x A→x Ax| y y y A → x       A → y A→x\ \ \ \ \ A→y Ax     Ay 不断利用上述规则做变换,直到每个产生式右部最多包含有一个终极符为止(严格意义的正则文法,可以直接对应相应的有穷状态自动机)

    R = a ( a ∣ b ) ∗ R=a(a|b)^* R=a(ab) 转换为正规文法

    G [ S ] : S → a A A → a A ∣ b A ∣ ε \begin{aligned} G[S]:S&→aA\\ A&→aA|bA| ε\end{aligned} G[S]:SAaAaAbAε

    R = ( a ∣ c ∣ b a ∣ b c ) ∗ ( b ∣ ε ) R=(a|c|ba|bc)^*(b|ε) R=(acbabc)(bε) 转换为正规文法

    α = a ∣ c ∣ b a ∣ b c α=a|c|ba|bc α=acbabc G [ S ] : S → α S ∣ b ∣ ε 即 : S → a S ∣ c S ∣ b a S ∣ b c S ∣ b ∣ ε G[S]:S→αS|b| ε\\ 即: S→aS|cS|baS|bcS|b|ε G[S]:SαSbε:SaScSbaSbcSbε进一步转化为严格意义的正则文法: S → a S ∣ c S ∣ b A ∣ b B ∣ b ∣ ε A → a S B → c S S→aS|cS|bA|bB|b|ε\\ A→aS\\ B→cS SaScSbAbBbεAaSBcS

    有穷状态自动机 F A FA FA (finite automata)

    有穷自动机作为一种识别装置,它能准确地识别正规集,即:识别正规文法所定义的语言和正规式表示的集合 有穷自动机分为两类:确定的有穷自动机( D F A DFA DFA),不确定的有穷自动机( N F A NFA NFA
    可以把 F A FA FA 看作由一个读头和一个有穷状态转换器组成: 它可以从左至右从带上一次读一个字符, 每读一个字符改变一次状态在开始读字符前, F A FA FA 处于 开始状态有一些状态指定为 终止状态当 F A FA FA 处于终止状态又准备读带右边的字符时,带上的字符串就被 F A FA FA 识别或接受,或者说,该串 ∈ L ( F A ) ∈L(FA) L(FA) (被 F A FA FA 所识别的语言) F A FA FA 定义了正则语言集合,因此对 ∑ \sum 上的任意串 w w w,能够判定它是可接受的还是不可接受的

    有穷自动机的三种表示形式

    F A FA FA 处于状态 q i q_i qi,正在读字符 a a a,而状态应转换为 q j q_j qj ,则

    状态转换函数 f : f ( q i , a ) = q j f:f (q_i, a) = q_j f:f(qi,a)=qj状态装换图,节点代表状态,弧代表转换,弧上符号代表输入字符 状态转换矩阵 M : M [ q i , a ] = q j M:M [q_i, a] = q_j M:M[qi,a]=qj

    给出识别语言 { 以 i 为 首 的 i , d 串 } \{以i为首的i,d串\} {iid} F A FA FA 的三种形式

    状态转换矩阵中,列 F F F 代表终止状态标记,对应行标记 1 表示该状态为终止状态

    例 例

    构造一个 D F A DFA DFA,它识别的语言为 { x ∣ x ∈ { 0 , 1 } ∗ , 且 当 把 x 看 成 二 进 制 数 时 , x   M O D   3 = 0 } \{x | x \in\{0,1\}^*,且当把 x 看成二进制数时,x\ MOD\ 3=0\} {xx{0,1}xx MOD 3=0}( x x x 模3与0同余)

    定义下列状态: q 0 , q 1 , q 2 q_0,q_1,q_2 q0,q1,q2:分别对应除以 3 余数为 0,1,2 的 x x x 组成的等价类 q s q_s qs: F A FA FA 的开始状态 q s q_s qs 状态下读入0时,有 x = 0 x=0 x=0,应进入状态 q 0 q_0 q0;读入1时,有 x = 1 x=1 x=1,应进入状态 q 1 q_1 q1 q 1 q_1 q1状态下有 x = 3 n + 1 x=3n+1 x=3n+1。读入0时, x ′ = 2 × ( 3 n + 1 ) = 6 n + 2 x'=2\times(3n+1)=6n+2 x=2×(3n+1)=6n+2。所以, δ ( q 1 , 0 ) = q 2 δ(q_1,0)=q_2 δ(q1,0)=q2;读入1时, x ′ = 2 × ( 3 n + 1 ) + 1 = 6 n + 3 x'=2\times(3n+1)+1=6n+3 x=2×(3n+1)+1=6n+3。所以, δ ( q 1 , 1 ) = q 0 δ(q_1,1)=q_0 δ(q1,1)=q0…依次分析可以画出下面的 D F A DFA DFA

    根据 F A FA FA 编写词法分析程序

    根据画出的(识别单词的)状态转换图构造词法分析程序,每个状态对应一段程序,完成到达此状态的工作;词法分析程序的控制程序模拟状态转换图的状态转换伪代码: Start: getch; /*读入符号*/ While (ch=' ') do getch ; /*滤掉无用的空格*/ /*每进入一次case语句,都会识别出一个单词符号*/ case char of 'a'..'z': begin While letter or digit do begin concat; getch end; /*连接字符串*/ c:=reserve; /*查保留字表 */ if c=0 then return($ID,val) /*识别到一个标识符*/ else return(c,-) end; /*识别到一个保留字*/ '0'..'9':begin /*以无符号整数为例*/ While digit do begin concat; getch end; /*连接字符串*/ Return($INT, val) end; '+': Return($plus, _); '-': Return($minus, _); ')': Return($rpar, _); '<': begin /*超前搜索: 读取下一个字符,查看这一字符是否为‘=’,若是即为 ‘<=’; 是否为‘>’,若是即为‘< >’;否则为‘<’*/ end; ...... other {′$′, ′@′,?,&,^,!} error (24); /*报告源程序含有非法符号*/ END {of case} goto Start;

    有穷自动机及其与正则文法的等价性

    有穷自动机的形式化定义

    确定的有穷自动机 D F A DFA DFA (deterministic finite automata)

    D F A DFA DFA 是一个五元组: M = ( K , Σ , f , S , Z ) M=(K,Σ,f,S,Z) M=KΣfSZ

    K K K:状态的有穷非空集 (对应文法中的 V N V_N VN) Σ Σ Σ:有穷输入字母表 (对应文法中的 V T V_T VT) f f f K × Σ K× Σ K×Σ K K K 的一个映射(是单值函数) (对应文法中的 P P P) S ∈ K S∈K SK 是开始状态 (对应文法中的 S S S) Z ⊆ K Z\subseteq K ZK 是终止状态集

    不确定的有穷自动机 N F A NFA NFA (nondeterministic finite automata)

    N F A NFA NFA 是一个五元组: M = ( K , Σ , f , S , Z ) M=(K,Σ,f,S,Z) M=KΣfSZ

    K K K:状态的有穷非空集 (对应文法中的 V N V_N VN) Σ Σ Σ:有穷输入字母表 (对应文法中的 V T V_T VT) f f f K × Σ K× Σ K×Σ K K K 的子集 (在离散数学中表示为 2 K 2^K 2K) 的一个映射 (对应文法中的 P P P) S ⊆ K S\subseteq K SK 是开始状态集 (对应文法中的 S S S) Z ⊆ K Z\subseteq K ZK 是终止状态集

    特别地,对于带空转换的 N F A NFA NFA:

    f f f K × ( Σ   ∪   { ε } ) K×( Σ\ \cup\ \{ε\}) K×(Σ  {ε}) K K K 的子集的一个映射

    注意: f , S f,S f,S D F A DFA DFA 不同

    D F A DFA DFA N F A NFA NFA 的两点区别

    N F A NFA NFA 可以有多个开始状态 N F A NFA NFA 的映射函数值可是多个状态或空集 ( 1 → 多   或   1 → 空 1→多\ 或\ 1→空 1  1) ( N F A NFA NFA 在任意时刻可以处于有穷多个状态)

    构造一个 D F A DFA DFA,识别语言 { x 000 y ∣ x , y ∈ { 0 , 1 } ∗ } \{x000y | x,y \in\{0,1\}^*\} {x000yx,y{0,1}}

    该语言定义的句子都会有三个连续的 0

    该语言的正则表达式为 ( 0 ∣ 1 ) ∗ 000 ( 0 ∣ 1 ) ∗ (0|1)^*000(0|1)^* (01)000(01)。可以看出, N F A NFA NFA 与正则表达式天然同构

    识别实常数

    d d d 代表数字, D F A DFA DFA 如图:

    构造一个 D F A DFA DFA,识别语言 { 0 n 1 m ∣ n , m ≥ 0 } \{0^n1^m | n,m\geq0\} {0n1mn,m0}

    解 例

    构造 N F A NFA NFA,识别语言 { x ∣ x 为 非 负 偶 整 数 , 不 允 许 0 开 头 } \{x | x为非负偶整数,不允许0开头\} {xx0}

    N F A   M NFA\ M NFA M 构造如下: 对应正规文法: S → D 1 A ∣ 2 ∣ 4 ∣ 6 ∣ 8 D 1 → 1 ∣ 2 ∣ 3 ∣ 4 ∣ 5 ∣ 6 ∣ 7 ∣ 8 ∣ 9 A → D 1 A ∣ 0 A ∣ 0 ∣ 2 ∣ 4 ∣ 6 ∣ 8 S→D_1 A | 2 | 4 | 6 | 8\\ D_1 →1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9\\ A→D_1A | 0A| 0 | 2 | 4 | 6 | 8 SD1A2468D1123456789AD1A0A02468

    定理

    对于任意两个有穷自动机 M M M M ′ M' M,如果 L ( M ) = L ( M ′ ) L(M) = L(M') L(M)=L(M),则称 M M M M ′ M' M 是等价的对任意的有穷自动机 A A A,都存在一个确定的有穷自动机 A ′ A' A,使得 L ( A ′ ) = L ( A ) L(A')= L(A) L(A)=L(A)。即: N F A NFA NFA D F A DFA DFA 都识别同一语言类, D F A DFA DFA N F A NFA NFA 的特例

    N F A NFA NFA 并不比 D F A DFA DFA 识别能力强,但有时描述起来更容易、更自然。但在化为程序时,必须使用 D F A DFA DFA

    格局运动(表示 F A FA FA 识别正则句子的过程) 设 M = { K , ∑ , f , S , Z } M = \{K,\sum,f,S,Z\} M={KfSZ} ∑ \sum 上的一个 D F A DFA DFA

    K × ∑ ∗ K\times \sum^* K×上的元素 ( q , w ) (q,w) (qw) 称为 K K K 的一个格局 ( w w w 表示待分析的串)如果 f ( q , a ) = q ’ f(q, a) = q’ f(q,a)=q,则称 D F A DFA DFA 从格局 ( q , a x ) (q, ax) (q,ax) 进入 ( q ’ , x ) (q’,x) (qx) 为一次运动。记为 ( q , a x ) ⊢ ( q ’ , x ) (q,ax)\vdash (q’,x) (qax)(qx),其中: a ∈ ∑ , x ∈ ∑ ∗ a\in\sum,x\in\sum^* a,x

    运动 ⊢ \vdash 是格局上的一个二元关系

    例 串 b d b d d bdbdd bdbdd 的识别过程 解 ( q 1 , b d b d d ) ⊢ ( q 2 , d b d d ) ⊢ ( q 2 , b d d ) ⊢ ( q 2 , d d ) ⊢ ( q 2 , d ) ⊢ ( q 2 , ε ) (q_1,bdbdd)\vdash(q_2,dbdd)\vdash(q_2,bdd)\vdash(q_2,dd)\vdash(q_2,d)\vdash(q_2,ε) (q1bdbdd(q2dbdd)(q2bdd)(q2dd)(q2d)(q2ε) ( q 1 , b d b d d ) ⊢ ∗ ( q 2 , ε ) (q_1,bdbdd)\vdash^*(q_2,ε) (q1bdbdd)(q2ε) q 2 ∈ F q_2 \in F q2F,所以 b d b d d bdbdd bdbdd 被识别。

    ( q 2 , ε ) (q_2,ε) (q2ε) 也被称为 终止格局

    F A FA FA 识别的语言

    M = ( K , Σ , f , S , Z ) M=(K,Σ,f,S,Z) M=KΣfSZ是一个 F A FA FA,如果有 ( S , w ) ⊢ ∗ ( A , ε ) , 且 A ∈ Z , w ∈ Σ ∗ (S, w) \vdash^* (A, ε),且A\in Z,w\inΣ^* (S,w)(A,ε)AZwΣ则称串 w w w 可被 M M M 识别 M M M 所识别的 Σ ∗ Σ^* Σ 上的所有串,称为 M M M 所识别的语言 F A FA FA 识别空串 如果开始状态也是终止状态,或是存在一条从初态到某个终止状态的 ε ε ε 道路,则空串可被 F A FA FA 识别

    例 构造 F A FA FA 识别由偶数个 0 0 0 和偶数个 1 1 1 组成的串 解 构造 F A FA FA 的状态转换图

    于是 F A FA FA 记为: A = ( { S , A , B , C } , { 0 , 1 } , f , S , { S } ) A=(\{S,A,B,C\},\{0,1\},f,S,\{S\}) A=({S,A,B,C},{0,1},f,S,{S}) f ( S , 0 ) = A , f ( A , 0 ) = S , f ( B , 0 ) = C , f ( C , 0 ) = B , f ( S , 1 ) = B , f ( A , 1 ) = C , f ( B , 1 ) = S , f ( C , 1 ) = A f(S,0)=A , f(A,0)=S , f(B,0)=C , f(C,0)=B ,\\ f(S,1)=B, f(A,1)=C ,f(B,1)=S, f(C,1)=A f(S,0)=A,f(A,0)=S,f(B,0)=C,f(C,0)=B,f(S,1)=B,f(A,1)=C,f(B,1)=S,f(C,1)=A

    101 101 101 能否被识别? ( S , 101 ) ⊢ ( B , 01 ) ⊢ ( C , 1 ) ⊢ ( A , ε ) , A ∉ Z (S,101) \vdash(B,01)\vdash(C,1)\vdash(A,ε), A\notin Z (S,101)(B,01)(C,1)(A,ε),A/Z因此不能被识别

    该语言直接写出文法有些困难,但是写出 F A FA FA 之后就可以很方便的构造文法: G [ S ] : S → 0 A ∣ 1 B ∣ ε A → 0 S ∣ 1 C B → 0 C ∣ 1 S C → 1 A ∣ 0 B \begin{aligned}G[S]:S&→0A|1B| ε\\ A&→0S|1C \\ B&→0C|1S \\ C&→1A|0B\end{aligned} G[S]:SABC0A1Bε0S1C0C1S1A0B

    例 构造 D F A DFA DFA 识别含有奇数个1的0、1串

    F A FA FA 的状态转换图,可得正则式 r = 0 ∗ 1 ( 0 ∣ 1 0 ∗ 1 ) ∗ r=0^*1(0|10^*1)^* r=01(0101) 或者 r = ( 0 ∣ 1 0 ∗ 1 ) ∗ 1 0 ∗ r= (0|10^*1)^*10^* r=(0101)10

    D F A DFA DFA 的仿真算法(伪代码描述)

    读入以 E O F EOF EOF 结束的符号串 x x x,按 D F A DFA DFA 的转换函数进行状态转换。如果 D F A DFA DFA 接受 x x x,返回 Y E S YES YES,否则返回 N O NO NO

    int smlt_DFA() { int S; char C; S = S0; //开始状态 C = nextchar(); while (C != EOF) { S = move(S, C); // 状态转移函数 move C = nextchar(); } if (S is in Z) return YES; else return NO; }

    N F A NFA NFA 的确定化算法(不带 ε ε ε 转换)

    思路:就像32位的寄存器,在某一时刻,虽然它的每一个位有一个状态(1或0),但这32位组合在一起也是一种状态。因此,可以考虑让 N F A NFA NFA 的一组状态对应 D F A DFA DFA 的一个状态

    已知: N F A   M 1 = ( K , Σ , f , S , F ) NFA\ M_1=(K,Σ,f,S,F) NFA M1=(KΣfSF),且 ε ∉ Σ ε\notin Σ ε/Σ。求: D F A   M 2 = ( K ′ , Σ , f ′ , S ′ , F ′ ) DFA\ M_2= (K' ,Σ,f',S',F') DFA M2=(KΣfSF)

    步骤:

    S ′ = { S 1 , S 2 , . . . , S n } S'= \{S_1,S_2,...,S_n\} S={S1S2...Sn} ,其中 S i ∈ S ( i = 1 S_i \in S(i=1 SiS(i=1 ~ n ) n) n) M 1 M_1 M1 开始状态 K ′ = { S ′ } K'=\{ S'\} K={S} K ′ K' K 中的新状态 P P P,针对每个 a ∈ Σ a\inΣ aΣ,求 f ′ ( P , a ) : f'(P, a): f(P,a): Q = f ′ ( P , a ) = { f ( t , a ) ∣ t ∈ P } Q= f'(P , a)=\{ f (t, a) | t\in P \} Q=f(P,a)={f(t,a)tP} Q Q Q 不在 K ′ K' K 中,则 K ′ = K ′ ∪ { Q } K'=K'\cup\{ Q\} K=K{Q}重复第二步,直至 K ′ K' K 中所有新状态的映射都计算完标记终止状态 若 K ′ K' K 中的状态 P P P 包含 F F F 中的状态,则令 P ∈ F ′ P\in F' PF

    例 构造有穷自动机,它识别的语言为以 a b b abb abb 结尾的 a 、 b a、b ab 串,并将其确定化 ( 1 ) (1) (1) 构造 N F A NFA NFA,识别以 a b b abb abb 结尾的 a 、 b a、b ab ( 2 ) (2) (2) N F A NFA NFA 转化为 D F A DFA DFA

    G [ S ] : S → b S ∣ a X X → a X ∣ b Y Y → a X ∣ b Z Z → a X ∣ b S ∣ ε \begin{aligned}G[S]: S &→bS|aX\\ X &→aX|bY\\ Y &→aX|bZ\\ Z &→aX|bS|ε\end{aligned} G[S]SXYZbSaXaXbYaXbZaXbSε

    例 已知 N F A   M NFA\ M NFA M,求 D F A   M DFA\ M DFA M

    ε — N F A ε—NFA εNFA(带有空转换的 F A FA FA)确定化

    在构造有穷自动机时,使用空转换是很方便的。空转换就是输入字符是空串 ε ε ε 的转换。具有空转换的有穷自动机记为 ε − N F A ε-NFA εNFA ε ε ε 弧表明 N F A NFA NFA 在某状态下,不读入任何字符(不移动读头)而只改变状态(自动转换)

    例 识别语言 { a n b m c k ∣ n , m , k ≥ 0 } \{a^nb^mc^k|n,m,k\geq0\} {anbmckn,m,k0}


    因为 N F A NFA NFA D F A DFA DFA 在功能上是等价的,即接收相同的语言类。所以对任意的 ε ε ε- N F A   M NFA\ M NFA M,都存在一个确定的 D F A   M ′ DFA\ M' DFA M,使得 L ( M ) = L ( M ′ ) L(M)=L(M') L(M)=L(M),即空转换可以消除

    带有空转换的 N F A NFA NFA 的确定化算法:

    ε ε ε- N F A NFA NFA 构造等价的 D F A DFA DFA 的算法与不带有空转换的 N F A NFA NFA 确定化的算法类似,只是需要引进状态集的 ε ε ε-闭包( ε ε ε-CLOSURE)的概念,并在算法中,凡是涉及到状态集时就用与它相对应的 ε ε ε-闭包代替

    定义状态集 I I I 的空闭包: 设 I I I 是一状态集, C ( I ) C(I) C(I) 是其空闭包( ε ε ε-closure( I I I)),

    P ∈ I P\in I PI,则 P ∈ C ( I ) P\in C(I) PC(I)对于 P ∈ I P\in I PI,若 f ( P , ε ) = Q f(P,ε)=Q f(P,ε)=Q,则 Q ∈ C ( I ) Q\in C(I) QC(I) 即从 P P P 出发,经过任意条 ε ε ε 弧所能到达的任何状态 Q Q Q,都属于 C ( I ) C(I) C(I)

    在确定化算法中,状态集由它的 ε ε ε闭包代替,即可消除 ε ε ε 转换

    定理

    对任何一个具有 ε ε ε 转移的不确定的有穷自动机 N F A   N NFA\ N NFA N,一定存在一个不具有 ε ε ε 转移的不确定的有穷自动机 N F A   M NFA\ M NFA M ,使得 L ( M ) = L ( N ) L(M)=L(N) L(M)=L(N)

    C ( S ) = { S , A } C ( A ) = { A } \begin{aligned}C(S)&=\{S,A\}\\C(A)&=\{A\}\end{aligned} C(S)C(A)={S,A}={A}

    将状态集都用其空闭包表示,其余步骤与不带 ε ε ε 转换的确定算法相同

    D F A DFA DFA 如下:

    例 解 该 N F A   M NFA\ M NFA M 识别的语言是 L ( M ) = ( a ∣ b ) ∗ a b b L(M)=(a|b)^*abb L(M)=(ab)abb 转换后的 D S A   M DSA\ M DSA M 的状态图

    F A FA FA 与正则文法的转化

    定理

    对任意的正则文法 G = ( V N , V T , P , S ) G=( V_N, V_T, P, S) G=(VN,VT,P,S),都存在一个有穷自动机 A A A,使得 L ( A ) = L ( G ) L(A)=L(G) L(A)=L(G)对任一 D F A DFA DFA (或 N F A NFA NFA ),都存在一个正则文法 G G G,使 L ( G ) = L ( A ) L(G)=L(A) L(G)=L(A)文法 G G G 是正则的,当且仅当存在一个 F A FA FA,使 L ( G ) = L ( M ) L(G)=L(M) L(G)=L(M)

    正则文法 → F A →FA FA

    已知: G = ( V N , V T , P , S ) G = (V_N,V_T,P,S ) G=(VNVTPS) 是正则文法。用文法的非终极符作为状态,开始符号作为开始状态。再增加一个新的符号 R R R,作为终止状态

    注意,这里的正则文法指严格意义上的正则文法,即 a ∈ V T a\in V_T aVT 而非一个终结符号串 (因为 F A FA FA 是一个符号一个符号地读入)

    右线性文法 F A FA FA q i → a q j q_i\rightarrow aq_j qiaqj f ( q i , a ) = q j f(q_i,a)=q_j f(qi,a)=qj q i → a q_i\rightarrow a qia f ( q i , a ) = R f(q_i,a)=R f(qi,a)=R A → ε A\rightarrow ε Aε A A A 也作为终止状态

    G [ S ] : S → 0 S ∣ 1 A A → 0 A ∣ 1 S ∣ ε \begin{aligned}G[S]: S &→0S | 1A \\ A &→0A|1S | ε\end{aligned} G[S]:SA0S1A0A1Sε

    F A → FA→ FA 正则文法

    F A   M = ( Q , ∑ , δ , q 0 , F ) FA\ M=(Q,∑,δ,q_0,F) FA M=(Qδq0F)

    对于转换函数 δ ( A , t ) = B δ(A, t) =B δ(A,t)=B,可写一产生式 A → t B A→tB AtB对于可接受状态 z z z,增加一产生式 z → ε z→ε zε S = q 0 S=q_0 S=q0 V T = ∑ V_T =∑ VT=

    例 已知 L ( G ) = { x ∣ x ∈ { 0 , 1 } ∗ , 且 不 含 两 个 相 邻 的 1 } L(G)=\{x | x\in\{0,1\}^* ,且不含两个相邻的1\} L(G)={xx{0,1},1}, 求文法 G G G

    该语言属于正则语言,容易给出 F A   M FA\ M FA M,如下图所示 根据 F A   M FA\ M FA M,可以构造出如下的正则文法: G [ S ] : S → 0 S ∣ 1 A ∣ ε A → 0 S ∣ ε \begin{aligned}G[S]: S &→0S | 1A | ε\\ A &→0S | ε\end{aligned} G[S]:SA0S1Aε0Sε


    **左线性正则文法 G G G 构造 F A   M FA\ M FA M

    对于 A → a A\rightarrow a Aa 的产生式,按归约理解(自底向上),句子中的第1个字符,都是用 A → a A\rightarrow a Aa 的产生式进行归约的。对应到 F A FA FA 中, F A FA FA 从开始状态出发,读到句子的第一个字符 a a a, 将它归约为 A A A。此时引入初态 q q q, 定义为: f ( q , a ) = A f(q,a)=A f(q,a)=A对于 A → B a A\rightarrow Ba ABa 的产生式, F A FA FA 应该在状态 B B B 读入 a a a, 其状态转为 A A A, 即 f ( B , a ) = A f(B,a)=A f(B,a)=A按归约来说,如果一个输入串是文法 G G G 产生语言的合法句子,它最终应该被归约成开始符号。所以 G G G 的开始符号就是 F A   M FA\ M FA M 的终止状态

    例 构造下述文法 G [ S ] G[S] G[S] 的自动机: S → A 0 A → A 0 ∣ S 1 ∣ 0 \begin{aligned}S&→A0 \\ A&→A0 | S1 | 0 \end{aligned} SAA0A0S10该自动机是确定的吗?若不确定,则对它确定化。该自动机相应的语言是什么? 解

    确定化:

    正规式: 00 ( 0 ∣ 10 ) ∗ 00(0|10)^* 00(010)

    例 考虑 字 母 表 = { a } 字母表 =\{a\} ={a} 上的语言,该语言包含的所有串的长度要么是 2 的倍数,要么是 3 的倍数,其中包括了空串 (1)试写出该语言的正则表达式 (2)画出识别该语言的不确定有限自动机(NFA);你可直接画NFA,不必运用机械 算法从正则表达式得到 (3)画出识别该语言的确定有限自动机(DFA);你可直接画DFA,不必运用机械算法从上一小题的NFA确定化得到

    提示:串长只能是 2、3 的倍数,如: a a a a a aaaaa aaaaa 不满足要求

    (1) ( a a ) ∗ ∣ ( a a a ) ∗ (aa)^*|(aaa)^* (aa)(aaa) (2)

    (3)

    例 写出下列语言的正规式描述:所有不含子串011的01串

    先画出含有子串 011 的 DFA 对上面的自动机求补得到 DFA,即,将它的非终结状态改为终结状态,终结状态改为非终结状态,同时删去不可终止的状态 依据该 DFA 可写出正则文法: 由正则文法改造可得正则式 1 ∗ ( 0 ∣ 01 ) ∗ 1^*(0|01)^* 1(001) (如果直接用 DFA 写正则式的话,得到的不是最简的正则式)

    正则式与 F A FA FA 的等价性

    定理

    对于 Σ Σ Σ 上的 N F A   M NFA\ M NFA M,可构造一个 Σ Σ Σ 上的正则式 r r r,使 L ( r ) = L ( M ) L(r)=L(M) L(r)=L(M)对于 Σ Σ Σ 上的每个正则式 r r r,可构造 Σ Σ Σ 上的 N F A   M NFA\ M NFA M,使 L ( M ) = L ( r ) L(M)=L(r) L(M)=L(r)

    正则表达式(RE)可看做是一种“程序设计语言”,用来表示某些重要的应用,比如文本搜索应用或编译器部件

    例如:

    搜索命令 (Linux 的 grep…) 搜索系统把正则表达式转换成 D F A DFA DFA N F A NFA NFA,并在所搜索的文件上模拟这个自动机词法分析器生成器。词法分析器是编译器部件,接受本质上是正则表达式的记号形式的描述,产生一个 D F A DFA DFA,识别在输入中下一个出现的记号是哪一个

    N F A → R E NFA\rightarrow RE NFARE 的步骤(纸上作业法):

    新增两个状态 x , y x,y xy x x x 为新的初态结点,用 ε ε ε 弧连向原来所有的初态结点。 y y y 为新的终态结点,将原来所有的终态结点用 ε ε ε 弧连向 y y y。形成与 M M M 等价的 M ′ M' M N F A   M ′ NFA\ M' NFA M 中的结点按下图所示规则合并弧和去状态 反复使用这些规则,直到 N F A   M NFA\ M NFA M 中只剩下结点 x , y x,y xy。其弧上的标记即为所求的正则式 R R R(结果不唯一)

    例: 已知 F A FA FA,求正则式 解 所求正则式 r = ( a ∣ b ∣ c ( a ∣ b ) ∗ d ) ∗ r=(a | b | c (a | b)^*d )^* r=(abc(ab)d)

    例: 已知 F A FA FA,求正则式

    解 利用规则删去一个状态时,必须注意到一切与之有关的支路

    所求正则式 r = ( 0 0 ∗ 1 ) ∗ 0 0 ∗ 0 r= ( 00^*1)^*00^*0 r=(001)000 (或 : r = 0 ( 0 ∣ 10 ) ∗ 0 r= 0(0|10)^*0 r=0(010)0

    例 已知 L ( G ) = { x ∣ x ∈ { 0 , 1 } ∗ , 且 不 含 11 子 串 } L(G)=\{x | x\in\{0,1\}^* ,且不含11子串\} L(G)={xx{0,1},11} (1) 试构造识别该语言的 N F A NFA NFA (2) 求出 N F A NFA NFA 对应的正则式 (3) 给出该语言的正则文法 G G G 解 (1) (3)根据 F A   M FA\ M FA M,给出对应的正则文法(右线性): G [ S ] : S → 0 S ∣ 1 A ∣ ε A → 0 S ∣ ε \begin{aligned}G[S]: S &→0S | 1A | ε\\ A &→0S | ε\end{aligned} G[S]:SA0S1Aε0Sε

    (2)根据 N F A → R E NFA \rightarrow RE NFARE 的纸上作业法,可得 R = ( 0 ∣ 10 ) ∗ ( 1 ∣ ε ) R=(0|10)^*(1|ε) R=(010)(1ε)

    例 求下列 F A   M FA\ M FA M 所描述的语言

    解 (1) { w ∣ w ∈ { 0 , 1 } ∗ , 且 包 含 至 少 一 个 0 } \{w|w \in\{0,1\}^* ,且包含至少一个0\} {ww{0,1},0} (2) { 0 } \{0\} {0} (3) { ε } \{ε\} {ε}


    正则式 R R R 构造等价的 N F A   M NFA\ M NFA M

    我们希望能够给出一种比较“机械”的方法,使得计算机系统能够按照规则自动进行 N F A NFA NFA 与正则表达式之间的转换

    相应的等价转换方法如下:

    r = r 1 ∣ r 2 r=r_1|r_2 r=r1r2 等价的 ε ε ε- N F A NFA NFA

    其中, M 1 M_1 M1 识别 r 1 r_1 r1 M 2 M_2 M2 识别 r 2 r_2 r2

    r = r 1 r 2 r=r_1r_2 r=r1r2 等价的 ε ε ε- N F A NFA NFA r = r 1 ∗ r=r_1^* r=r1 等价的 ε ε ε- N F A NFA NFA 例 构造与 r = ( 0 ∣ 1 ) ∗ 0 ∣ ( 00 ) ∗ r=(0|1)^* 0|(00)^* r=(01)0(00) 等价的 ε ε ε- N F A NFA NFA

    正则式 R → N F A   M R \rightarrow NFA\ M RNFA M(适合手工推导)

    引进两个状态 x x x y y y x x x N F A   M NFA\ M NFA M 的开始状态, y y y 是终止状态, x x x 引向 y y y 的弧上标记为正则式 R R R,即把正则式表示成拓广转换图运用如下的三条转换规则不断加入新结点进行分解,直到每个弧的标记只是 V T V_T VT 中的一个字符或 ε ε ε 为止,所得的 N F A   M NFA\ M NFA M 即为所求

    例 已知正则式 r = b ∗ ( d ∣ a d ) ( b ∣ a d ) ∗ r=b^*(d|ad)(b|ad)^* r=b(dad)(bad),构造等价的 N F A   M NFA\ M NFA M

    例 已知正则式 r = 1 ( 01 ) ∗ ( 0 ∗ ∣ 1 ∗ ) 0 r= 1 (01)^*(0^* | 1^* ) 0 r=1(01)(01)0 ,构造等价的 N F A   M NFA\ M NFA M

    根据正则式定义语言的特征,可以使 N F A   M NFA\ M NFA M 的状态图更简化

    注意,上面的状态转换图在 ( 01 ) ∗ (01)^* (01) 的部分进行了简化

    例 语言 < 无 符 号 数 > <无符号数> <> ( a ) (a) (a) 正则式表示 d d ∗ ( . d d ∗ ∣ ε ) ( e ( + ∣ − ∣ ε ) d d ∗ ∣ ε ) dd^*(.dd^*|ε)(e(+|-|ε)dd^*|ε) dd(.ddε)(e(+ε)ddε)

    ( c ) (c) (c) F A FA FA ( d ) (d) (d) 正则文法定义 N → d N 1 N 1 → d N 1 ∣ . N 2 ∣ e N 4 ∣ ε N 2 → d N 3 N 3 → d N 3 ∣ e N 4 ∣ ε N 4 → d N 5 ∣ + N 6 ∣ − N 6 N 5 → d N 5 ∣ ε N 6 → d N 5 \begin{aligned}N&→dN_1\\ N_1&→dN_1|.N_2|eN_4| ε \\ N_2&→dN_3 \\ N_3&→dN_3|eN_4| ε \\ N_4&→dN_5|+N_6|-N_6\\ N_5&→dN_5| ε \\ N_6&→dN_5\end{aligned} NN1N2N3N4N5N6dN1dN1.N2eN4εdN3dN3eN4εdN5+N6N6dN5εdN5

    D F A DFA DFA 的化简 ( D F A DFA DFA 的最小化)

    在编译程序中,词法分析器(扫描器)的效率是很重要的。如果可能的话,应该使构造的 D F A DFA DFA 最小(即状态数最少)。实际上,对于任何给定的 D F A DFA DFA ,都有与之等价且唯一的具有最小状态数的 D F A DFA DFA 存在

    D F A   M DFA\ M DFA M 的每个可达状态存储一个输入字符子串的等价类,记为 s e t ( q ) set(q) set(q)对于同一正则语言 L L L,不同结构的自动机模型对 ∑ ∗ ∑^* 进行的等价划分不同,所得到字符子串的等价类也可能不同使 ∑ ∗ ∑^* 划分形成的等价类个数最少,即:用来存储字符子串的状态数最少的自动机,便可实现自动机的最小化

    定义

    化简的 F A FA FA:是指没有多余状态且状态中没有两个是互相等价的多余状态:从 D F A DFA DFA 的开始状态出发,任何输入串也不能到达的那个状态在 D F A DFA DFA 中,状态 s s s t t t 状态等价的条件是: (1) 一致性条件: s s s t t t 必须同时为可接受态或不可接受态 (即 f ( s , a ) , f ( t , a ) f(s,a),f(t,a) f(s,a),f(t,a) 均有定义或无定义) (2) 蔓延性条件:对于所有输入符号, s s s t t t 必须转换到等价的状态集里 ( f ( s , a ) , f ( t , a ) f(s,a),f(t,a) f(s,a),f(t,a)属于相同的状态集)如果 D F A DFA DFA 的状态 s s s t t t 不等价,则称 s s s t t t 是可区分的

    分割法将 D F A DFA DFA 最小化:将 D F A DFA DFA 的状态集分割成一些不相交的子集,使得任何不同子集的状态都是可区分的,而同一子集中的任何状态都是等价的

    D F A DFA DFA 的终态和非终态分开,形成具有两个子集的基本划分对当前已划分出的子集 I ( 1 ) , I ( 2 ) , … , I ( n ) I^{(1)} ,I^{(2)},…,I^{(n)} I(1),I(2),,I(n),看每一个 I ( i ) I^{(i)} I(i) 是否能进一步分割 如果 s , t ∈ I ( i ) s,t\in I^{(i)} s,tI(i) ,若 f ( s , a ) f(s,a) f(s,a) f ( t , a ) f(t,a) f(t,a) 属于不同子集,则 I ( i ) I^{(i)} I(i) 应进一步细分,使 s s s t t t 属于 I ( i ) I^{(i)} I(i) 的不同子集 (蔓延性); 若 s s s 有定义,而 t t t 无定义,则 s s s t t t 也是可区分的,应划分在 I ( i ) I^{(i)} I(i) 的不同子集中 (一致性)重复进行上一步中的划分,直到每个子集无法再分割对每个子集,选一个状态为代表,删去其余等价状态 例如,若 I ( i ) = { S 1 , S 2 , S 3 } I^{(i)}=\{S_1,S_2,S_3\} I(i)={S1,S2,S3},删去 S 2 , S 3 S_2,S_3 S2,S3。原 D F A   M DFA\ M DFA M 中有指向 S 2 , S 3 S_2,S_3 S2,S3 的有向边,均改为指向 S 1 S_1 S1;所有 S 2 , S 3 S_2,S_3 S2,S3 引出的弧,均已由 S 1 S_1 S1 引出 (由蔓延性保证)若子集中有初态,则该状态为新的初态;若子集中有终态,则该状态为新的终态

    例 将下图所示的 D F A   M DFA\ M DFA M 最小化。 解 先画出状态转换矩阵,便于之后的观察

    M M M 的状态按照终态和非终态分成两个子集 P 0 = ( { 1 , 2 , 3 , 4 } , { 5 , 6 , 7 } ) P_0=(\{1,2,3,4\}, \{5,6,7\}) P0=({1,2,3,4},{5,6,7})在任一含两个或以上元素的子集中寻找可区分元素。例如可以在 P 0 P_0 P0 中寻找一个子集和一个输入符号,使该子集中的状态可区分。考察: { 1 , 2 , 3 , 4 } \{1,2,3,4\} {1,2,3,4}。因为 { 1 , 2 } a = { 6 , 7 } ⊂ { 5 , 6 , 7 } , { 3 , 4 } a = { 1 , 4 } ⊂ { 1 , 2 , 3 , 4 } \{1,2\}_a=\{6,7\}\subset\{5,6,7\},\{3,4\}_a=\{1,4\} \subset\{1,2,3,4\} {1,2}a={6,7}{5,6,7},{3,4}a={1,4}{1,2,3,4},所以 P 1 = ( { 1 , 2 } , { 3 , 4 } , { 5 , 6 , 7 } ) P_1=(\{1,2\},\{3,4\},\{5,6,7\}) P1=({1,2},{3,4},{5,6,7})继续在任一含两个或以上元素的子集中寻找可区分元素。例如可以在 P 1 P_1 P1 中考察子集 { 3 , 4 } \{3,4\} {3,4}:由于 { 3 } a = { 1 } , { 4 } a = { 4 } \{3\}_a=\{1\},\{4\}_a =\{4\} {3}a={1},{4}a={4} 所以 P 2 = ( { 1 , 2 } , { 3 } , { 4 } , { 5 , 6 , 7 } ) P_2=(\{1,2\},\{3\},\{4\},\{5,6,7\}) P2=({1,2},{3},{4},{5,6,7}) P 2 P_2 P2 中考察 { 5 , 6 , 7 } \{5,6,7\} {5,6,7} : 由于 { 5 } a = { 7 } , { 6 , 7 } a = { 4 } \{5\}_a=\{7\}, \{6,7\}_a=\{4\} {5}a={7},{6,7}a={4} 所以 P 3 = ( { 1 , 2 } , { 3 } , { 4 } , { 5 } , { 6 , 7 } ) P_3=(\{1,2\},\{3\},\{4\},\{5\},\{6,7\}) P3=({1,2},{3},{4},{5},{6,7})经观察,不能再划分了令 1 1 1 代表 { 1 , 2 } \{1,2\} {1,2} 6 6 6 代表 { 6 , 7 } \{6,7\} {6,7},消去 2 2 2 7 7 7 。把原来指向 2 2 2 7 7 7 的弧,指向 1 1 1 6 6 6 。最小化的 D F A DFA DFA 如右图:


    定理

    对于有同一接受集的 F A FA FA,与之等价且具有最小状态数的 D F A DFA DFA 在同构意义下是唯一的(不考虑状态命名)可通过构造最小 D F A DFA DFA,证明正则式的等价性

    例 通过构造下列正则式的最小 D F A DFA DFA,证明它们是等价的 ( a ∣ b ) ∗ , ( a ∗ ∣ b ∗ ) ∗ , ( ( ε ∣ a ) b ∗ ) ∗ (a | b)^*,(a^* | b^*)^*,(( ε| a)b^*)^* (ab),(ab),((εa)b)

    解 它们对应的 N F A NFA NFA 分别为

    经确定化以及化简后对应的最小 D F A DFA DFA 均为:

    词法分析器的自动生成模型

    词法分析器的自动生成是指能够自动构造分析表(即状态转换矩阵)。这种词法分析程序的总控制程序是根据分析表的内容进行操作,实现状态的变迁和单词的识别自动构造词法分析器的难点在于构造分析表,对于实际的程序设计语言来说,需要借助词法分析器的自动生成工具LEX来实现LEX源程序是使用LEX语言编写的词法规则说明,经过LEX编译后形成目标文件YYLEX.C,再用C编译器对YYLEX.C进行编译,生成目标程序YYLEX.EXE,它就是词法分析程序。用YYLEX.EXE就可以将字符串源程序转换成符号串源程序
    Processed: 0.019, SQL: 8