编译原理第8章-中间代码生成

合集下载

中间代码生成实验报告

中间代码生成实验报告

一、实验目的1. 理解编译原理中中间代码生成的基本概念和作用。

2. 掌握中间代码生成的常用算法和策略。

3. 提高对编译器构造的理解和实际操作能力。

二、实验环境1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:Eclipse三、实验内容1. 中间代码生成的基本概念2. 中间代码的表示方法3. 中间代码生成算法4. 实现一个简单的中间代码生成器四、实验步骤1. 了解中间代码生成的基本概念中间代码生成是编译过程中的一个重要环节,它将源程序转换成一种中间表示形式,便于后续的优化和目标代码生成。

中间代码生成的目的是提高编译器的灵活性和可维护性。

2. 研究中间代码的表示方法中间代码通常采用三地址代码(Three-Address Code,TAC)表示。

TAC是一种低级表示,由三个操作数和一个操作符组成,例如:(t1, t2, t3) = op,其中t1、t2、t3为临时变量,op为操作符。

3. 学习中间代码生成算法中间代码生成算法主要包括以下几种:(1)栈式中间代码生成算法(2)归约栈中间代码生成算法(3)递归下降中间代码生成算法4. 实现一个简单的中间代码生成器本实验采用递归下降中间代码生成算法,以一个简单的算术表达式为例,实现中间代码生成器。

(1)定义语法规则设表达式E由以下语法规则表示:E → E + T | E - T | TT → T F | T / F | FF → (E) | i(2)设计递归下降分析器根据语法规则,设计递归下降分析器,实现以下功能:①识别表达式E②识别项T③识别因子F(3)生成中间代码在递归下降分析器中,针对不同语法规则,生成相应的中间代码。

例如:当遇到表达式E时,生成以下中间代码:(t1, t2, t3) = op1(t1, t2) // op1表示加法或减法(t4, t5, t6) = op2(t4, t5) // op2表示乘法或除法(t7, t8, t9) = op3(t7, t8) // op3表示赋值(4)测试中间代码生成器编写测试用例,验证中间代码生成器的正确性。

编译原理课件-中间代码生成

编译原理课件-中间代码生成
6/75
Wensheng Li BUPT @ 2008
賦值語句a:=b*-c+b*-c的圖表示法
語法樹表示: assign
dag圖形表示: assign
a
+
a
+
*
*
b uminus b uminus
c
c
* b uminus
c
Wensheng Li BUPT @ 2008
7/75
二、三地址代碼
三地址代碼
賦值語句a:=b*-c+b*-c的三元式表示
Wensheng Li BUPT @ 2008
op
arg1
arg2
(14) uminus
c
(15)
*
b
(14)
(16) uminus
c
(17)
*
b
(16)
(18)
+
(15)
(17)
(19)
:=
a
(18)
12/75
語句x[i]:=y和x:=y[i]的三元式序列
EE1+E2
{ E.place=newtemp; if (E1.type==integer) && (E2.type==integer) { emit(E.place := E1.place + E2.place); E.type=integer; }; else if (E1.type==real) && (E2.type==real) { emit(E.place := E1.place real+ E2.place); E.type=real; }; else if (E1.type==integer) && (E2.type==real) { u=newtemp; emit(u := inttoreal E1.place); emit(E.place := u real+ E2.place); E.type=real; }; else if (E1.type==real) && (E2.type==integer) { u=newtemp; emit(u := inttoreal E2.pace); emit(E.place := E1.place real+ u); E.type=real; }; else E.type=type_error; }

编写中间代码生成程序

编写中间代码生成程序

武夷学院实验报告课程名称:编译原理项目名称:编写中间代码生成程序二、实验过程记录1:(一)实验目的:在分析理解PL/0编译程序的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。

(二)实验内容:对PL/0语言作如下功能扩充:(1)扩充条件语句的功能使其为:if <条件> then <语句>[else <语句>](2)增加repeat语句,格式为:repeat <语句> {; <语句>} until <条件>(三)实验过程语句语法描述图:1注:实验过程记录要包含实验目的、实验原理、实验步骤,页码不够可自行添加。

EBNF表示:<程序>::= <分程序>.<分程序>::= [<常量说明部分>][<变量说明部分>][<过程说明部分>]<语句> <常量说明部分>::= const<常量定义>{,<常量定义>};<常量定义>::= <标识符>=<无符号整数><无符号整数>::= <数字>{<数字>}<标识符>::= <字母>{<字母>|<数字>}<变量说明部分>::= var<标识符>{, <标识符>};<过程说明部分>::= <过程首部><分程序>{;<过程说明部分>}<过程首部>::= procedure<标识符>;<语句> ::= <赋值语句>|<条件语句>|<当循环语句>|<过程调用语句><复合语句>|<读语句>|<写语句>|<空><赋值语句>::= <标识符> := <表达式><表达式> ::= [+|-]<项>{<加法运算符><项>}<项>::= <因子>{<乘法运算符><因子>}<因子>::= <标识符>|<无符号整数>| ‘ ( ’ <表达式> ‘ ) ’<加法运算符>::= +|-<乘法运算符>::= *|/<条件>::= <表达式><关系运算符><表达式>|odd<表达式>程序描述图:三、实验结果与讨论:2实验结果:实验小结:通过在PL/0的编译程序的实验中,认识了许多关于中间代码生成的知识,掌握了中间代码中的作用所谓“中间代码”是一种结构简单、含义明确的记号系统,这种记号系统复杂性介于源程序语言和机器语言之间,容易将它翻译成目标代码,产生中间代码的过程叫中间代码生成。

编译原理中间代码生成

编译原理中间代码生成

编译原理中间代码生成在编译原理中,中间代码生成是编译器的重要阶段之一、在这个阶段,编译器将源代码转换成一种中间表示形式,这种中间表示形式通常比源代码抽象得多,同时又比目标代码具体得多。

中间代码既能够方便地进行优化,又能够方便地转换成目标代码。

为什么需要中间代码呢?其一,中间代码可以方便地进行编译器优化。

编译器优化是编译器的一个核心功能,它能够对中间代码进行优化,以产生更高效的目标代码。

在中间代码生成阶段,编译器可以根据源代码特性进行一些优化,例如常量折叠、公共子表达式消除、循环不变式移动等。

其二,中间代码可以方便地进行目标代码生成。

中间代码通常比较高级,比目标代码更具有表达力。

通过中间代码,编译器可以将源代码转换成与目标机器无关的形式,然后再根据目标机器的特性进行进一步的优化和转换,最终生成目标代码。

中间代码生成的过程通常可以分为以下几步:1.词法分析和语法分析:首先需要将源代码转换成抽象语法树。

这个过程涉及到词法分析和语法分析两个步骤。

词法分析将源代码划分成一个个的词法单元,例如标识符、关键字、运算符等等。

语法分析将词法单元组成树状结构,形成抽象语法树。

2.语义分析:在语义分析阶段,编译器会对抽象语法树进行静态语义检查,以确保源代码符合语言的语义规定。

同时,还会进行类型检查和类型推导等操作。

3.中间代码生成:在中间代码生成阶段,编译器会将抽象语法树转换成一种中间表示形式,例如三地址码、四元式、特定的中间代码形式等。

这种中间表示形式通常比较高级,能够方便进行编译器的优化和转换。

4.中间代码优化:中间代码生成的结果通常不是最优的,因为生成中间代码时考虑的主要是功能的正确性,并没有考虑性能的问题。

在中间代码生成之后,编译器会对中间代码进行各种优化,以产生更高效的代码。

例如常量折叠、循环优化、死代码删除等等。

5.中间代码转换:在完成了中间代码的优化之后,编译器还可以对中间代码进行进一步的转换。

这个转换的目的是将中间代码转换成更具体、更低级的形式,例如目标机器的汇编代码。

编译原理与中间代码生成技术

编译原理与中间代码生成技术

编译原理与中间代码生成技术编译原理是计算机科学中的重要理论基础,它研究的是将高级语言翻译成机器语言的转换过程。

而中间代码生成技术则是编译原理中的一个关键环节,它负责将源代码转换为中间表示形式,为后续的优化和目标代码生成做准备。

本文将介绍编译原理的基本概念和中间代码生成技术的原理与应用。

一、编译原理基础编译原理是计算机科学中的一个重要分支,它研究的是高级语言程序如何转换为机器语言的过程。

编译原理包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等多个阶段。

其中,中间代码生成是编译原理的一个关键环节,它将源代码转换为中间表示形式,以便后续的优化和目标代码生成。

二、中间代码生成技术的原理中间代码是源代码与目标代码之间的一种中间表示形式。

它既比源代码更容易理解,又比目标代码更容易生成和优化。

中间代码生成技术的目的是将源代码转换为中间代码,为后续的优化和目标代码生成做准备。

中间代码生成技术的原理可以用以下步骤来描述:1. 词法分析:将源代码分割成一个个语法单元,比如标识符、关键字、操作符等。

词法分析器会根据事先定义好的词法规则,将源代码转换为词法单元序列。

2. 语法分析:将词法单元序列转换为抽象语法树(AST)。

语法分析器会根据事先定义好的语法规则,分析词法单元序列所组成的语法结构,并构建出相应的抽象语法树。

3. 语义分析:对抽象语法树进行语义检查和类型推断。

语义分析器会检查语法结构中是否存在语义错误,并为表达式推导出对应的类型信息。

4. 中间代码生成:将语法树转换为中间代码表示形式。

中间代码生成器会根据语义信息和事先定义好的转换规则,将语法树转换为中间代码表示形式。

三、中间代码生成技术的应用中间代码生成技术广泛应用于编译器、解释器和虚拟机等领域。

以下是中间代码生成技术在这些领域的具体应用场景:1. 编译器:编译器是将高级语言程序转换为机器语言的工具。

中间代码生成技术在编译器中起到了至关重要的作用,它能够将源代码转换为中间代码表示形式,为后续的代码优化和目标代码生成做准备。

编译原理(第2版)课后习题答案详解

编译原理(第2版)课后习题答案详解

第1 章引论第1 题解释下列术语:(1)编译程序(2)源程序(3)目标程序(4)编译程序的前端(5)后端(6)遍答案:(1)编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。

(2)源程序:源语言编写的程序称为源程序。

(3)目标程序:目标语言书写的程序称为目标程序。

(4)编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。

通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符号表管理等工作。

(5)后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。

(6)遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。

第2 题一个典型的编译程序通常由哪些部分组成?各部分的主要功能是什么?并画出编译程序的总体结构图。

答案:一个典型的编译程序通常包含8 个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。

其各部分的主要功能简述如下。

词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机内表达形式。

语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。

语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。

中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式的中间语言代码,如三元式或四元式。

中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。

目标代码生成程序:将优化后的中间代码程序转换成目标代码程序。

表格管理程序:负责建立、填写和查找等一系列表格工作。

表格的作用是记录源程序的各类信息和编译各阶段的进展情况,编译的每个阶段所需信息多数都从表格中读取,产生的中间结果都记录在相应的表格中。

编译原理中的中间代码生成

编译原理中的中间代码生成

编译原理中的中间代码生成编译原理是计算机科学的一门重要课程。

在编译器的构造过程中,中间代码生成是其核心部分之一。

它是将源代码翻译为目标代码的重要中间阶段。

中间代码生成的过程涉及到链表、树,生成三元式、四元式等多种中间形式。

本文将介绍中间代码生成的过程和其在编译中的作用。

一、中间代码的概念中间代码是指在源程序和目标程序之间所生成的一系列指令的集合。

目标代码是指机器可执行的二进制代码,而中间代码则是一种可传递、可处理和可修改的编译代码形式。

中间代码属于一种中间状态,它不是源代码也不是目标代码,但可以被转换成目标代码。

中间代码可以基于语法树、语法分析栈、语法分析表进行生成,生成的中间代码需要满足语言语法结构和语义规则。

二、中间代码生成的流程在编译过程中,中间代码生成是指将源代码转换成中间代码的过程。

它是在词法分析、语法分析和语义分析阶段之后完成的。

下面介绍一下中间代码生成的流程。

1.源代码转换为语法树编译器通过词法分析和语法分析将源代码转换成语法树。

语法树是一种树形结构,它记录了源代码中各个语句的组成情况。

2.语法树进行语义分析在语法分析之后,编译器进行语义分析,检查语法树的合法性,然后根据语言的语义规则对语法树进行标注。

标注的内容包括符号表信息、数据类型等。

3.中间代码的生成在语义分析后,编译器进入中间代码的生成阶段,生成语句的中间代码。

中间代码通常采用三元式或四元式等形式。

三元式包含操作符、操作数以及结果的地址,四元式中还包括了类型信息。

4.中间代码优化在中间代码生成的过程中,编译器会尽可能地优化中间代码。

可以对中间代码进行多种优化,如常量合并、变量替换、公共子表达式消除等。

5.中间代码转换为目标代码在中间代码生成后,编译器将中间代码转换为目标代码。

目标代码可以是汇编代码或机器代码等不同形式的二进制代码。

三、中间代码生成优化的意义编译器中间代码优化的目标是提高程序的执行效率和降低其资源消耗。

执行效率的提高可以通过以下方式实现:1.减少内存使用编译器可以通过删除冗余代码、去除死代码和不必要的变量等方式来减少中间代码的内存使用。

编译原理课件-中间代码生成

编译原理课件-中间代码生成
(2)E→E1 and E2 { backpatch(E 1.true, E2.codebegin); E.Codebegin:= E 1.codebegin; E.true:= E 2.true; E.false:= merge(E 1.false, E2false);}
(3) E→not E1 { E.true:= E 1.false; E.Codebegin:= E 1.codebegin; E.false:= E 1.true
(翻譯不是最優)
語句 if a<b or c<d and e<f then S1 else S2 的四元式
(1) if a<b goto (7) //轉移至(E.true )
(2) goto (3)
(3) if c<d goto (5)
(4) goto (p+1)
//轉移至(E.false)
(5) if e<f goto (7) (6) goto (p+1) (7)( S1的四元式
不同層次的中間代碼
源語言
中間代碼
(高級語言) (高級)
中間代碼 (中級)
中間代碼 (低級)
float a[10][20]; a[i][j+2];
t1 = a[i, j+2]
t1 = j + 2 t2 = i * 20 t3 = t1 + t2 t4 = 4 * t3 t5 = addr a t6 = t5 + t4 t7 = *t6
語義描述使用的變數和過程:
E.true : “真”鏈, E.false : “假”鏈
E.codebegin : E 的第一個四元式
Nextstat: 下一四元式地址
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
产生一条中间代码的子程序GenCode():
运算分量(栈顶和次栈顶)类型检查; 如需类型转换:生成类型转换中间代码; 生成操作的中间代码; 从栈中删除运算分量的语义信息;
简单表达式中间代码 的LR语法制导
E T
E E+T
#GenCode(+)
TP
T T×P
#GenCode(×)
PC
{Push((C.type,C.Arg))}
如:a:= b×c+b×d
三元式 (1) (×, b, c) (2) (×, b, d) (3) (+, (1), (2)) (4) (:=, (3), a)
四元式 (1) (×, b, c, t1) (2) (×, b, d, t2) (3) (+, t1, t2, t3) (4) (:=, t3, a, -)
表达式的语义信息:
表达式种类:E.kind 表达式的类型:E.type 表达式的结果值ARG:E.Arg 或 ARG(E)
标号L:ARG(L)= LabelForm’(L) 整数C:ARG(C)= ValueForm’(C) 源程序变量X:ARG(X)= AddrForm’(L,Off, Mode) 临时变量T:ARG(T)= AddrForm’(-1, off, Mode) 表达式的中间代码:E.tuple
V V1[E] #IndexVar IndexVar: L:= Sem[top-1]; R:= Sem[top];
ResultArg:=NewTemp(indir); ResultType:= L.Type.ElemType; Low:=L.Type.Low;Size:= L.Type.ElemSize; Generate(SUBI, R.Arg, Low, t1); Generate(MULI, t1, Size, t2); Generate(AADD, L.Arg,t2, ResultArg); POP(2); Push((ResultType,ResultArg)); V V1 #DenoVar DenoVar: ResultArg:=NewTemp(indir); ResultType:= Sem[top].Type.BaseType; Generate(ASSIG, Sem[top].Arg, ResultArg) POP(1); Push((ResultType, ResultArg))
表达式中间代码生成的例子
a[5+i].x + m * z 其中,i,m:integer; z:real; a:array[1..100] of rt; rt = record y:int;x:real end
1. (ADDI, 5, i, t1) 2. (SUBI, t1 ,1, t2) 3. (MULTI, t2, 2,t3) 4. (AADD, a , t3, t4)
语法制导:
(WRITE, E.Arg);Leabharlann S Read(V) #READ
S Write(E) #WRITE
赋值语句:
赋值语句形式:
V:=E
Vptr:=V1ptr
f:=E
赋值语句的中间代码形式:
(ASSIGN,Arg1,Arg2,n)
Vstr:=V1str
或 (FLOAT,Arg1,Arg2)
S L:= R
L.tuple R.tuple (ASSIGN, R,Arg, L.Arg, size) 或 (FLOAT, R.Arg, L.Arg)
第八章 中间代码生成
中间语言 简单表达式的中间代码生成 原子语句的中间代码生成 结构语句的中间代码生成 声明的中间代码
中间语言
后缀式----逆波兰式 三地址中间代码(三元式、四元式) 图结构中间代码(语法树、DAG)
三地址中间代码
三元式:i:(,op1,op2) 四元式:( ,op1,op2,result)
5. (AADD , t4, 1, t5) 6. (FLOAT , m, t6) 7. (MULTF , t6, z, t7) 8. (ADDF , t5, t7,t8)
原子语句的中间代码
输入输出语句:
S Read(V) S Write(E)
V.tuple (READ, V.Arg)
E.tuple
简单表达式的中间代码形式
E C
Tuple(E)=空,ARG(E)= C.val
E x
Tuple(E)=空,ARG(E)= x.val
E E1 E2
Tuple(E)= Tuple(E1)|| Tuple(E2) || (,ARG(E1),ARG(E2),t)
ARG(E)= t, t是临时变量
变量中间代码结构
• V id • V V1.id
V.tuple=空
V1.tuple (AADD,V1.Arg,offset(id),V.Arg)
• V V1[E] • V V1
V1.tuple E.tuple (SUBI, E.Arg, low, t1) (MULTI, t1, size, t2) (AADD, V1.Arg, t2, V.Arg)
V1.tuple (ASSIGN,V1.Arg, V.Arg)
变量中间代码的LR语法制导
V id
{Push((VarType(entry),VarArg(entry)))} V V1.id #FieldVar
FieldVar: L:= Sem[top-1]; R:= Sem[top]; ResultArg:= NewTemp(indir); Generate(AADD,L.Arg, R.arg,ResultArg) Pop(2),Push((R.type, ResultArg))
P id {Push(VarType(entry),VarArg(entry))}
P (E)
简单表达式的LL语法制导
E T Es Es +T #GenAdd Es Es T PTs Ts *P #GenMul Ts Ts P id #VPrimary P C #CPrimary P (E) GenAdd : GenCode(+) ; GenMul: GenCode(×) Vprimary,Cprimary: 同上。
相关文档
最新文档