编译原理 第9章 语义分析和代码生成(Modified)
语义分析与代码生成

第七章语义分析与代码生成7.1 语法制导翻译编译程序的实质性工作是翻译,即为源程序生成目标代码。
为此,我们必须知道程序的含义是什么(语义分析)?应该翻译成什么(代码生成)?在三、四章,我们主要讨论了源程序的识别,即判定一个源程序是否符合源语言的文法。
在讨论语法分析时曾说过,上下文无关文法不足以描述编程语言的全部语法特征。
为了说明这一点,让我们来看一个例子:V ARi:integer;BEGINj:=i*iEND;如果j没有在外层块中说明,那么赋值语句中出现的j就是非法的。
这是一种上下文敏感的成分。
为了清楚地说明这一点,假定j是在自顶向下分析过程中由非终极符<变量>导出的,在这次推导之前的句型为αVARj:integer;β<变量>γ其中α,β,γ为符号串。
推导后的句型为αVARj:integer;βjγ为了保证变量在使用前必须说明,需要有如下形式的规则:V AR j:integer;β<变量>→V AR j:integer;βj而不是<变量>→j即<变量>只有在一定的上下文中才可以展开成j。
上下文敏感成分的分析实质上是语法分析的内容。
但是,因为我们的语法分析是以上下文无关文法为基础的,没有考虑上下文敏感成分的处理,所以必须在语义分析时加以考虑。
这相当于把语言的敏感成分划归为语言的语义范畴(尽管在概念上并非如此)。
比如说在处理说明V AR j:integer时,语义分析应该将这个说明所提供的信息填入符号表,即完成对符号表的插入操作;当然也需要完成其它的语义分析工作,而后在确定是否可用规则<变量>→j进行推导时,就可通过对符号表的检索操作来完成。
如果符号表中有标识符j,而且j又是个变量标识符,就可以用此规则进行推导。
除了敏感成分的处理之外,为了生成目标代码,所需要完成的一切操作都属于语义分析的范畴。
考虑如下条件语句:IF E THEN S1 ELSE S2为它生成的目标代码应具有图7.1的结构(称为它的目标结构),其中,计算E的目标指令、S1和S2的目标指令是在处理表达式和语句时生成的,处理条件语句时所生成的指令就是“jumpf l0”和“jump l1”。
编译原理实验报告

编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。
二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。
三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。
在本次实验中,我们使用有限自动机的理论来设计词法分析器。
首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。
然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。
在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。
(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。
在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。
首先,我们根据给定的语法规则,编写了相应的递归函数。
每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。
在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。
(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。
在本次实验中,我们使用了四元式作为中间代码的表示形式。
在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。
同时,根据语法树的结构,生成相应的四元式中间代码。
(四)代码优化代码优化的目的是提高生成代码的质量和效率。
在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。
通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。
编译原理语义分析与中间代码生成

编译原理语义分析与中间代码生成在编译原理中,语义分析是编译器的重要组成部分之一,它负责验证和处理源代码中的语义信息,为后续的中间代码生成做准备。
本文将介绍语义分析的基本概念和流程,并探讨中间代码生成的相关技术。
一、语义分析的基本概念和流程语义分析是指对源代码进行语义检查和语义信息提取的过程。
其主要目标是确保源代码在语义上是正确的,并从中提取出各种语义信息,以便后续阶段使用。
语义分析的基本流程如下:1. 词法分析和语法分析:在进行语义分析之前,需要先对源代码进行词法分析和语法分析,以便将代码转化为具有结构的中间表示形式(如抽象语法树)。
2. 符号表的构建:符号表是语义分析的重要数据结构,用于存储程序中出现的各种标识符及其相关信息,如类型、作用域等。
在语义分析阶段,需要构建符号表并实时更新。
3. 类型检查:类型检查是语义分析的核心任务之一。
它通过对表达式、赋值语句、函数调用等进行类型推导和匹配,来验证程序是否存在类型错误。
4. 语义规则检查:除了类型检查外,语义分析还需要检查程序是否符合语言规范中的其他语义规则,如变量是否已声明、函数调用是否正确等。
5. 语义信息提取:语义分析还负责提取源代码中的各种语义信息,如函数调用关系、变量的定义和引用关系、控制流信息等。
这些信息将为后续的代码优化和代码生成提供依据。
二、中间代码生成的相关技术中间代码是指某种形式的中间表示形式,通常与源代码和目标代码之间存在一定的映射关系。
它在编译过程中起到连接前后两个阶段的桥梁作用,并且可以进行一些优化。
常见的中间代码形式之一是三地址码。
三地址码是一种低级的代码表示形式,每条指令最多包含三个操作数。
它具有简洁明了的特点,适合进行后续的优化工作。
在进行中间代码生成时,需要考虑以下几个方面的技术:1. 表达式的翻译:在将源代码转化为中间代码时,需要将源代码中的表达式进行翻译。
这包括对表达式的计算顺序、运算符优先级等方面的处理。
2. 控制流的处理:在编译过程中,需要将源代码中的控制流转化为中间代码中的条件分支和循环结构。
智慧树答案编译原理知到课后答案章节测试2022年

第一章1.编译器(Compiler)能捕捉的错误都是静态错误(Static errors)。
答案:对2.编译器只能识别动态(Dynamic)语义,但不能识别静态(Static)语义。
答案:错3.对源程序进行编译正确处理顺序为()答案:词法分析、语法分析、语义分析、代码生成4.编译器的各个阶段的产物分别是()、中间代码和目标代码。
答案:记号序列、语法树、注释树5.()执行翻译代码的功能,且立即执行源程序,而不产生中间代码。
答案:解释程序6.将编译程序分成若干个“遍”是为了____。
答案:利用有限的机器内存并提高机器的执行效率7.词法分析器用于识别_____。
答案:单词8.在编译器的功能模块中,扫描器的功能是()。
答案:词法分析9.编译器进行的是()答案:静态语义分析10.编译器中词法分析的输入和输出分别是()答案:字符串、记号串第二章1.确定的自动机以及不确定的自动机都能正确地识别正规集。
答案:对2.正则文法、 DFA和正则表达式均可以用于描述高级程序设计语言的词法。
答案:对3.在有穷自动机中,两个状态是等价的条件是()。
答案:A和B4.扫描器所完成的任务是从字符串形式的源程序中识别出一个个具有独立含义的最小语法单位即()答案:单词5.设∑为{a,b},则a,ba,{},Ø都是∑上的正规式。
答案:对6.以下( )不是DFA的组成部分。
答案:初始状态集合7.在有穷自动机中,有穷自动机的状态s和t不等价,则称这两个状态是可区别的。
答案:对8.“由大写字母组成的、以Z开头并且不以Z结尾的字符串”的正则表达式是()答案:Z [a-Z]*[A-Y]9.下面( )是词法分析的理论基础。
答案:有穷自动机第三章1.高级语言编译程序常用的语法分析方法中,递归下降分析法属于()分析方法。
答案:自顶向下2.下面哪种分析方法是自顶向下分析()。
答案:LL(1)3.推导是一个替换序列,每一步都是对()进行替换,形成一个从单独的结构名开始,结束于一串记号符号的过程。
编译原理(第2版)课后习题答案详解

第1 章引论第1 题解释下列术语:(1)编译程序(2)源程序(3)目标程序(4)编译程序的前端(5)后端(6)遍答案:(1)编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。
(2)源程序:源语言编写的程序称为源程序。
(3)目标程序:目标语言书写的程序称为目标程序。
(4)编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。
通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符号表管理等工作。
(5)后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。
(6)遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。
第2 题一个典型的编译程序通常由哪些部分组成?各部分的主要功能是什么?并画出编译程序的总体结构图。
答案:一个典型的编译程序通常包含8 个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。
其各部分的主要功能简述如下。
词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机内表达形式。
语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。
语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。
中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式的中间语言代码,如三元式或四元式。
中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。
目标代码生成程序:将优化后的中间代码程序转换成目标代码程序。
表格管理程序:负责建立、填写和查找等一系列表格工作。
表格的作用是记录源程序的各类信息和编译各阶段的进展情况,编译的每个阶段所需信息多数都从表格中读取,产生的中间结果都记录在相应的表格中。
编译程序的工作过程:词法分析、语法分析、语义分析、优化、目标代码生成

编译程序的⼯作过程:词法分析、语法分析、语义分析、优化、
⽬标代码⽣成
词法分析:也就是从左到右⼀个⼀个地读⼊源程序,识别⼀个单词或符号,并进⾏归类。
语法分析:在词法分析的基础上,将单词序列分解成各类语法短语,如“程序”语句“表达式”等
语义分析:审查源程序是否有语义的错误,当不符合语⾔规范的时候,程序就会报错。
代码优化:这个阶段是对前阶段的中间代码进⾏变换或改造,⽬的是使⽣成的⽬标代码更为⾼效,即节省时间和空间。
⽬标代码⽣成:也就是吧优化后的中间代码变换成指令代码或汇编代码。
编译原理实验四语义分析及中间代码生成

编译原理实验四语义分析及中间代码⽣成⼀、实验⽬的(1)通过上机实验,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的语义翻译⽅法。
(2)掌握⽬前普遍采⽤的语义分析⽅法─语法制导翻译技术。
(3)给出 PL/0 ⽂法规范,要求在语法分析程序中添加语义处理,对于语法正确的表达式,输出其中间代码;对于语法正确的算术表达式,输出其计算值。
⼆、实验内容(1)语义分析对象重点考虑经过语法分析后已是正确的语法范畴,本实验重点是语义⼦程序。
已给 PL/0 语⾔⽂法,在实验⼆或实验三的表达式语法分析程序⾥,添加语义处理部分,输出表达式的中间代码,⽤四元式序列表⽰。
(2) PL/0 算术表达式的语义计算:PL/0 算术表达式,例如:2+35 作为输⼊。
输出: 17PL/0 表达式的中间代码表⽰:PL/0 表达式,例如: a(b+c)。
输出: (+,b,c,t1)(,a,t1,t2)三、设计思想1.原理属性⽂法:是在上下⽂⽆关⽂法的基础上为每个⽂法符号(终结符或⾮终结符)配备若⼲个相关的“值”(称为属性)。
属性:代表与⽂法符号相关的信息,和变量⼀样,可以进⾏计算和传递。
综合属性:⽤于“⾃下⽽上”传递信息。
在语法树中,⼀个结点的综合属性的值,由其⼦结点的属性值确定。
S—属性⽂法:仅仅使⽤综合属性的属性⽂法。
语义规则: 属性计算的过程即是语义处理的过程。
对于⽂法的每⼀个产⽣式配备⼀组属性的计算规则,则称为语义规则。
(1)终结符只有综合属性,它由词法分析器提供。
(2)⾮终结符既可以有综合属性也可以有继承属性,⽂法开始符号的所有继承属性作为属性计算前的初始值。
(3)产⽣式右边符号的继承属性和产⽣式左边符号的综合属性都必须提供⼀个计算规则。
(4)产⽣式左边符号的继承属性和产⽣式右边符号的综合属性由其它产⽣式的属性规则计算。
⼀遍扫描的处理⽅法: 与树遍历的属性计算⽅法不同,⼀遍扫描的处理⽅法是在语法分析的同时计算属性值,⽽不是语法分析构造语法树之后进⾏属性的计算,⽽且⽆需构造实际的语法树。
第09章 语义分析和代码生成

24
9.3.2 简单变量
TEST语言简单变量声明的属性翻译文法如下: < declaration_stat > → int ID↑n@name-def↓n,t;
动作解释(注意所有符号有继承属性vartablep, datap, labelp): @name-def↓n, t的动作:查询符号表,从vartablep所指的前一 个位置起往回查直到第一个记录,若没有,将标识符名n及类型 1、datap的值填入符号表vartablep所指的位置,然后vartablep 加1;若有,报告错误:变量重复定义。
F*3.1416*R*(H+R) F3.1416*R*HR+* 波兰后缀表示(逆波兰式)多应用于表达式类的语言结 构,也能够通过操作符的扩充来表示其他的语言结构。 10
9.2.2 N-元表示:三元式
三元式的每条指令只有3个域。
三元式的一般表示如下: <操作符>,<操作数1>,<操作数2>
如算术表达式X+Y,可用一个三元式(+,X,Y) 来描述。三元式的第一个域是操作符(+),第二和 第三个域分别是两个操作数(Y和Z)。 三元式的缺点是优化较困难。
(1)波兰后缀表示(逆波兰式)(掌握) (2)N-元表示 (2-1)三元式(掌握) (2-2)四元式(掌握) (2-3)抽象机代码 (3)栈式抽象机及其汇编指令
9
9.2.1 波兰后缀表示
中缀表示 a+b
a+b*c (a+b)*c a:=b*c+b*d
波兰后缀表示 ab+
abc*+ ab+c* abc*bd*+:=
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
9.2 中间代码
精品课件
9.2 中间代码
波兰后缀表示除可用来表示表达式类的语言结构以外, 也能够通过操作符的扩充来表示其他的语言结构。
例(P171) 条 件 语 句 : if <expr> then <stmt1> else <stmt2> 可转换成波兰后缀表示:
<expr><label1>BZ<stmt1><label2>BR<stmt2 > 注意:在该波兰表示中,引入了BZ和BR操作符。
精品课件
9.2 中间代码
波兰后缀表示的特点: 操作符位于操作数之后。
例(P170) 算术表达式:F*3.1416*R*(H+R)
波兰后缀表示: F3.1416*R*HR+* 赋值表达式:S=F*3.1416/R*(H+R)
波兰后缀表示: SF3.1416*R/HR+*=
精品课件
9.2 中间代码
精品课件
9.2 中间代码
使用中间代码的优点: ➢不考虑机器的特性,使生成的中间代码较为简单。 ➢生成中间代码的编译程序移植性好,只需为该中 间代码开发一个解释器或者将中间代码翻译为目标 机指令就能在目标机上运行。 ➢在中间代码上更便于做优化处理。
常见的中间代码: ➢(1)波兰后缀表示 ➢(2)N-元表示
三元式 四元式
9.2 中间代码
用一个抽象机的汇编语言作为TEST编译器的目标语 言。TEST机的指令仅能作为TEST语言的目标。TEST 机的模拟程序直接从一个文件中读取汇编代码并执行 它,因此避免了由汇编语言翻译为机器代码的过程。 但是,这个模拟程序并非是一个真正的汇编程序,它 没有符号地址或标号。
9.2 中间代码
例(P171)条件语句if (X>Y) Z=X;else Z=Y+1;
可以用如下三Z,(1),(5)
(3) =,Z,X
(4) BR, ,(7)
(5) +,Y,1
(6) =,Z,(5)
(7) …
注意:操作符BMZ和BR分别表示零转移和无条
件转移。
精品课件
第9章 语义分析和代码生成(P169)
9.1 语义分析的概念 9.2 中间代码 9.3 声明的处理 9.4 表达式语句 9.5 if语句 9.6 while语句 9.7 for循环语句 9.8 write语句 9.9 read语句 9.10 过程调用和返回 9.11 语义分析及精代品课码件 生成实现
精品课件
9.2 中间代码
构建抽象机模型的基本原则:
➢1)与源语言的操作和数据的良好对应:编译程 序的前端将源程序中的每一个原始操作和原始数 据模式翻译成抽象机指令。
➢2)在目标机上的高效实现:抽象机的伪操作能 够迅速转换成目标机的机器指令。
➢3)虚拟体系结构:需要为抽象机体系构建一个 运行环境,以便在该环境中模拟语言的数据模式 和操作的相互作用。 精品课件
9.2 中间代码
将中缀表达式转换成波兰后缀表示的算法实现: 设置一个操作符栈,当扫描到操作数时,就立即
输出该操作数。当遇到操作符时,则要与栈顶操作 符比较其优先级,若栈顶操作符优先级高于栈外操 作符,则输出该栈顶操作符;反之,则栈外操作符 入栈。而对于赋值表达式,只需定义赋值操作符 “=”的优先级低于可在表达式中出现的其他操作 符。
➢1、可移植性:如果花很小的代价,就能将一个 程序移植到另一台机器上,那么称该程序是可移植 的。
➢2、可适应性:如果一个程序能够容易地进行修
改就能满足不同的用户和系统的需求,那么称该程
序是可适应的。
精品课件
9.2 中间代码
要将一个给定的编译程序从X机移植到Y机,如果给定 的编译程序已分成前端和后端两部分,而且这两部分之 间定义有良好接口,那么移植的主要工作仅仅是重写现 有编译程序的代码生成程序以产生Y机的代码。一种较 理想的接口形式是抽象机的汇编程序,即能够将源语言 的各种语法结构映射到该抽象机的伪操作上。
➢2)语义分析的另一个重要功能是要分析由语法分 析所识别出来的语句的意义并作相应的语义处理。 例如,对声明语句,用户通过这类语句声明程序中 要使用的变量,并说明其种类和类型等特性。语义 分析程序就要将变量名及其有关属性填入符号表, 以备后面使用。对于程序中的可执行语句,则要根 据该语句的语义生成相应精品的课件中间代码或目标代码。
学习重点
声明的处理 表达式语句 if语句 while语句 for循环语句 write语句 read语句 过程调用和返回精品课件
9.1 语义分析的概念
语义错误:在语法分析中,严格按文法(上下文 无关文法)来检查语句的语法是否正确,但有些语 句单看语法结构并没有错误,但考虑该语句所处的 上下文会引起错误,称这种错误为语义错误。在语 义分析时会处理语义错误。
精品课件
9.2 中间代码
四元式的一般形式:
<操作符>,<操作数1>,<操作数2>,<结果 >
其中,<结果>表示操作符操作的结果,该结果 通常是一临时变量,在以后可以由编译程序分配给一 个寄存器或者一个主存地址。四元式的优点是便于进 行例优(P化1处72理)。表达式(A+B)*(C+D)-E能够由下列四元 式序列表示:
+,A,B, T1 +,C,D,T2 *,T1,T2,T3 -,T3,E,T4
注意:T1、T2、T3和精品T课件4均是临时变量。
9.2 中间代码
要开发出可移植又适用的编译程序的一种方法是 使编译程序产生一种作为源程序中间形式的抽象机 的代码。而该抽象机的指令应当尽可能模仿所编译 的源语言的结构,且具备下列特点:
精品课件
9.2 中间代码
精品课件
9.2 中间代码
精品课件
9.2 中间代码
三元式的一般表示: <操作符>,<操作数1>,<操作数2>
例(P171)
表达式W*X+(Y+Z)可用如下三元式序 列表示:
(1) *,W, X
(2) +,Y, Z (3) +,(1),(2)
对每一个三元式都编上 号码,且对前面三元式的计 算结果的引用可用三元式的 精编品课号件 来表示。
例(P169) 考虑下段程序,有哪些语义错误? 1. { int a; 2. int b; 3. real a,c; 4. d=a+b; 5. }
精品课件
9.1 语义分析的概念
语义分析主要借助符号表记录的信息来实现语义 分析动作。常见的语义分析动作有:
➢1)对表达式中的操作数进行类型的一致性检查。 当发现类型不一致时,则强制或自动作相应的类型 转换。