精华内容
下载资源
问答
  • 中间代码生成及编译器后端概述

    千次阅读 2020-08-15 10:13:05
    中间代码生成及编译器后端概述 中间代码的生成 经过了词法分析,语法分析,语义分析之后就到了中间代码生成阶段 中间代码有两种形式: 三地址码 语法结构树(简称语法树),这和之前的语法分析树不同 三地址码 三地址码...

    中间代码生成及编译器后端概述

    中间代码的生成

    经过了词法分析,语法分析,语义分析之后就到了中间代码生成阶段

    中间代码有两种形式:

    • 三地址码
    • 语法结构树(简称语法树),这和之前的语法分析树不同

    三地址码

    三地址码由类似汇编语言的指令序列组成,每个指令最多有三个操作数,所以称为三地址码

    地址可以有三种形式

    1. 源程序中的名字(变量名)
    2. 常量
    3. 编译器产生的临时变量

    常见的三地址指令

    在这里插入图片描述

    三地址指令的表示

    1. 四元式
    2. 三元式
    3. 间接三元式

    在这里插入图片描述

    在这里插入图片描述

    目标代码的生成

    中间代码生成之后会对其代码进行一定程度的优化,然后就进入进入到了目标代码的生成

    目标代码生成器会将中间代码作为输入,并将它映射到目标语言,同时目标代码生成器还有一个重要任务就是为变量分配寄存器.

    机器代码相关优化器

    有一个重要任务就是为变量分配寄存器.

    机器代码相关优化器

    为改进代码所做的等价程序变换,使其运行的更快,占用空间更少.

    展开全文
  • 编译原理实验七:中间代码生成

    千次阅读 2019-04-13 12:08:02
    实现一门语言的中间代码生成器(4小时) ...实现中间代码生成器,可以将任一源语言(源语言尽量与前期实验中的源语言保持一致)转化成三地址码(或其他中间表示形式)。 准备2~3个测试用例,测试你的程序,...

    实现一门语言的中间代码生成器(4小时)

     

    实验目的

    通过本次实验,加深对中间代码生成的理解,学会编制中间代码生成器。

    实验任务

    用C、JAVA或其他语言编写一门语言的中间代码生成器,所选实现语言应与之前语言保持一致。

    实验内容

    1. 实现中间代码生成器,可以将任一源语言(源语言尽量与前期实验中的源语言保持一致)转化成三地址码(或其他中间表示形式)。
    2. 准备2~3个测试用例,测试你的程序,并解释生成的中间代码。

     

    源代码下载和说明

    链接:https://pan.baidu.com/s/1Ogf4447oPMrxHVJE8_hwmg

    密码:fc7f

    运行方法:同实验一TINY编译器(这其实就是实验一的工程)

     

    说明:实验七中间代码生成器直接使用了TINY语言。在2018-2019年秋季学期,湖南大学编译原理课首次将本实验变为必做(之前是选做,但由于难度太大,基本没有学长学姐写),故本实验采用已有的代码。

     

    实验知识点讲解和函数源代码分析

     

    1、中间代码生成的任务

     

    中间代码生成属于编译器前端结构的最后一部分,首先,编译器前端读入代码,对代码进行词法分析,构建出符号序列,再将符号序列传入语法分析,构造出语法树;接下来的语义分析则是一个静态检查的过程,它判断上下文的各个结点是否符合语法规则,并报错,生成符号表,而接下来的中间代码生成则也是对于语法树进行操作,传入一棵语法树,从根结点,根据该节点的词法属性,分析词法结点之间的逻辑,翻译成合适的中间表示。

    在TINY语言中,需要将NO_CODE标记位设置为真,这样就能够输出中间代码的生成结果。

    2、实现TINY语言的中间代码生成器

     

    本次实验要求实现一个中间代码生成器,则我们采用的方法是增量编程,在之前所构造好的TINY前期组件基础之上,构建中间代码的生成部分。

     

    2.1 TINY语言的中间代码生成结果——TM CODE

     

    TINY语言可以被翻译为一个适用于TM虚拟机环境的代码表示:TM CODE。TM CODE其实是类似于汇编指令的程序语言,但是何其不同的地方在于,TM CODE可以在为TINY语言所构建的虚拟机中运行,它模拟了汇编代码中的一些特性,比如说寄存器操作,它在CODE.H头文件中定义了几个寄存器的值(地址),使得这样的一种基于寄存器操作的类汇编语言能够执行。

    T机的模拟程序直接从一个文件中读取汇编代码并执行它,因此应避免将由汇编语言翻译为机器代码的过程复杂化。但是,这个模拟程序并非是一个真正的汇编程序,它没有符号地址或标号。因此,TINY编译器必须仍然计算跳转的绝对地址。此外为了避免与外部的输入/输出例程连接的复杂性,TM机有内部整型的I/O设备;在模拟时,它们都对标准设备读写。

    下图展示了TM CODE的详细定义:

    我们注意到装入操作中有3个地址模式并且是由不同的指令给出的:LDC是“装入常量”,LD是“由存储器装入”,而LDA是“装入地址”。另外,该地址通常必须给成“寄存器+偏差”值。例如“10(1)”(上面代码的第2条指令),它代表在将偏差10加到寄存器1的内容中计算该地址。(因为在前面的指令中,0已被装入到寄存器1中,这实际是指绝对位置10)。我们还看到算术指令MUL和ADD可以是“三元”指令且只有寄存器操作数,其中可以单独确定结果的目标寄存器。

     

    2.2 MAIN函数调用入口及文件预处理

     

    如图代码展示了MAIN函数的文件预处理和中间代码生成的调用入口:

    第一步是文件的预处理。

    strcspn函数的作用是,在pgm字符串中查找到第一个“.”,并返回它之前的所有字符作为子串,这样做的目的在于,我们传入给编译器的文件是一个文件,我们中间代码的输出结果也需要保存在一个文件中,输出文件在这里这样做,是为了保持和输入文件同名。

    strncpy函数的作用是拷贝字符串,这里用于将strcspn提取的文件名存入字符串供输出文件使用。

    接下来程序使用提取的文件名创建了一个.TM文件,作为中间代码的输出,并打开它,赋予其“w”写的权限,并执行中间代码生成的后续操作。

    【这里大家注意一下,运行完程序之后,文件夹里面会出现一个.TM结尾的文件,用记事本打开,就是其生成的TM CODE,也就是运行结果】

    第二步就是中间代码生成,它调用了codeGen函数,传入了语法树根结点以及需要写入的文件,进行后续操作,下面代码所展示的是该函数:

    这个代码主要是调用了emitRM,emitComment函数插入了TM虚拟机的初始化指令,其中这些函数传入的都是mp、ac等定义好的寄存器,这个在code.H中有详细定义:

    TM虚拟机不是一开始就能运行中间代码的,需要一些初始化的条件,在插入完这些指令之后,就会到达一个正式的cGen的代码生成过程,待到cGen函数执行完毕,继续需要插入一条停机指令HALT代表代码执行完毕。

     

    2.3 代码生成的具体过程

     

    下图展示的是cGen函数的代码:

    可以看到,传入的语法树在一边遍历的同时,检查结点的类型,TINY语言中分为两种语句结点,一种是带有关键字的保留语句,一种是表达式,比如赋值或者是算式(总之,不带有保留关键字),这两种情况分开考虑。

     

    1、getStmt——分析含有保留关键字语句的函数

    该函数的作用主要是处理TINY语言中所包含的五个关键字——if,repeat,assign,read,write。

    这里以if作为一个例子来分析说明这个函数需要做的工作:if结点包括三个子结点,if本身的判断表达式、then、以及else(通常,else可以被省略)。我们对于每个if的子结点递归分析(因为if的子结点可能也会是一个表达式,比如if的条件判断,这样的话就需要对它进行递归分析)。

    用savedLoc变量记录递归的返回位置,待分析完这一条路径之后,就可以找到函数在哪里被调用了,在调用的过程中,由于各个节点都需要递归地访问,因此这里在处理下一个节点的时候,使用了emitSkip这个函数,用于跳过并保存当前点的位置,以便于函数最后的返回工作。【这个地方,也叫作回填】

    其他的处理也是类似的,比如在repeat语句里面,repeat包含的是两个结点,一个是repeat它本身,第二个是与之对应的until条件,同if一样,分为两块进行分别的一个递归处理。

    其他三个关键字分别是assign,read,write。这三个的处理比较简单,因为他们的语句结构决定了他们只有一个子结点,因此,直接处理子结点就可以了。

    如何处理子结点呢?

    如图所示,我们获取了结点的类型,也能够获取结点的逻辑关系,此时,只要调用刚刚提到的函数emit,就可以将这条指令写到输出文件中,使得最后的TM虚拟机能够执行完成。

     

    2、getExp——处理表达式

     

    处理表达式结点的逻辑比较简单,如果表达式的结点类型是ID或者数字,那么直接使用LD命令加载它即可。

    如果结点是一个运算符,那么据我们所知,运算符是由子结点构成的,它的子结点就是运算的两个数字,或者是ID字符。我们需要使用LD命令将子结点里面的具体数字或字符读取出来,再根据运算符的类型构造相应的TM code命令。

    下图展示的是小于和等于的命令TM code:

    运行结果

     

    输入数据:(文件名:SAMPLE.TNY)

    { Sample program
      in TINY language -
      computes factorial
    }
    read x; { input an integer }
    if 0 < x then { don't compute if x <= 0 }
      fact := 1;
      repeat
        fact := fact * x;
        x := x - 1
      until x = 0;
      write fact  { output factorial of x }
    end

    输出:(文件名:SAMPLE.TM)

    * Standard prelude:
      0:     LD  6,0(0) 	load maxaddress from location 0
      1:     ST  0,0(0) 	clear location 0
    * End of standard prelude.
      2:     IN  0,0,0 	read integer value
      3:     ST  0,0(5) 	read: store value
    * -> if
    * -> Op
    * -> Const
      4:    LDC  0,0(0) 	load const
    * <- Const
      5:     ST  0,0(6) 	op: push left
    * -> Id
      6:     LD  0,0(5) 	load id value
    * <- Id
      7:     LD  1,0(6) 	op: load left
      8:    SUB  0,1,0 	op <
      9:    JLT  0,2(7) 	br if true
     10:    LDC  0,0(0) 	false case
     11:    LDA  7,1(7) 	unconditional jmp
     12:    LDC  0,1(0) 	true case
    * <- Op
    * if: jump to else belongs here
    * -> assign
    * -> Const
     14:    LDC  0,1(0) 	load const
    * <- Const
     15:     ST  0,1(5) 	assign: store value
    * <- assign
    * -> repeat
    * repeat: jump after body comes back here
    * -> assign
    * -> Op
    * -> Id
     16:     LD  0,1(5) 	load id value
    * <- Id
     17:     ST  0,0(6) 	op: push left
    * -> Id
     18:     LD  0,0(5) 	load id value
    * <- Id
     19:     LD  1,0(6) 	op: load left
     20:    MUL  0,1,0 	op *
    * <- Op
     21:     ST  0,1(5) 	assign: store value
    * <- assign
    * -> assign
    * -> Op
    * -> Id
     22:     LD  0,0(5) 	load id value
    * <- Id
     23:     ST  0,0(6) 	op: push left
    * -> Const
     24:    LDC  0,1(0) 	load const

     

    展开全文
  • 中间代码生成三地址码 语法制导翻译 目标代码:mips代码 接上篇:【编译原理/类C编译器】(三)语法分析 运行界面 说明 语法制导翻译(在语法分析过程中,随着分析的步步进展,在使用某个产生式进行推导或归约时...

    说在前面

    运行界面

    在这里插入图片描述
    在这里插入图片描述

    说明

    语法制导翻译(在语法分析过程中,随着分析的步步进展,在使用某个产生式进行推导或归约时便执行相应的语义子程序,完成既定的翻译工作,生成中间代码)


    写不动了,有时间再写,github在第一篇

    展开全文
  • 常用的中间表示形式 三地址码(three-address Code) 三地址码由类似于汇编的指令序列组成,每个指令最多有三个操作数 地址可以具有如下形式之一 源程序中的名字 ...目标代码生成以源程序的中间表示形...

    常用的中间表示形式

    • 三地址码(three-address Code)
      • 三地址码由类似于汇编的指令序列组成,每个指令最多有三个操作数
        说的都是.png
      • 地址可以具有如下形式之一
        • 源程序中的名字
        • 常量
        • 编译器生成的临时变量
      • 三地址转换成数据结构
        • 四元式
          是的是的.png

          - 三元式
        • 间接三元式
    • 语法结构树/语法树(syntax trees)

    编译器的结构

    • 目标代码生成以源程序的中间表示形式作为输入,并把它映射到目标语言
    • 目标生成的一个重要任务是为程序中使用的变量合理分配寄存器

    代码优化

    代码优化:为改进代码进行的等价程序变换

    • 机器无关优化:中间层面进行优化
    • 机器相关优化:目标代码层面进行优化
    展开全文
  • 编译原理-中间代码生成

    千次阅读 2019-04-17 10:43:52
    1.概述 1.1 定义 源程序的一种内部表示,不依赖目标机的结构,易于机械生成目标代码中间表示。... 逆波兰式(后缀式)、三地址码(三元式、四元式)、抽象语法树、有向无环图。 1.3 地位 如下所示: ...
  • 编译原理——中间代码生成

    万次阅读 2016-03-28 22:37:22
    源语言->中间代码->目标语言 ...四元式是一种普遍采用的中间代码形式,很类似于三地址指令,有时把这类中间表示称为“三地址代码”,这种表示可以看作是一种虚拟三地址机的通用汇编,每条”指令“包
  • 第六章 中间代码生成

    千次阅读 2018-11-15 16:51:49
    文章目录三地址码表达式的翻译表达式中的运算数组元素寻址条件表达式中的短路回填 三地址码 格式: x = y op z 三地址码的右边只能有一个操作符 每个三地址码语句包含三个地址:两个是操作数,一个是结果 三地址码的...
  • 中间代码三地址码的形式表示,由两个源操作数,一个目的操作数和一个运算符组成。然后uccc在生成中间代码时以基本块为单位,每个基本块包含若干条中间代码,基本块的开头都会有类似BB1:这样的标签。 从静态上来...
  • 第7章 语义分析与中间代码生成 重点:三地址码,各种语句的目标代码结构、 语法制导定义与翻译模式。 难点:布尔表达式的翻译,对各种语句的目标  代码结构、语法制导定义与翻译模式的  理解。 7.1 中间...
  • 一、中间代码简介 中间代码应具备的特性: 1)便于语法制导翻译 2)既与机器指令的结构...最常用的中间代码形式是三地址码,它的实现形式常采用四元式形式。 符号表是帮助声明语句实现存储空间分配的重要数据...
  • 本节对UCC编译器的中间代码生成及优化进行简介,给出基本块BasicBlock、三地址码、控制流图CFG的相应数据结构,介绍有条件跳转、无条件跳转和间接跳转等概念。
  • 文章目录一、什么是后缀式?1.后缀式的特点是什么?2.如何将中缀式转换成后缀...2.三地址码的三种表示形式:三元式、四元式、间接三元式;3.三元式、四元式、间接三元式各自优缺点4. 三元式与间接三元式之间的区别5....
  • 文章目录第一节 目标代码生成概述1.1 目标代码生成的任务1.2 主要问题1.3 GAM第二节 简单代码生成2.1 x=y2.2 x=-y2.3 x=y+z2.4 转移语句第三节 寄存器分配3.1 ...输入:中间代码三地址码) 输出:目标代码(汇编代码
  • 编译原理 中间代码表示

    千次阅读 2018-10-20 23:03:31
    控制流图在程序分析,程序优化中有重要的作用 将抽象层次逐渐降低,有的优化...如何生成三地址码?     F*代表0个或者多个F,正则文法,X是函数,可以有多个参数 S 函数体:内部可以再调用函数  ...
  • 这是因为中间代码的形式不依赖于具体的计算机,它可以是三地址码的形式,所以相应的对于中间代码的优化也不依赖于具体的计算机。另一类优化是在生成目标代码时进行的,它很大程序上依赖于具体的计算机。中间代码的...
  • Xian Jiaotong University 中间代码生成 第七章语义分析和中间 词法分析语法分析中间代码生成 代码生成 中间代码的表示形式有多种 逆波兰表示 三地址码三元式四元式 抽象语法树 P-代码 属性文法是实现中间代码生成的...
  • 三地址码:由类似汇编语言的指令序列组成,每个指令最多有三个操作数(此处案例不好展示) 常用的地址指令:赋值指令、复制、条件跳转、非条件跳转、参数传递、过程调用、过程返回、数值引用、数组赋值、地址及指针...
  • 中间代码生成三地址码 语法制导翻译 目标代码:mips代码 接上篇:【编译原理/类C编译器】(二)词法分析 运行界面 流程 语法分析使用的是 LL(1) 方法 消除左递归 i. 消除直接左递归 ii.消除...
  • 日历表格面板 [ConfigLine.java] 控制条类 [RoundBox.java] 限定选择控件 [MonthMaker.java] 月份表算法类 [Pallet.java] 调色板,统一配色类 Java扫雷源码 Java生成自定义控件源代码 2个目标文件 Java实现HTTP连接...
  • 抛开语言,我们来谈3地址码 对于位址码,每一条赋值指令的右侧只能有一个操作符,总共最多有个地址(等号右侧只能有一个操作符,比如t1=y+z,这里t1,y,z都是地址,它们指向了地址对应的内存数据) 位址码指令...
  • 代码语法错误分析工具pclint8.0

    热门讨论 2010-06-29 07:00:09
    new),其中最后一个选项是operator new,那么在operator和new中间只能有一个空 格。 选项还可以放在宏定义中,例如: #define DIVZERO(x) /*lint -save -e54 */ ((x) /o) /*lint -restore */ LINT的选项很多...
  • 中间代码生成三地址码 语法制导翻译 目标代码:mips代码 接上篇:【编译原理/类C编译器】(一)使用的词法规则以及语法规则 运行界面 说明 代码 js //0 开始 const KEY_WORD = ["int", "void", "if", ...
  • 本专栏总结王利涛《C语言嵌入式Linux...5)三地址码七、编译第五阶段1)生成汇编2)过程 一、编译输入输出 (1) 输入:C程序源文件; (2)输出:汇编文件,目标文件; (3)编译过程主要做了什么? 从高级语言到低级语言
  • 可是指导书上实验目的要求自己分析,我的分析结果:本次实验要求自己定义上次实验的语法分析的文法的SDD,然后编写程序在上次语法分析的基础上完成语义分析,生成测试程序的中间代码三地址码)。 基本概念 ...
  • c编译器ucc 编译原理

    2011-03-30 20:33:54
    2. 使用三地址码作为中间码,构建了由基本块组成的控制流图,适合很多优化算法 3. 编译速度快。词法分析,语法分析和目标代码生成器都是手写的(其中的代码 生成器本想用burg这样的工具自动生成,但这样可能会给...
  • 编译原理(龙书,带目录)

    热门讨论 2012-04-20 14:42:16
    8.2.3 从中间代码生成目标代码 317 8.3 数据结构引用的代码生成 319 8.3.1 地址计算 319 8.3.2 数组引用 320 8.3.3 栈记录结构和指针引用 325 8.4 控制语句和逻辑表达式的代码生成 328 8.4.1 if 和while 语句的代码...
  • 编译技术A实验报告

    2018-04-28 10:57:15
    以下是实验目的 实验一:词法分析 一.实验目的 1、学会针对DFA转换图实现相应的高级语言源程序。...(2) 掌握语法树到中间代码三地址码)的转换线性处理方法。 (3) 属性文法和语法制导翻译法进行语义翻译。
  • 编译相关

    2012-07-08 14:02:00
    编译的过程 : 1. 词法分析,程序被扫描成:关键字,...4. 运行时无关的中间码生成,此时的语法树可以转换成,并进行初步优化。 5. 生成目标代码,但此时变量的地址并未确定。 目标文件的内容: 段里...
  • 语法分析的输入是词法单元序列,然后根据语言的文法表示(展开式),利用有限状态机理论,生成抽象语法树,然后遍历得到中间代码,即,三地址码。本节就以一个实验的方式,来看一下,语法分析器的内在实现机制。  ...

空空如也

空空如也

1 2 3 4
收藏数 77
精华内容 30
关键字:

中间代码生成三地址码