910 likes | 1.06k Views
第四章 词法分析 ( lexical analysis ). 教学目的: 理解词法分析器功能及形式;熟练掌握词法分析器设计的原理,单词的描述工具,掌握正规文法、正规式、有穷自动机的相关概念及相互转换 ; 掌握运用状态转换图进行词法分析器设计。. 教学重、难点: 正规文法、正规式、有穷自动机. 课时分配: 6 学时. 本章知识点 ( 内容 ). 词法分析程序的设计. 单词的描述工具. 有穷自动机. 正规式和有穷自动机的等价性. 正规文法和有穷自动机的等价性. 词法分析程序的自动构造. 词法分析程序的设计. 编译程序首先是在单词级别上来分析和翻译源程序的。
E N D
第四章 词法分析(lexical analysis) 教学目的:理解词法分析器功能及形式;熟练掌握词法分析器设计的原理,单词的描述工具,掌握正规文法、正规式、有穷自动机的相关概念及相互转换; 掌握运用状态转换图进行词法分析器设计。 教学重、难点:正规文法、正规式、有穷自动机 课时分配:6学时
本章知识点(内容) 词法分析程序的设计 单词的描述工具 有穷自动机 正规式和有穷自动机的等价性 正规文法和有穷自动机的等价性 词法分析程序的自动构造
词法分析程序的设计 编译程序首先是在单词级别上来分析和翻译源程序的。 词法分析的任务是:从左至右逐个字符地对源程序进行扫描,产生一个个单词符号,把作为字符串的源程序改造成为单词符号串的中间程序。因此,词法分析是编译的基础。执行词法分析的程序称为词法分析器,词法分析程序亦称为扫描器。 首页 结束
一、词法分析器功能和输出形式 功能:输入源程序,输出单词符号。 程序语言的单词符号一般分为五种: (1)关键字(保留字或基本字) (2)标识符 (3)常数(整型、实型、布尔型、文字型等) (4)运算符。 (5)界符(逗号、分号、括号、/*,*/等)。 • 词法分析器输出的单词符号常常表示为二元式: • (单词种别,单词符号的属性值)
单词种别通常用整数编码。 • 1、标识符一般统归为一种 • 2、常数则宜按类型(整、实、布尔等)分种 • 3、关键字可视其全体为一种,也可以一字一种。 • 4、运算符可采用一符一种的分法,但也可以把具有一定共性的运算符视为一种。 • 5、界符一般一符一种的分法。
如果一个种别只含有一个单词符号,那么对于这个单词符号,种别编码就完全代表它自身了。若一个种别含有多个单词符号,那麽,对于它的每个单词符号,除了给出种别编码之外,还应给出有关单词符号的属性信息。如果一个种别只含有一个单词符号,那么对于这个单词符号,种别编码就完全代表它自身了。若一个种别含有多个单词符号,那麽,对于它的每个单词符号,除了给出种别编码之外,还应给出有关单词符号的属性信息。 • 单词符号的属性是指单词符号的特征或特性。属性值则是反映特性或特征的值。 • 【例如】对于某个标识符,常将存放它有关信息的符号表项的指针作为其属性值;对于某个常数,则将存放它的常数表项的指针作为其属性值。
作为例子考虑下述C++代码段: while (i>=j) i- -; 经词法分析器处理后,它将转换为如下的单词符号序列: < while的编码, - > < ( 的编码, - > < 标识符编码 ,指向i的符号表项的指针 〉 < >=的编码 , - > <标识符编码 ,指向j的符号表项的指针> < ) , - > <标识符编码 ,指向i的符号表项的指针 > < - -编码 , - > < ; 的编码 , - >
单词种别编码 单词符号 类别编号 / 12 ( 13 ) 14 > 15 >= 16 < 17 <= 18 <> 19 := 20 ; 21 . 22 , 23 【例如】 单词符号 类别编号 标识符 1 常数 2 if 3 then 4 else 5 program 6 begin 7 end 8 + 9 - 10 * 11
词法分析器作为独立子程序 • 可使整个编译程序的结构更简沽、清晰和条理化。 • 也可以把词法分析器安排成一个子程序,每当语法分析器需要一个单词符号时就调用这个子程序。每一次调用,词法分析器就从输人串中识别出一个单词符号,把它交给语法分析器。
二、词法分析器的设计 • 1、输入、预处理 • 词法分析器工作的第一步是输入源程序文本。输入串一般放在一个缓冲区中,这个缓冲区称输入缓冲区。词法分析器的工作可以直接在这个缓冲区中进行。但在许多情况下,把输入串预处理一下,对单词符号的识别工作将是比较方便的。 • 预处理工作包括对空白符、跳格符、回车符和换行符等编辑性字符的处理,及删除注解等。我们可以设想构造一个预处理子程序,他完成上面的工作。每当词法分析器调用它时就处理出一串确定长度的输入字符,并将其装入词法分析器所指定的缓冲区中(称为扫描缓冲区)。这样分析器就可以在此缓冲区中直接进行单词符号的识别工作。
扫描缓冲区进行扫描时一般用两个指示器,一个指向当前正在识别的单词的开始位置(指向新单词的首字符),另一个用于向前搜索以寻找单词的终点。扫描缓冲区进行扫描时一般用两个指示器,一个指向当前正在识别的单词的开始位置(指向新单词的首字符),另一个用于向前搜索以寻找单词的终点。
2、 单词符号的识别 词法分析器的结构图如图1所示。 图1词法分析器
当词法分析器调用预处理子程序处理出一串输入字符串放进扫描缓冲区之后,分析器就从此缓冲区中逐一识别单词符号。当缓冲区里的字符串被处理完之后,它又调用预处理程序装入新串。当词法分析器调用预处理子程序处理出一串输入字符串放进扫描缓冲区之后,分析器就从此缓冲区中逐一识别单词符号。当缓冲区里的字符串被处理完之后,它又调用预处理程序装入新串。
单词的描述工具-正规表达式 • 单词的识别系统-有穷自动机 首页 结束
单词是程序设计语言中的基本语法符号,正规式给出了字符串的简洁结构表示,因此通常用正规式来描述字符串的词法结构,再利用正规式与有穷自动机之间的等价性,构造出能识别符合词法结构的字符串的有穷自动机,这便是词法分析器的形式化构造方法。单词是程序设计语言中的基本语法符号,正规式给出了字符串的简洁结构表示,因此通常用正规式来描述字符串的词法结构,再利用正规式与有穷自动机之间的等价性,构造出能识别符合词法结构的字符串的有穷自动机,这便是词法分析器的形式化构造方法。
单词的描述工具 1、正规文法 3型文法,又称右线性文法或正规文法(Regular Grammars),其表达式形如:A→aB或A→a。 绝大部份程序设计语言的单词都能用正规文法来描述。 首页 结束
2、正规式 所谓正规表达式就是用特定的运算符及运算对象按某种规则构造的表达式,用于描述给定3型语言的所有句子。
正规表达式与正规集 正规式和正规集的递归定义: (1)ε和φ都是Σ上的正规式,它们所表示的正规集分别为{ε}和φ (2)任何a€Σ,a是Σ上的一个正规式,它所表示的正规集为{a}; (3)假定U和V都是Σ上的正规式,它们所表示的正规集分别记为L(U)和L(V),那么,(U|V)、(U·V)和(U)*也都是正规式,它们所表示的正规集分别为L(U) UL(V),L(U)L(V)(连接积)和(L(U))*(闭包)。 仅由有限次使用上述三步骤而得到的表达式才是Σ上的正规式。仅由这些正规式所表示的字集才是Σ上的正规集。
【说明】 1、正规式的运算符,‘|’读为“或”,“·”读为“连接”,“*”读为“闭包”(即,任意有限次的自重复连接)。 2、规定算符的优先顺序为:先“*”,,次“·”.最后”|”。连接符‘ ·’一般可省略不写。
设r,s,t为正规式,则正规式服从如下的代数规则: r|s=s|r ('或'满足交换律) r|(s|t)=(r|s)|t ('或'满足结合律) r(st)=(rs)t ('连接'满足结合律) r(s|t)=rs | rt (分配律) rε=εr=r (ε是连接的恒等元素) 注意: rssr r|(st)rs | rt
【例】 令Σ={a, b}其正规式和正规集如下: 正规式 正规集 ba* a(a|b)* (a|b)*(aa|bb)(a|b)* Σ上所有以b为首后跟着任意多个a 的字 Σ上所有以a为首的字。 正规集是 所有两个相继的a或相继的b 的字
【例】 令Σ={A,B,0,1} ,则: 正规式 正规集 (A|B)(A|B|0|1)* (0|1)(0|1)* Σ上的“标识符”的全体 Σ上“数”的全体 【说明】若两个正规式所表示的正规集相同,则认为二者等价。两个等价的正规式U和V记为U=V。 例如:b(ab)*=(ba)*b等价。
正规式和正规文法之间的转换 将上的正规式r 转换成正规文法G =(VN, VT,P,S) 方法规则: (1)令S→r (2)对形如A→xy的产生式,可分解成A→xB ,B→y (3)对形如A→x*y的产生式,可分解成为A→xA, A→y (4)对形如A→x|y 的产生式,可分解为 A→x ,A→y 反复利用上述规则,直至所有产生式都符合正规文法的形式。
文法产生式 正规式 规则1 A->xB B->y A=xy 规则2 A->xA|y A=x*y 规则3 A->x A->y A=x|y 正规文法到正规式的转换规则
例:将正规文法 G[S]: S→dA|eB A→aA|b B→bB|c换成正规式。 解:步骤如下: (1)由A→aA|b ,将A转换成a*b; 由B→bB|c,将 B转换成b*c; (2)由 S→dA|eB ,将S可转换成(da*b)|(eb*c) 故所求正规式为R=(da*b)|(eb*c)
有穷自动机 文法是语言的生成系统,而自动机是语言的识别系统,有限自动机理论是描述词法规则的基本理论;一条词法规则表示为一个正规表达式(简称正规式),而一个正规式又可以化为一个确定的有限自动机,这个有限自动机就可以用来识别该词法规则定义的所有单词符号。把程序设计语言的所有词法规则都构造出相应的有限自动机,就得到了一个词法分析器。
一、有穷(有限)自动机的定义 • 有穷自动机(Finite Automata):可准确的识别 正规集。 • 分类: (1)确定的有穷自动机 (Deterministic Finite Automata ,简称DFA) (2)不确定的有穷自动机 (Nondeterministic Finite Automata ,简称NFA)
1、确定的有限自动机(DFA) 是一个五元组 M= ( Σ,S,s0, F, δ) 其中: (1) 是一个有穷字母集,它的每个元素称为一个输入字符。 (2)S是一个有限集,它的每个元素称为一个状态。 (3) δ是一个从S x 至S的单值部分映射。 δ(s,a)=S’。意味着:当现行状态为s、输入字符为a时,将转换到下一个状态S’。我们称S’为s的后继状态。 4)S0S,是唯一的初态。 5)FS,是一个终态集(可空)
DFA可以用①矩阵表示 DFA也可以②表示成一张(确定的)状态转换图。使用状态转换图是设计和实现词法分析程序的一种有效工具,是有限自动机的直观图示。在转换图中,结点代表状态,用园圈表示;状态之间用箭弧连结。箭弧上的标记(字符)代表在射出结点(即箭弧始结点)状态下可能出现的输入字符或字符类。
DFA的状态图表示 假设DFA M有m个状态,n个输入字符,则: 1、状态图有m个状态结点,每个结点顶多有n条箭弧射出和别的结点相连接,每条箭弧用上的一个不同字符作标记; 2、整张图有唯一的一个初态结点,前面冠以“=>”或“-”标记; 3、有若干终态结点,用双圆圈或“+”标记;
DFA的矩阵表示 1、行表示状态; 2、列表示输入字符; 3、矩阵元素表示相应状态行和输入字符后的新状态,即第k行a列为f(k,a)的值; 4、用“=>”标记行或第一行表示初态; 5、终态行右端标以1,非终态行右端标以0。
状态转换矩阵 • 例如,有DFA M=({0,1,2,3},{a,b},δ,0,{3}) 其中δ为 δ(0,a)=1 δ(0,b)=2 δ(1,a)=3 δ(1,b)=2 δ(2,a)=l δ(2,b)=3 δ(3,a)=3 δ(3,b)=3 它所对应的状态转换矩阵如表
一个DFA也可表示成一张(确定的) 状态转换图 问:有几个状态?几个输入字符?并画出其转换图,L(M)=?。
1 a a a 0 a 3 b b b b 2 解:有0,1,2,3共四个状态。输入字符为a,b两个。其状态转换图如下图: 这个NFA所能识别的是所有含有相继两个a或相继两个b的字。
【例】右图表示:在状态1下,若输入字符为X,则读进X,并转换到状态2。若输入字符为y,则读进Y,并转换到状态3。一张转换图只包含有限个状态(即有限个结点),其中有一个被认为是初态,而且实际上至少要有一个终态(用双圈表示)。
接受(识别) • 对于∑*中的任何字α,若存在一条从初态结点到某一终态结点的通路,且这条通路上所有弧的标记符连接成的字等于α,则称α可为DFA M所识别(读出或接受)。 • 若M的初态结点同时又是终态结点,则为 • 空字,可以为M所识别。DFA M所能识 • 别的字的全体记为L(M)。
【例】试证串abbc可被图示DFA识别 。 证明: f(S,abbc)=f(f(S,a),bbc)=f(f(A,b),bc) =f(f(A,b),c)=f(A,c)=B B为终态,得证。
说明 • 上的一个字符串集V*是正规集,当且仅当存在着一个上的确定有穷自动机M,使得V=L(M)。 • DFA的确定性表现在状态转换函数是一个单值函数,即f(k,a)唯一确定一个后继状态。
2、非确定有限自动机(NFA) 一个非确定有限自动机(NFA)是一个五元式 M= (S, Σ,δ,S0, F) 其中: (1) 是一个有穷字母集,它的每个元素称为一个输入字符。 (2) S是一个有限集,它的每个元素称为一个状态。 (3) δ是一个从S x Σ*到S的子集的映射,即 δ:S x Σ*→2s (4) S0S,是一个非空的初态集; (5)F S,是一个终态集(可空)
一个含有m个状态和n个输入字符的NFA可表示成如下的状态转换图:一个含有m个状态和n个输入字符的NFA可表示成如下的状态转换图: 该图含有m个状态结点,每个结点可射出若干条箭弧与别的结点相连接,每条弧用∑*中的一个字(不一定要不同的字而且可以是空字ε)作标记(称为输入字),整张图至少含有一个初态结点以及若干个(可以是0个)终态结点。某些结点既可以是初态结点也可以是终态结点。
说明 对于∑*中的任何一个字α,若存在一条从某一初态结点到某一终态结点的通路,且这条通路上所有弧的标记字依序连接成的字(忽略那些标记为ε的弧)等于α,则称α可为NFA M所识别(读出或接受)。 若M的某些结点既是初态结点又是终态结点,或者存在一条从某个初态结点到某个终态结点的ε通路,那么,空字ε可为M所接受。
【例】试证串abc可被图示NFA识别 证:f(S,abc)=f(A,bc)=f(A,c)∪f(C,c)=B 又因为B ∈ 终态集{B},得证。
DFA与NFA的等价 显然,DFA是NFA的特例。 但是,对于每个NFA M存在一个DFA M ' ',使L(M)=L(M ' ' )。证明过程如下: (1)假定NFA M=<S,∑,δ,s0,F>,对M的状态转换图进行以下改造: ①引进新的初态结点X和终态结点Y, X,Y∈S, 从X到s0中任意状态结点连一条ε箭弧,从F中任意状态结点连一条ε箭弧到Y。 ②对M的状态转换图进一步施行图1 所示的替换.其中k是新引入的状态。重复这种分裂过程直至状态转换图中的每条箭弧上的标记或为ε,或为∑中的单个字母。将最终得到的NFA记为M ' , 显然L(M ')=L(M)。
AB A B i j i k j A A/B i j i j B A* i j ε ε i k i A 图1
(2)将M'进一步变换为DFA,方法如下: ①假定I是M ' 的状态集的子集,定义I的ε闭包=CLOSURE(I)为: (a)若q∈I,则q∈CLOSURE(I); (b)若q∈ I,那么从q出发经任意条ε弧而能到达的任何状态q ‘都属于ε_CLOSURE(I); ②假定I是M ' 的状态集的子集,a∈∑, 定义 Ia=ε_CLOSURE(J) 其中,J是那些可从I中的某一状态结点出发经过一条a弧而到达的状态结点的全体。
③假定∑={a1,…,ak}。我们构造一张表,此表的每一行含有k十1列。置该表的首行首列为ε_CLOSURE(X)。③假定∑={a1,…,ak}。我们构造一张表,此表的每一行含有k十1列。置该表的首行首列为ε_CLOSURE(X)。 一般而言,如果某一行的第一列的状态子集已经确定,例如记为I,那么,置该行的i十1列为Iai(i=1,…,k)。然后,检查该行上的所有状态子集,看它们是否已在表的第一列中出现.将未曾出现者填入到后面空行的第一列。重复上述过程,直至出现在第i+1列(i=1,....k)上的所有状态子集均已在第一列上出现。因为M ‘的状态子集的个数是有限的,所以上述过程必定在有限步内终止。
V j i 正规式和有限自动机的等价性 正规式到有限自动机的变换过程是:首先根据正 则式构造出非确定的有限自动机,然后用子集法 将其确定化,再进行最小化,最后得到一个状态 最小的确定的有限自动机。 1、将正则式转换成非确定的有限自动机 (1)首先把正则式V表示为下图所示 (2)通过对V进行分裂和加进新节点的办法,逐步把这个图转换成每条弧都标记有的一个字符或的图,规则如下图:
AB A B i j i k j A A/B i j i j B A* i j ε ε i k i A
a ε C G a ε b b ε ε a ε ε E D Z C S A B b b 【例】正规式:R=(a*b)*ba(a|b)* 可以画为: