编译原理-(第三章词法分析)课件_第1页
编译原理-(第三章词法分析)课件_第2页
编译原理-(第三章词法分析)课件_第3页
编译原理-(第三章词法分析)课件_第4页
编译原理-(第三章词法分析)课件_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章词法分析词法分析的:

从左至右逐个字符地扫描源程序,产生一个个的,把作为字符串的源程序改造成为单词符号串的中间程序。词法分析器/扫描器:执行词法分析的程序。源程序扫描器scanner1、关键字词法分析器的功能如下图所示:2、标识符5、界符4、运算符3、常数由程序语言定义的具有固定意义的标识符。也可称为保留字或基本字。例如:Pascal中的begin,end,if等。界符:如逗号、分号、括号、/*,*/等。它是确定的。运算符:如+、-、*、/等。它是确定的。常数的类型一般有整型、实型、布尔型、文字型等。它是不限的。用来表示各种名字,如变量名、数组名、过程名等。它是不限的。2.1对词法分析器的要求2.1.1词法分析器的功能和输出形式词法分析器的功能:输入源程序,输出单词符号。单词符号:一个程序语言的基本语法符号。分为以下5种。

1、关键字:由程序语言定义的具有固定意义的标识符。也可称为保留字或基本字。例如:Pascal中的begin,end,if等。它是确定的。2、标识符:用来表示各种名字,如变量名、数组名、过程名等。它是不限的。3、常数:常数的类型一般有整型、实型、布尔型、文字型等。它是不限的。4、运算符:如+、-、*、/等。它是确定的。5、界符:如逗号、分号、括号、/*,*/等。它是确定的。确定不限例2-1:151-FORTRAN编译程序的词法分析器在扫描输入串IF(5·EQ·M)GOTO100后,它输出的单词符号串是:

逻辑IF(34,_)左括号(2,_)整常数(20,‘5’的二进制表示)等号(6,_)标识符(26,‘M’)右括号(16,_)GOTO(30,_)标号(19,‘100’的二进制表示)IF为关键字,种别编码34,采用一符一种的编码方式。常数类型,种别编码20,单词自身的值为‘5’的二进制表示。‘(’为界符,种别编码2,采用一符一种的编码方式。等号为运算符,种别编码6,采用一符一种的编码方式。M为标识符,种别编码26,单词自身值为‘M’。‘)’为界符,种别编码16,采用一符一种的编码方式。GOTO为关键字,种别编码30,采用一符一种的编码方式。100为标号,种别编码19,单词内部的值用100的二进制表示。例2-2:下述C++代码段:while(i>=j)i--;经词法分析器处理以后,它将被转换为如下的单词符号串

(while,_)((,_)(id,指向i的符号表指针)(>=,_)(id,指向j的符号表指针)(),_)(id,指向i的符号表指针)(--,_)(;,_)2.1.2词法分析与语法分析的关系1、把词法分析从语法分析中脱离出来的优点:使编译程序的结构更加简洁、清晰和条理化。词法分析和语法分析方法不同,词法分析可以使用正则文法自动构造scanner简单。有利于提高语法分析的效率。可以改善词法分析的细节,甚至于一个语法分析配几个scanner,把不同的输入变成一种内部表示。2、把词法分析作为独立的一遍scanner当作一遍。把scanner当作子程序。外存scanner语法分析源程序单词符号scanner作为一遍语法分析scanner源程序scanner作为子程序若识别输入语句IF(5.EQ.M)GOTO100,若缓冲区情况如下所示:IF(5.EQ.M)GO起点指示器搜索指示器输入缓冲区

TO100IF(5.EQ.M)GO起点指示器搜索指示器输入缓冲区TO100IF(5.EQ.M)GO起点指示器搜索指示器两个互补输入缓冲区120个字符扫描缓冲区的结构:

缓冲区大小:120个字符。采用两个指示器:起点指示器、搜索指示器。

两个互补区。2.2.2单词符号的识别——超前搜索单词符号识别的简单方法:超前搜索。关键字识别:

例如:在标准FORTRAN中1、DO99K=1,102、IF(5.EQ.M)I=103、DO99K=1.104、IF(5)=55

其中的DO、IF为关键字其中的DO、IF为标识符的一部分标识符的识别多数语言的标识符是字母开头的“字母/数字”串,而且在程序中标识符的出现后都跟着算符或界符。因此,不难识别。常数的识别对于某些语言的常数的识别也需要使用超前搜索。算符和界符的识别对于诸如C++语言中的“++”、“--”,这种复合成的算符,需要超前搜索。

XY(a)转换图示例2字母其他字母或数字*(b)识别标识符的转换图其他2数字数字*(c)识别整数的转换图例2-3:简单的状态转换图示例:初态终态从0状态到1状态可能出现字母图2.2状态转换图7*·数字数字数字数字E或D+或-数字其他E或D·数字其他数字例2-4:识别FORTRAN实型常数的转换图:例如下列实型常数可以被以下转换图识别:1.23E+4.56E-7单词符号种别编码助忆符内码值DIM1$DIM-IF2$IF-DO3$DO-STOP4$STOP-END5$END-标识符6$ID内部字符串常数(整)7$INT标准二进制形式=8$ASSIGN-+9$PLUS-*10$STAR-**11$POWER-,12$COMMA-(13$LPAR-)14$RPAR-例2-5:综合实例——做出识别下表所示的小语言的单词符号的状态转换图2.2.4状态转换图的实现1、CHAR字符变量,存放最新读进的源程序字符。2、TOKEN字符数组,存放构成单词的字符串。3、GETCHAR过程,将下一输入字符读入CHAR,搜索指示器前移一个字符。4、GETBC过程,检查CHAR中的字符是否为空白。若是,则调用GETCHAR直至CHAR中进入一个非空白字符。5、CONCAT过程,把CHAR中的字符连接到TOKEN之后。6、LETTER布尔函数过程,它们分别判断CHAR中的字符是数字或是字母,

DIGIT从而给出真假值TRUE、FALSE。7、RESERVE整型函数过程,用TOKEN中的字符串查保留字表,若是一个保留字则给予编码,否则回送0值(假定0不是保留字的编码)。8、RETRACT过程,把搜索指示器回调一个字节,把CHAR中的字符置为空白。以上函数和子程序过程都不难编制,使用它们能够方便的构造状态转换图的对应程序。一般,我们可以让每一个状态结对应一个程序段。例如:我们可以让不含回路的分叉结,对应一个CASE语句,或者是一组IF…THEN…ELSE语句。具体见后面实例。

终态结一般对应一个RETURN(C,VAL)语句。其中C为单词种别编码;VAL是字符数组的TOKEN,或者是一个整数值,或者无定义。具体见后面实例。为了把状态转换图转化成程序,每个状态要建立一段程序,它要做的工作如下:第一步:从输入缓冲区中取一个字符。为此,我们使用函数GETCHAR,每次调用它,推进先行指针,送回一个字符。第二步:确定在本状态下,哪一条箭弧是用刚刚来的输入字符标识的。如果找到,控制就转到该弧所指向的状态;若找不到,那么寻找该单词的企图就失败了。失败:先行指针必须重新回到开始指针处,并用另一状态图来搜索另一单词。如果所有的状态转换图都试过之后,还没有匹配的,就表明这是一个词法错误,此时,调用错误校正程序。GETCHAR是过程,将下一输入字符读入CHAR,搜索指示器前移一个字符。对于如上的状态转换图,状态0的代码如下所示:

state0:C:=GETCHAR;ifLETTER(C)thengotostate1elseFAIL()2字母其他字母或数字LETTER()是布尔函数过程,当且仅当C中的字符是字母,它返回真假值TRUE。FAIL()是例子程序,它移回先行指针(lookaheadpointer),开始下一状态转换图,或调用出错程序。例2-7:示例——如何把状态结对应于一段程序:*对于如上的状态转换图,状态1的代码如下所示:

state1:C:=GETCHAR;ifLETTER(C)orDIGIT(C)thengotostate1elseifDELIMITER(C)

thengotostate2elseFAIL()2字母其他字母或数字DIGIT()是布尔函数过程,当且仅当C中的字符是数字,它返回真假值TRUE。DELIMITER(C)是过程,只要碰到标识符后的分界符,它返回TRUE。分界符一般为:空格、算术、逻辑符号,括号、‘=’、‘;’、‘.’、‘,’。*对于如上的状态转换图,终态——状态2的代码如下所示:

state2:RETRACT();

RETURN($id,INSTALL())2字母其他字母或数字RETRACT()是过程,由于分界符不属于标识符,所以我们要把先行指针回调一个字符。INSTALL()是过程,如我们识别出的标识符不在符号表中,我们把它装入符号表。我们还要给语法分析程序返回一个二元式。*如果同时识别标识符和定义符,则需要修改为State2:修改之后,状态2的代码如下所示:

state2:RETRACT();c:=RESERVE();ifc=0thenRETURN($id,INSTALL)

elseRETURN(C,_)RESERVE()整型函数过程,针对TOKEN中的字符串进行查找,看其是否是保留字,是保留字给出它的编码,否则回送0(假定0不是保留字编码)。例2-9:以下程序段对应的状态图‘0’…‘9’:BEGINWHILEDIGITDOBEGINCONCAT;GETCHAREND;

RETRACT;

RETURN($INT,DTB);END;非数字数字数字4*RETURN语句,对应终态结,其中$INT为种别编码,DTB为一个把十进制转换到二进制的转换函数。它把TOKEN中的数字译成标准二进制码,并以此为函数值返回。正规式与正规集的递归定义:1、ε和Φ都是字母表∑上的正规式,它们所表示的正规集分别为{ε}和Φ;2、任何a∈∑,a是∑上的一个正规式,它所表示的正规集为{a};3、正规式正规集正规式正规集UL(U)(U|V)L(U)∪L(V)VL(V)(U·V)L(U)L(V)(U)*

L(U)*(闭包)仅由有限次使用上述三步骤而得到的表达式才是∑上的正规式。仅由这些正规式所表示的子集才是∑上的正规集。2.3正规表达式与有限自动机2.3.1正规式与正规集运算符的优先顺序:先“*”,次“·”,最后“|”“|”读做“或”“·”读做“连接”“*”读做“闭包”∑*的子集U,V:

积UV={αβ|α∈U&β∈V}

n次积Vn=VVV…VV0={ε}V的闭包V*=V0

UV1

UV2U…V的正则闭包V+=VV*2.3.2确定有限自动机(DFA)一个确定有限自动机(DFA)M是一个五元式:M=(S,∑,δ,s0,F),其中1、S是一个有限集,它的每个元素称为一个状态2、∑是一个有穷字母表,它的每个元素称为一个输入字符3、δ是一个从S×∑至S的单值部分映射。δ(s,a)=s´意味着:当现行状态为S、输入字符为a时,将转换到下一状态s´。我们称s´为s的一个后继状态。4、s0∈S是唯一的初态5、FS是一个终态集(可空)。显然,一个DFA可用一个矩阵表示,该矩阵的行表示状态,列表示输入字符,矩阵元素表示δ(s,a)的值。这个矩阵称为状态转换矩阵。例2-12:有DFA

M=({0,1,2,3},{a,b},δ,0,{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

状态ab012132213333相应的状态转换矩阵如下表:

一个DFA也可用一张(确定的)状态转换图来表示。假定DFAM含有m个状态和n个输入字符,那么,这个状态转换图含有m个状态结点,每个结点顶多有n条箭弧射出和别的结点相连接,整张图含有一个初态结点和若干个(可以为0)终态结点。3图2.5状态转换图aaaabbb状态ab01213221333-如下表所示的状态转换矩阵对应的状态转换图如右图:3aaabbb上图所示的状态转换图的S、∑及∑*如下:S={0,1,2,3}∑={a,b}∑*={α|α为ε,或者α为a、b的任意组合}从初态0到终态3有如图所示的通路,箭弧上到标记符连接起来的字aa属于∑*,所以右图所示的DFA可以识别字aa。同理:从初态0到终态3还有如图所示的通路,箭弧上到标记符连接起来的字bba属于∑*,所以右图所示的DFA可以识别字bba。a例2-13:科学表示法中数字常量的正则表达式对应的DFA:digitdigitnat对应的DFA如下图digit=[0-9]nat=digit+

signedNat=(+|-)?natnumber=signedNat(“·”nat)?signedNat对应的DFA如下图加上可选的小数部分,数字常量的正则表达式number=signedNat(“·”nat)?对应的DFA如下图:+digitdigitdigit-+digitdigitdigit-digitdigit•abbb接受与正则式ab+|ab*|b*相同的语言的DFA如下所示:例2-14:串中只有一个b被如下所示的DFA接受:bnotbnotb例2-15:包含最多一个b的串被如下所示的DFA接受:bnotbnotb注意二者之间的区别

定理:如果一个DFAM的输入字母表为∑,则我们也称M是∑上的一个DFA。可以证明:∑上的一个字集V∑*是正规的,当且仅当存在∑上的DFAM,使得V=L(M)。DFA的确定性表现在映射δ:S×∑→S是一个单值函数。即:对于任何状态s∈S和输入符号a∈∑,δ(s,a)唯一确定了一个状态。从转换图角度,我们也可以得到答案。如果允许是一个多值函数,我们就得到下一节要讲到的非确定自动机的概念。2.3.3非确定有限自动机(NFA)一个非确定有限自动机(NFA)M是一个五元式:

M=(S,∑,δ,S0,F),其中1、S是一个有限集,它的每个元素称为一个状态2、∑是一个有穷字母表,它的每个元素称为一个输入字符3、δ是一个从S×∑*至S的子集的映射,即δ:S×∑*

→2s4、S0∈S是唯一的初态5、FS是一个终态集(可空)。一个含有m个状态和n个输入字符的NFA可用一张如下的状态转换图来表示:该图含有m个状态结点,每个结点可以射出若干条弧与别的结点相连接,每条弧用∑*中的一个字(可以是不同的字,也可以是空字)做标记,整张图至少含有一个初态结点和若干个(可以为0)终态结点。某些结点既可以是初态结点也可以是终态结点。1aaa,b2bbaba,b0ab,baaa,bbab,baaa,bbyaaaabεbbbεεε下图所示的状态转换图的S、∑及∑*如下:S={0,1,2,3}∑={a,b}∑*={α|α为ε,或者α为a、b的任意组合}对于∑*中的任何一个字α,若存在一条从某一初态结点到某一终态结点的通路,且这条通路上所有弧上的标记字依序连接成的字(忽略ε)等于α,则称α可以为NFAM识别。从初态x到终态y的连接通路弧上,有如下标记字:εεaaεε,去除ε,为aa,所以字aa可为NFA接受。4aaεbεε例2-16:上图所示的NFA的以下两个转换序列都可以接受串abb:允许接受ab允许接受与ab*匹配的字符串允许接受与b*匹配的字符串允许接受与ab+匹配的字符串由此,我们可以看出这个NFA接受与正则式ab+|ab*|b*相同的语言!接受ab接受ab接受ab+接受ab接受ab+接受ab*接受ab接受ab+接受ab*接受b*练习:考虑以下NFA通过怎样的转换接受串acab:10aεbεεεεεεεεcDFA是NFA的特例,可以采用子集法将NFA确定化。假定I是NFAM的状态集的一个子集,我们定义ε_CLOSURE(I)为:

1、若s∈I,则s∈ε_CLOSURE(I);2、若s∈I,那么从s出发经过任意条ε弧而能到达的任何状态s’都属于ε_CLOSURE(I)。状态集ε_CLOSURE(I)称为I的ε_闭包。ε_CLOSURE(I)的定义假定I是NFAM的状态集的子集,a∈∑,定义Ia=ε_CLOSURE(J)其中,J是那些可从I中的某一状态结点出发经过一条a弧而到达的状态结点的全体。Ia定义∑={a1,a2,….ak}。先构造一张表,该表每一行含有k+1列。置该表的首行首列为ε_CLOSURE(X)。重复上述过程,直至所有第二列和第三列的子集均已在第一列上出现了为止。如果某一行的第一列的状态子集已经确定,例如记为I,那么,求出这一行的第二个和第三个子集Ia和Ib看它们是否已在表的第一列出现,将未出现的填入到后面空行的第一列。1表的初始化构造2处理表的一行3重复处理子集算法例2-17:考虑下图所示NFA的确定化:yaaaabεbbbεεεIIaIb{X,5,1}{5,3,1}{5,4,1}{5,3,1}{5,3,1,2,6,Y}{5,4,1}{5,4,1}{5,3,1}{5,4,1,2,6,Y}{5,3,1,2,6,Y}{5,3,1,2,6,Y}{5,4,1,6,Y}{5,4,1,6,Y}{5,3,1,6,Y}{5,4,1,2,6,Y}{5,4,1,2,6,Y}{5,3,1,6,Y}{5,4,1,2,6,Y}{5,3,1,6,Y}{5,3,1,2,6,Y}{5,4,1,6,Y}I=ε_CLOSURE{X}为{X,5,1}。从状态I出发经过一条a弧而能到达的状态全体J为{5,3},而ε_CLOSURE(J)={5,3,1}。从而Ia={5,3,1}。初态ε_闭包{X,5,1}Ja为{5,3}ε_CLOSURE(J)为{5,3,1}(根据ε_闭包的定义)根据此方法依次求出左边表中的状态转换矩阵即可。对右下图表中的所有子集重新命名,得到左图中的状态转换矩阵形成如下状态转换矩阵,从而得到相应的DFA。如图所示:sab0121322153344655656343aaaabbb546abbabIIaIb{X,5,1}{5,3,1}{5,4,1}{5,3,1}{5,3,1,2,6,Y}{5,4,1}{5,4,1}{5,3,1}{5,4,1,2,6,Y}{5,3,1,2,6,Y}{5,3,1,2,6,Y}{5,4,1,6,Y}{5,4,1,6,Y}{5,3,1,6,Y}{5,4,1,2,6,Y}{5,4,1,2,6,Y}{5,3,1,6,Y}{5,4,1,2,6,Y}{5,3,1,6,Y}{5,3,1,2,6,Y}{5,4,1,6,Y}重命名为状态0重命名为状态1根据重命名的状态填写表格ab例2-18:考虑下图所示NFA的确定化:{1}在letter上有到{2}的转换:{2}={2,3,4,5,7,10}{2,3,4,5,7,10}letter在letter上有到{6}的转换:{6}={4,5,6,7,9,10}{4,5,6,7,9,10}letter在digit上有到{8}的转换:{8}={4,5,7,8,9,10}{4,5,7,8,9,10}digitletterdigitdigitletter注意:所有这些状态都有在letter和digit上的转换。上图所示NFA的确定化后的DFA如下:子集构造过程如下:初始状态:{1}={1}ε10letterεletterεεεεεε

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论