编译原理课件第2章.ppt
《编译原理课件第2章.ppt》由会员分享,可在线阅读,更多相关《编译原理课件第2章.ppt(123页珍藏版)》请在三一办公上搜索。
1、第2章 词 法 分 析,2.1 词法分析中的若干问题 2.2 模式的形式化描述 2.3 记号的识别有限自动机 2.4 从正规式到词法分析器 2.5 本章小结,2.1 词法分析中的若干问题,2.1.1 记号、模式与单词 自然语言中的句子通常由一个个单词和标点符号组成,可以根据其在句子中的作用,将它们划分为动词、名词、形容词、标点符号等不同的种类。程序设计语言与此相类似,组成语句的基本单元也可根据其在句子中的作用分类。最基本分类有四类:(1)关键字(保留字):这类单词在程序设计语言中有固定的意义,如begin、end、while等。若在程序设计语言中不允许用它们再表示其他的意思,则这类单词也被称为
2、保留字。,(2)标识符:标识符是程序设计语言中最大的一个类别,它的作用是为某个实体起一个名字,以便于今后称呼(引用),如draw_line、sort等。可以用标识符来命名的实体包括类型、变量、过程、常量、类、对象、程序包、标号等,即类型名、变量名、过程名、常量名等。,(3)字面量:字面量是指直接以其字面所表示的常量,如25、true、This is a string等。值得注意的是,字面量与常量是两个不同的概念,常量可以是一个字面量(直接表示),也可以是一个常量名(命名表示)。例如可以在Pascal中声明:const max_length=25,显然25是一个常量,max_length也是一个
3、常量,我们称25为字面量,而不称max_length为字面量。根据字面量的内容,可以将它们再进行更细的划分,如常数字面量(包括整型字面量、实型字面量、枚举字面量等)、字符串字面量等。,(4)特殊符号:程序设计语言中的特殊符号,类似于自然语言中的标点符号,每个符号在程序设计语言中均有特殊用途。可以根据它们的用途,再细分为算符(如+、*、/等)、分隔符(如;、”、“等)。显然,一个单词究竟是标识符、关键字,还是特殊符号,需要根据一定的构词规则来产生和识别。我们将产生和识别单词的规则称为模式(patten),按照某个模式(规则)识别出的元素称为记号(token),而单词(lexeme)一词是指被识别
4、出元素自身的值。,例2.1 对于语句:position:=initial+rate*60,可以识别出下述序列:标识符 特殊符号 标识符 特殊符号 标识符 特殊符号 数字字面量 其中position、initial、rate均被识别为标识符,因为它们均符合同一条规则,即以字母打头的字母数字串。记号至少含有两个信息:一个是记号的类别,如“标识符”;另一个是记号的值,如“position”。显然,如果把记号看作是一个类型的话,则单词就是一个类型中的实例。由于我们总是说识别出一个标识符,而不说识别出一个position或rate,因而将词法分析器识别出的序列称为记号流。,记号的类别、模式以及单词三者之
5、间的关系可以用表2.1加以说明。其中,const和if分别是被细分的关键字,它们的特点是一个记号类别仅对应一个单词;relation表示关系运算符;id表示标识符;num表示数字字面量;literal表示字符串字面量;comment表示注释,它们的特点是一个记号类别可以对应若干个单词。由于语法分析及其后的阶段并不对注释进行分析,因而可在词法分析阶段中滤掉注释,即词法分析器可以不向语法分析器返回comment。而其他的记号,均是源程序中的有效成分,需要返回给语法分析器。,表2.1 记号、模式与单词,2.1.2 记号的属性 从例2.1中已经知道,记号至少包含两个部分:记号类别和记号的其他信息。可以
6、看出,记号的类别唯一标识一类记号,例如所有的关系运算符均可以由relation来标识,而所有字符串字面量均可以由literal来标识。所以,记号的类别可以被认为是记号的名字或记号的代表,在不引起混淆的情况下,将记号的类别简称为记号。记号的其他信息被称为记号的属性。例如,num可以取值3.1416,则称3.1416是num的属性,而literal可以取值“core dumped”(不含引号),则称“core dumped”是literal的属性。由此可见,记号的类别标识一类记号,而记号的类别加属性标识一个记号实例。,在计算机内部,可以有不同的方式来表示记号的类别和属性。一般情况下,记号的类别可以
7、用整型编码或枚举类型表示,如表2.1中每个记号类别可以用括号中的整型编码表示,如01表示const,82表示id等。根据记号类别的不同,记号的属性的值可以有不同的表示方法。relation的属性值是一个有限可枚举集合,可以用每个属性值在集合中的位置来表示它,如1表示,2表示=,依此类推。id的属性值是一个无限可枚举集合,因此,只能用每个标识符的原始输入形式(字符串)来表示,如pi、draw_line等。字面量的属性根据情况,其表示方式也不同,如数字字面量可由转义后的实际值表示,如表示为3.1416而不是“3.1416”,而字符串字面量就无需转义。,例2.2 表达式mycount 25由表2.2
8、的三个记号组成。其中标识符的属性值也可以由mycount在符号表中的入口(下标)来表示。,表2.2 记号的表示,2.1.3 词法分析器的作用与工作方式 词法分析器是编译器中唯一与源程序打交道的部分,从某种意义说,也可以被认为是整个编译器的预处理器。它的主要工作包括:(1)滤掉源程序中的无用成分,如注释、空格、回车等。例如,表2.1中记号的种类除了comment之外,均有一个编码,表示需要递交给语法分析器进行后继的处理,而comment没有对应编码,表示注释成分可以过滤掉,不需要递交,因为语法分析及其之后的各个阶段已经不再需要它们。,(2)处理与具体平台有关的输入。不同的操作系统或相关软件构成的
9、平台,对某些特殊符号(如文件结束符等)可能有不同表示,因此需要在词法分析阶段分情况处理。(3)识别记号,并交给语法分析器。这是词法分析器的主要任务,本章将在各节中详细讨论。,(4)调用符号表管理器或出错处理器,进行相关处理。词法错误是源程序中常见的错误,如出现非法字符、拼错关键字、多或少字符等。值得注意的是,词法错误往往不是由词法分析器检查出来的,而是由语法分析器发现的。这是因为,源程序中除了非法字符之外的大部分字符或字符串,都可以被词法分析器的某个模式所匹配,从而被识别成一个记号。而这些记号的正确与否,在没有上下文对照的情况下,是很难判断的。例如,12x被认为是一个非法的Pascal的标识符
10、,但是,由于12可以被识别整型数的模式匹配,而x可以被识别标识符的模式匹配,因而词法分析器会分别识别出一个整型数和一个标识符,而不是报告一个错误。,根据编译器的总体需求,词法分析器在整个编译器中可以有不同的工作方式。(1)词法分析器作为语法分析器的子程序。最常采用,也最容易实现的工作方式是将词法分析器作为语法分析器的子程序,每当语法分析器需要一个记号时,就调用词法分析器,并得到一个识别出的记号。其工作方式如图2.1所示。(2)词法分析器进行单独的一遍扫描。另一种常用的工作方式,是安排词法分析器进行单独的一遍扫描,它以源程序为输入,输出是以记号流形式表示的源程序。其工作方式如图2.2所示。,图2
11、.1 作为子程序的词法分析器,图2.2 词法分析器进行单独一遍扫描,(3)与语法分析器并行工作的模式。上述两种词法分析器的工作模式与语法分析器的关系均被认为是串行的。为了提高编译器的效率,可以通过一个队列,使词法分析器和语法分析器以生产/消费的形式并行工作。词法分析器将识别出的记号流输出到队列中,语法分析器从队列中取得记号,只要队列中有识别出的记号,则词法分析器和语法分析器就可以同时工作。其工作方式如图2.3所示。,图2.3 并行工作模式,2.1.4 输入缓冲区 词法分析器是编译器中读入源程序字符序列的唯一阶段,而相当可观的编译时间又消耗在词法分析阶段,所以,加快词法分析是设计编译器时要考虑的
12、重要问题之一。可以通过设立输入缓冲区来加快读入源程序字符序列的速度。如果使用词法分析器生成器编写词法分析器,则生成器会提供读入和缓冲输入序列的例程;如采用通用程序设计语言编写词法分析器,就需要显式地管理源程序的读取。,输入缓冲区一般被设计为一块与磁盘扇区大小成倍数关系的内存。若一个扇区为1024字节,则输入缓冲区可以取1024、4096或8192字节等。这样可以保证对缓冲区的一次输入所需的I/O操作次数尽可能少。输入缓冲区的安排一般采用单缓冲区或双缓冲区(缓冲区对)的方式。下边所介绍的是单缓冲区方式,它也是词法分析器生成器FLEX所采用的方式。,图2.4是一个单缓冲区的示意图。有效输入序列从缓
13、冲区的起始位置开始存放,最后添加一个特殊标记(此处用#表示):若缓冲区一次装不下整个源程序,它就表示缓冲区的结束,否则它紧跟在文件结束符(eof)之后,表示整个输入源程序的结束。用两个指针c_ptr和f_ptr分别指向当前被识别记号的第一个字符和向前扫描的字符。最初,两个指针同时指向下一个被识别记号的第一个字符,f_ptr向前扫描,直到某个模式匹配成功。一旦这个记号被确定,f_ptr指向被识别出记号的右端字符,在此记号被处理后,两个指针都移向该记号之后的下一个字符。在f_ptr向前扫描的过程中,如果遇到文件结束标志,则表示输入序列已被处理完。如果遇到特殊标记#,说明缓冲区中的内容需要更新。这时
14、,首先将c_ptr到f_ptr所指的内容(不包括特殊标记)移到缓冲区的起始位置,然后将新的内容读进缓冲区,最后加上特殊标记。具体算法如下:,c_ptr f_ptr,图2.4 单缓冲区,procedure get_next_buffer(buffer,start,length)is-start和length是需仍保留在缓冲区中字符串的起始位置和长度begin if length=buffer_size-buffer_size是缓冲区实际容量 then return error;else for i in low.low+length1-low是缓冲区下界,假设从0开始 loop buffer(i
15、):=buffer(start+ilow);-把剩余的输入移到缓冲区头部 end loop;,num_to_read:=buffer_sizelength;if number_to_readblock_size-block_size应是磁盘扇区的整数倍 then number_to_read:=block_size;end if;read_buffer(buffer,length+low,num_to_read);end if;end get_next_buffer;,假设被扫描的输入序列的最大长度不超过max_length,则可以选择buffer_size=block_size+max_le
16、ngth,即缓冲区的大小是磁盘扇区大小的整数倍加上一个最长可能被扫描的输入序列。这种缓冲技术能胜任大多数情况,但在向前被扫描字符个数超过缓冲区长度的极端情况下会失效。早期的程序设计语言通常采用开括号与闭括号的方式标识注释,如表2.1中的comment,如果程序员不小心忘记书写闭括号,而词法分析器的设计又将comment作为一个完整的记号识别,就会出现被扫描字符个数超过缓冲区长度的情况。因此,后来设计的程序设计语言大多采用仅有开括号,而默认换行标志为闭括号的注释方式,如上述算法中的“-”(Ada的注释方式)或者C+中的“/”,从根本上杜绝了这种极端情况。,2.2 模式的形式化描述,2.2.1 字
17、符串与语言 从词法分析的角度看,程序设计语言是由记号组成的集合,每个记号又是由若干字母按照一定规则组成的字符串。为了讨论的简单性和准确性,本章对常用的术语以定义的方式给出。有一点需要强调,编译领域的很多名词术语的使用并不统一,因此希望读者掌握“是什么”,而不是“叫什么”。在下述的讨论中,我们首先定义一个泛泛的“语言”,然后在此基础上规定一个正规集,而程序设计语言就是一个正规集。,定义2.1 语言L是有限字母表上有限长度字符串的集合。定义2.1明确指出,语言是一个集合,集合中的元素是字符串,并且强调了两个有限:字母表是有限的,即字母表中元素是有限多个;字符串的长度是有限的,即字符串中字符个数是有
18、限多个。这是由于计算机所能表示的字符个数和字符串的长度都是有限的。,由于字符串的有序性,使得以字符串作为元素的集合具有某些特性。字符串和集合的基本概念和特性,以表格的形式分别列在表2.3和表2.4中。其中,字符串的连接运算是一种新形式的运算,它表示两个字符串首尾相接,形成一个新的集合。例如,S1=pre,S2=fix,则S1S2=prefix。值得注意的是,集合中连接运算所形成的新集合与交运算形成的新集合完全不同。例如,若L=pre,M=fix,则LM=,而LM=prefix。,表2.3 字符串的基本概念,表2.4 字符串集合上的基本运算,2.2.2 正规式与正规集 定义2.2 令是一个有限字
19、母表,则上的正规式及其表示的集合递归定义如下:是正规式,它表示集合L()=;若a是上的字符,则a是正规式,它表示集合L(a)=;若正规式r和s分别表示集合L(r)和L(s),则(a)r|s是正规式,表示集合L(r)L(s);(b)rs是正规式,表示集合L(r)L(s);(c)r*是正规式,表示集合(L(r)*;(d)(r)是正规式,表示的集合仍然是L(r)。可用正规式描述的语言称为正规语言或正规集。,定义2.2中和规定了正规式的基本操作数或基本正规式。定义2.2的给出了正规式上的三种运算:(a)或运算、(b)连接运算和(c)闭包运算。对于由多个操作数和多个操作符组成的正规式,可以利用(d)所给
20、的括号规定运算的先后次序。如果对或、连接和闭包运算进行如下约定:三种运算均具有左结合性质;运算的优先级从高到低顺序排列为:闭包运算、连接运算、或运算。则正规式中不必要的括号可以被省略。例如,(a)|(b)*(c)可以简化成a|b*c。,例2.3 设字母表=a,b,c,部分上的正规式和正规式所表示的正规集如表2.5所示。,表2.5 正规式与它表示的正规集,正规集是一个集合,而正规式是表示正规集的一种方法。正如不同算术表达式可以表示同一个数(如3+5、5+3、2+6等均表示8)一样,不同正规式也可以表示同一个正规集,即正规式与正规集之间是多对一的关系。例2.4 令 L(x)=a,b,L(y)=c,
21、d,则L(x|y)=a,b,c,dL(y|x)=a,b,c,d x|y和y|x表示同一个正规集。,定义2.3 若正规式P和Q表示了同一个正规集,则称P和Q是等价的,记为P=Q。正规式之间的一些恒等运算,被称为正规式的代数性质。表2.6给出了正规式的若干代数性质。利用这些性质,可以对复杂的正规式进行化简,使得可以用最简单形式的正规式表示一个集合。而简单的正规式意味着其所对应的识别器的构造也是简单的。,表2.6 正规式的代数性质,2.2.3 记号的说明 表2.1中用自然语言对模式进行了非形式化的描述,例如标识符模式的非形式化描述是“以字母打头的字母数字串”。这一描述很不精确,存在一些问题,如哪些符
22、号是字母,哪些符号是数字,字母数字串的长度可以是多少等等。由于正规式是严格的数学表达式,采用正规式来描述模式,解决了精确描述模式的问题。另外,从词法分析器的角度上看程序设计语言,用正规式说明的记号是一个正规集。用正规式说明记号的公式为:记号=正规式,可以读作为“(左边)记号定义为(右边)正规式”,或者“记号是正规式”。通常,在不引起混淆的情况下,也把说明记号的公式简称为正规式,或者规则。,例2.5 表2.1中的记号relation、id和num分别是Pascal的关系运算符、标识符和无符号数,它们的正规式表示如下所示:relation=|=|=id=(a|b|c|d|e|f|g|h|i|j|k
23、|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z)(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|0|1|2|3|4|5|6|7|8|9)*,num=(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*(|.(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|
24、9)*)(|E(+|-|)(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)上述正规式给出了标识符的精确定义,用自然语言可以描述为“字母是英文26个字母大小写中任何一个,数字是十进制阿拉伯数字中的任何一个,标识符是以字母打头的、其后可跟随0个或若干个字母或数字的字符串”。,1简化正规式描述 为了简化正规式的描述,通常可以采用如下的几种正规式的缩写形式。(1)正闭包。若r是表示L(r)的正规式,则r+是表示(L(r)+的正规式,且下述等式成立:r+=rr*=r*r,r*=r+|+与*具有相同的运算优先级和结合性。(2)可缺省。若r是正规式,则(r)?是表示L
25、(r)的正规式,且下述等式成立:r?=r|,(3)字符组。字符组是或关系的缩写形式,它把所有存在或关系的字符集中在 里面。其中的字符可以有如下两种书写方式:枚举方式:如abc,它等价于a|b|c 分段方式:如0-9a-z,它等价于 0123456789abcdefghijklmnopqrstuvwxyz,(4)非字符组。若r是一个字符组形式的正规式,则r是表示L(r)的正规式。例如,若=,则L(abc)=d,e,f,g。(5)串。若r是字符连接运算的正规式,则串r与r等价,即r=r。特别地,=,?a=a。引入串的表示可以避免与正规式中运算符的冲突。例如:a|b=a|ba|b。,2引入辅助定义式
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 课件
链接地址:https://www.31ppt.com/p-5665765.html