-
2019-04-17 10:43:52
1.概述
1.1 定义
源程序的一种内部表示,不依赖目标机的结构,易于机械生成目标代码的中间表示。如果不生成中间代码而是直接生成机器语言或者汇编语言形式的目标代码,优点是编译时间短,缺点是目标代码执行效率和质量都比较低,移植性差。
1.2 表示形式
逆波兰式(后缀式)、三地址码(三元式、四元式)、抽象语法树、有向无环图。
1.3 地位
如下所示:
2.逆波兰式
2.1 定义
把运算量(操作数)写在前面,把运算符写在后面,因此又称为后缀表示法
2.2 案例
如下所示:
表达式语句 逆波兰式 a+b ab+ (a+b)*c ab+c* a+b*c abc*+ a=b*c+b*d abc*bd*+= 3.三元地址
3.1 定义
指每条代码包含一个运算和三个地址,两个地址用于存放运算对象,一个地址用于存放运算结果。其一般形式为
x=y op z。
3.2 四元式
3.2.1 定义
一个四元式具有四个域的记录结构,表示为:(op,arg1,arg2,result)。op为运算符;result存放运算结果;arg为运算对象,如果为空,则使用空格,留出位置。
3.2.2 案例
例:将 a=b*c+b*d用四元式形式 写成三地址码的赋值语句形式如下: 1) t1 = b*c 2) t2 = b*d 3) t3 =t1+t2 4) a = t3 写成四元形式如下: 1) (*,b,c,t1) 2) (*,b,d,t2) 3) (+,t1,t2,t3) 4) (=,t3, ,a)
3.3 三元式
3.3.1 定义
一个三元式具有三个域的记录结构,表示为:(op,arg1,arg2)。
3.3.2 案例
例:将 a=b*c+b*d用三元形式 (1) (*,b,c) (2) (*,b,d) (3) (+,(1),(2)) (4) (=,(3),a)
3.4 抽象语法树
3.4.1 定义
抽象语法树(Abstract Syntax Code,AST)是语法树的一种简化形式,是源程序的抽象语法结构的树状表示,树的每个节点都表示源代码中的一种结构。
3.5 有向无环图
3.5.1 定义
有向无环图(Directed Acyclic Graph,简称DAG)对表达式中的每个子表达式都有一个结点,内部结点表示运算符,它的孩子代表运算分量。DAG中代表公共子表达式的结点只出现一次,具有多个父结点。
更多相关内容 -
【编译原理/类C编译器】(四)中间代码生成+目标代码生成
2019-06-25 09:54:19目标代码:mips代码 接上篇:【编译原理/类C编译器】(三)语法分析 运行界面 说明 语法制导翻译(在语法分析过程中,随着分析的步步进展,在使用某个产生式进行推导或归约时便执行相应的语义子程序,完成既定的...说在前面
- 使用语言:javascript
- 语法分析:LL(1)
- 中间代码生成:三地址码 语法制导翻译
- 目标代码:mips代码
- 接上篇:【编译原理/类C编译器】(三)语法分析
运行界面
说明
语法制导翻译(在语法分析过程中,随着分析的步步进展,在使用某个产生式进行推导或归约时便执行相应的语义子程序,完成既定的翻译工作,生成中间代码)
写不动了,有时间再写,github在第一篇
-
编译原理课程设计 目标代码生成器
2021-04-13 08:30:17它依次把每条中间代码变换成目标代码,并且在一个基本块范围内考虑如何充分利用寄存器的问题。 代码生成器。它依次把每条中间代码变换成目标代码,并且在一个基本块范围内考虑如何充分利用寄存器的问题。 -
目标代码中间代码生成-四元式设计文档.doc
2021-09-25 20:47:38目标代码中间代码生成-四元式设计文档.doc -
编译原理中间代码生成器实现C++
2011-10-30 19:37:27编译原理中间代码生成器实现C++编译原理中间代码生成器实现C++ -
语义分析和中间代码生成.pptx
2020-04-06 00:23:514.1 概 述 4.1.1 语义分析的概念 一个源程序经过词法分析语法分析之后表明该源程序在书写上是正确的并且符合程序语言...直接生成机器语言或汇编语言形式的目标代码的优点是编译时间短且无需中间代码到目标代码的翻译而 -
编译目标代码产生器,将编译的中间代码转换成需要的目标代码如c/c++等
2009-05-26 12:09:08目标代码产生器,将编译的中间代码转换成需要的目标代码如c/c++等 -
编译原理课程设计——目标代码生成器
2011-09-13 14:50:48能完成指定寄存器个数的情况下降一中间代码程序段翻译成会变语言目标代码(汇编指令应包括加、减、乘、除),要求指令条数最少的情况下,尽量使用寄存器,尽量少访问内存,这样才能做到运行效率高。 -
编译原理--中间代码生成
2020-01-08 15:25:16文章目录基础DAG三地址代码问题声明语句的翻译表达式和赋值语句的翻译控制流翻译布尔表达式的翻译switch 语句的翻译过程调用的翻译回填 基础 DAG 语法树是一种图形化的中间表示。但语法树中,公共子表达式每出现一次...基础
DAG
语法树是一种图形化的中间表示。但语法树中,公共子表达式每出现一次,就有一个对应的子树,产生了大量冗余,
因此定义了另一种中间表示:有向无环图(Directed Acyclic Graph, DAG)
有向无环图的构造与抽象语法树类似。
三地址代码
一般包括一个运算符和之多三个运算分量(地址),所以叫做三地址代码。这里的地址包括:变量、常量、临时变量。
- 指令集合
- 运算/赋值指令:x=y op z ,x = op y
- 复制指令:x=y
- 无条件转移指令:goto L
- 条件转移指令:if x goto L ,ifFalse x goto L
- 条件转移指令:if x relop y goto L
- 过程调用/返回 p(x1, x2, …, xn)
• param x1 //设置参数
• param x2
• …
• param xn
• call p, n //调用子过程p,n为参数个数 - 带下标的复制指令:x=y[i] x[i]=y • 注意:i表示离开数组位置第i个字节,而不是数组的第i个元素
- 地址/指针赋值指令: • x=&y x=*y *x=y
- 三地址代码的四元式表示
格式(字段): op arg1 arg2 result
如:+ x y z
对于有些指令,一些参数是空缺的,如
param x1 null null
[if goto] x null L
- 三地址代码的三元式表示
op arg1 arg2
使用三元式的位置来引用三元式的运算结果
- 三地址代码的间接三元式表示
包含了一个指向三元式的指针的列表 我们可以对这个列表进行操作,完成优化功能;操作时不 需要修改三元式中的参数
- 静态单赋值SAA
问题
声明语句的翻译
PPT 24-54
表达式和赋值语句的翻译
- 数组引用生成代码的翻译方案
非终结符号L的三个综合属性
- L.addr指示一个临时变量,计算数组引用的偏移量 ij * wj
- L.array是一个指向数组名字对应的符号表条目的指针, L.array.base为该数组的基地址
- L.type是L生成的子数组的类型,对于任何数组类型t,其宽度由 t.width给出,t.elem给出其数组元素的类型
控制流翻译
- 文法:B表示布尔表达式,S代表语句 S → if (B) S1 ; S → if (B) S1 else S2 ;S → while (B) S1 . 代码的布局见下图
- 继承属性
- B.true:B为真的跳转目标
- B.false:B为假的跳转目标
- S.next:S执行完毕时的跳转目标
例: S ⟶ i f B t h e n S 1 S\longrightarrow if\ B\ then\ S_1 S⟶if B then S1
布尔表达式的翻译
- 当布尔表达式的计算用于跳转分治
布尔表达式翻译的主要语义动作是跳转,而跳转的标签主要根据短路规则来确定。
- 当布尔表达式的计算用于赋值
采用临时变量的方法
switch 语句的翻译
过程调用的翻译
回填
布尔表达式用于语句的控制流时,它总是在取值true时和取值false 时分别跳转到某个位置
-
引入两个综合属性
- truelist: 包含跳转指令(位置)的列表,这些指令在取值true时执行
- falselist:包含跳转指令(位置)的列表,这些指令在取值false时执行
-
辅助函数
- Makelist(i):创建一个只包含i的列表
- Merge(p1,p2):将p1和p2指向的列表合并
- Backpatch(p,i):将i作为目标标号插入到p所指列表中的各指令中
-
控制转移语句的回填
M的作用就是用M.instr记录下一个指令的位置 • N的作用是生成goto指令坯,N.nextlist只包含这个指令 的位置
- 指令集合
-
【编译原理】中间代码(一)
2017-12-05 15:08:56在编译器的分析-综合模型中,前端对源程序进行分析并产生中间表示,后端在此基础上生成目标代码。...和中间代码相关的内容包括中间代码表示、静态类型检查和中间代码生成,本文将讨论关于中间代码表示的内容。在编译器的分析-综合模型中,前端对源程序进行分析并产生中间表示,后端在此基础上生成目标代码。理想情况下,和源语言相关的细节在前端分析中处理,而关于目标机器的细节则在后端处理。和中间代码相关的内容包括中间代码表示、静态类型检查和中间代码生成,本文将讨论关于中间代码表示的内容。
有向无环图
表达式的有向无环图(Directed Acyclic Graph,简称DAG)与语法分析树类似,一个DAG的叶子结点对应于原子运算分量,内部结点对应于运算符。与语法分析树不同的是,如果DAG中一个结点N表示一个公共子表达式,那么N可能有多个父结点。举个例子,表达式
a+a*(b-c)+(b-c)*d
的DAG如下:DAG的每个结点通常作为一条记录被存放在数组中,一个记录包括的结点信息有:
- 结点标号:如果记录表示叶子结点,那么结点标号是该结点的文法符号;如果记录表示内部结点,那么结点标号是运算符;
- 词法值:如果记录表示叶子结点,那么记录还包括该结点的词法值,通常是一个指向符号表的指针或者一个常量;
- 左右子结点:如果记录表示内部结点,那么记录还包括该结点的左右子结点。
由于一个DAG的结点都会保存在一个记录数组中,因此我们可以通过数组下标引用某个记录从而获取结点信息,这个数组下标称为相应结点的值编码。
对图1的DAG,它的记录数组为:
其中,左边的下标是每个结点的值编码,并且在某些记录中可以包括值编码。例如:对于第5条记录,它表示内部结点”-“,该结点左边的子结点是叶子结点”b”,右边的子结点是叶子结点”c”,由于代表b和c的记录已经存在并且它们的值编码分别为2和3,因此内部结点”-“的记录为(-, 2, 3)。
三地址代码
三地址代码是形如
x = y op z
的指令集合,之所以名为“三地址代码”,是因为指令x = y op z
具有三个地址:两个运算分量y和z,一个结果变量x。由于三地址代码会对多运算符算术表达式和控制流语句的嵌套结构进行拆分,因此适用于目标代码的生成和优化。三地址代码基于两个基本的概念:地址和指令。简单地说,地址就是运算分量,指令就是运算符,一个地址的表现形式可以是变量名、常量或者编译器生成的临时变量。下面是几种常见的三地址指令形式:
除此之外,另一种方式是用记录表示三地址代码中的每条指令,四元式、三元式和间接三元式是三种用记录表示三地址代码的方式。
四元式
一个四元式是一条表示三地址指令的记录,它有4个字段:
- op:表示一个运算符;
- arg1:表示第一个运算分量;
- arg2:表示第二个运算分量;
- result:表示结果变量。
一个四元式中可能用到了所有4个字段,也可能只用到了其中几个字段,它的几个特例如下:
- 形如
x = minus y
的单目运算符指令不使用arg2字段,”minus”表示单目减运算符; - 形如
x = y
的赋值指令不使用arg2字段,并且它的op字段是”=”; - 形如
param x
的参数传递指令不使用arg2和result字段; - 条件和非条件转移指令将目标标号放入result字段。
下图是一个例子,左边给出了三地址代码,右边是对应的四元式表示:
三元式
通过图2我们发现,一段三地址代码对应的四元式被存放在一个记录数组中,这一点和DAG结点的记录数组很像;另外,四元式中的result字段主要被用于保存临时变量名,这个临时变量是由编译器生成的。如果我们仿照DAG的记录数组用值编码表示临时变量的地址,那么就可以省略四元式中的result字段,三元式就是由此而来的。
一个三元式只有3个字段:op、arg1和arg2,它们的含义和在四元式中相同。为了取代四元式中的result字段,三元式用值编码表示结果变量的地址。图2中三地址代码的三元式表示如下:
在图3(b)中,表格左边的数字是值编码,它表示三元式的结果变量的地址,并且这些值编码可以在三元式中被使用(使用的时候用括号括起来)。另外,对形如
x=y
的赋值指令,和四元式不同的是,三元式的op字段是”=”,arg1字段是”x”,arg2字段是”y”。间接三元式
三地址代码的三元式表示存在一个问题,如果记录数组中的某条记录R的位置发生改变,那么所有使用到记录R的值编码的记录都需要更新。举个例子,在图3(b)中,如果把第1和第2条记录的位置互换,那么第3和第4条记录的内容都会发生改变。为了解决这个问题,提出了用间接三元式来表示三地址代码。
一个间接三元式在三元式的基础上增加了一个列表,这个列表包含了指向三元式的指针。仍以例子说明,下图是图3中三元式的间接三元式:
图4(a)是图3(b)的间接三元式,它使用了一个instruction数组保存要执行的指令,每条指令是一个指向某个三元式的指针。这样的话,当我们改变指令顺序时,就不用再更新三元式了,如图4(b)所示。
静态单赋值形式
静态单赋值(Static Single Assignment,简称SSA)形式是另一种中间表示形式,它和三地址代码的主要区别在于:
第一,SSA中的所有赋值都是针对具有不同名字的变量的,这也是“静态单赋值”名字的由来。这一特性如下图中表示:
第二,由于同一个变量可能在两个不同的控制流路径中被定值,因此SSA使用一种被称为φ函数的表示规则将这个变量的两处定值合并起来。这一特性如下图所示:
欢迎关注微信公众号fightingZhヾ(◍°∇°◍)ノ゙ -
编译原理完整学习笔记(八):目标代码生成
2020-08-19 10:37:42文章目录目标代码生成一、目标代码生成概述1.1 任务1.2 输入1.3 输出二、抽象计算机模型三、...将分析、翻译、优化后的中间代码变换成目标代码 1.2 输入 源程序的中间表示,以及符号表中的信息 类型检查均已完成 1.3 -
编译原理( 词法分析程序 语法分析程序 语义分析程序 中间代码生成程序 代码优化程序 目标代码生成程序 ...
2020-02-26 20:46:48词法分析程序:读字符流的源程序、识别单词 语法分析程序:层次分析,把源程序的单词序列组成语法短语(表示成语法树). 语义分析程序:语义审查(静态语义) ...目标代码生成程序 :转换为机器指令上的绝对指... -
编译原理(十三)——中间代码生成(1)
2020-10-12 23:40:35一、生成中间代码的目的 便于优化 让生成的目标代码效率更高 优化不等同于对代码的精简和算法的优化 (对于高级程序设计...中间代码起到一个将一对一翻译转换成一对多对一的关系,通过编译前段可以不用改变,编译后 -
【编译原理】第六章 中间代码生成
2019-07-11 23:58:30中间代码也叫中间语言(Intermediate code /language)是:源程序的一种内部表示,不依赖目标机的结构,复杂性介于源语言和机器语言之间。 中间代码常见的几种形式 1、后缀式 2、图表示法 抽象语法树、DAG图 3、三... -
第25讲 目标代码生成.pdf
2020-03-16 18:51:09编译原理 目标代码生成 编译程序总框 源程序 词法分析器 单词符号 语法分析器 理 管 表 号 符 语法单位 理 处 错 出 视频区域 语义分析与中间代码生成器 中间代码(四元式) 优化段 中间代码(四元式) 目标代码生成器 ... -
内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成
2010-04-28 17:22:48内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成 -
编译实验(三)目标代码生成
2018-01-28 17:00:09而代码生成则是通过四元式来完成。我们先从简单开始做起。 编译实验项目下载链接:http://download.csdn.net/download/supersmart_dong/10224159 例如四元式(j,0,0,7)这样的,代码生成只需要一个goto语句;(j=,A,B... -
编译原理(十六)——中间代码优化(1)
2020-10-23 11:38:21编译器后端对目标代码进行优化 两个编译器必须等价,编译的结果必须是正确的,即使有99.99%的可能性是不正确的,但是效率很好也不行,正确性是根本。 二、中间代码优化的分类 从优化的种类来看,中间代码的优化可... -
编译原理:中间代码生成
2020-08-22 15:42:19(2)使编译程序改变目标机更容易;易于编译器的移植 (3)使编译程序的结构在逻辑上更为简单明确,以中间语言为界面,编译前端和后端的接口更清晰。 中间语言的形式:后缀式,图表示法,三元式 编译过程中... -
【编译原理】语义分析及中间代码生成(C/C++源码+实验报告)
2021-10-23 16:47:03文章目录1 实验目的和内容1.1 实验目的1.2 实验内容...(1)通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析 所识别的语法范畴变换为某种中间代码的语义翻译方法。 (2)掌握目前普遍采用的语义分析方法─ -
【编译原理】中间代码优化(一) 优化技术大观
2020-05-31 18:07:27优化其实可以在编译的各个阶段进行,但最主要的一类优化是在目标代码生成以前,对语法分析、语义分析后产生的中间代码进行优化。这是因为中间代码的形式不依赖于具体的计算机,它可以是三地址码的形式,所以相应的... -
【编译原理】中间代码(二)
2017-12-13 09:37:46本文是关于中间代码的第二篇文章。在第一篇文章中,我们介绍了3种表示中间代码的方式,本文将接着介绍和静态类型检查以及中间代码生成相关的内容。 -
一张图解释编译过程词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成
2017-10-04 11:00:31编译过程概述 -
语义分析及中间代码生成
2020-11-08 09:40:46实验四 语义分析及中间代码生成 1.实验目的 (1)通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析 所识别的语法范畴变换为某种中间代码的语义翻译方法。 (2)掌握目前普遍采用的语义分析方法──语法... -
编译原理 第七章复习题 语法制导翻译和中间代码
2019-06-18 08:53:20中间代码是介于源语言程序和什么之间的一种代码?(D)。 A 源代码 B 机器语言 C 汇编语言 D 目标代码 在编译程序中与生成中间代码的目的无关的是(B)。 A 便于目标代码优化 B 便于存储空间的组织 C 便于目标代码... -
BIT-Minicc编译原理实验-MIPS汇编目标代码生成最傻瓜的思路+问题记录
2020-06-26 22:42:26编译原理课程实验要求为BIT-Minicc编译器开发目标代码生成部分,本文针对...中间代码生成目标代码比直接从AST要方便许多,前提是中间代码生成时要解决变量读取和运算过程中临时变量的问题,即将所有操作数都放入寄存器 -
中间代码生成及编译器后端概述
2020-08-15 10:13:05经过了词法分析,语法分析,语义分析之后就到了中间代码生成阶段 中间代码有两种形式: 三地址码 语法结构树(简称语法树),这和之前的语法分析树不同 三地址码 三地址码由类似汇编语言的指令序列组成,每个指令最多有三... -
编译原理之中间代码生成
2020-04-07 12:35:44如果不生成中间代码而是直接生成机器语言或者汇编语言形式的目标代码,优点是编译时间短,缺点是目标代码执行效率和质量都比较低,移植性差。 为什么不直接翻译成机器码呢,而多此一举生成中间代码再转换?(代码的... -
编译原理-中间代码的生成
2020-03-30 19:17:46一、中间代码简介 中间代码应具备的特性: 1)便于语法制导翻译 2)既与机器指令的结构相近,又与具体机器无关 使用中间代码的好处: 1)一是便于编译器程序的开发和移植 2)二是代码进行优化处理 中间代码的... -
编译原理——中间代码生成
2016-03-28 22:37:22源语言->中间代码->目标语言 中间代码(Intermediate Representation或者IR):复杂性介于源程序语言和机器语言的一种表示形式。 编译程序锁使用的中间代码有多种形式。常见的有逆波兰记号,三元式,四元式,和树形...