编译原理
  • 编译原理
  • 一些简答题
  • 绪论
    • 编译器简介
    • 程序设计语言
    • 静态与动态
    • 参数传递机制
  • 词法分析
    • 词法单元、模式、词素
    • 串和语言
    • 正则表达式
    • 状态转换图
    • 不确定有穷自动机NFA
    • 确定有穷自动机DFA
    • 算法:正则表达式转NFA
    • 自动机到词法分析器
  • 语法分析
    • 语法分析器
    • 上下文无关文法
    • 二义性和左递归
    • 递归下降语法分析
    • 算法:求解FIRST集和FOLLOW集
    • 算法:LL(1)
    • 自底向上语法分析
    • 移入-归约语法分析
    • 算法:LR(0)
    • 算法:SLR(1)
    • 算法:LR(1)
    • 算法:LALR
    • LR分析器和LALR分析器
  • 语法制导
    • 语法制导定义(SDD)
    • 综合属性和继承属性
    • 语法树上的SDD求值
    • 依赖图
    • L属性的SDD
    • 类型
    • SDD的应用
  • 中间代码生成
    • 三地址代码
    • SSA(静态单赋值)
    • 类型和声明
    • 表达式的翻译
    • 类型检查
    • 控制流
    • 回填
  • 运行时刻环境
    • 存储组织
    • 栈式分配
    • 栈中非局部数据的访问
    • 堆管理
    • 垃圾回收
  • 代码生成
    • 代码生成器的设计
    • 目标语言
    • 目标代码中的地址
    • 基本块和流图
    • 基本块的优化
Powered by GitBook
On this page
  • AST表示
  • 编译器前端的逻辑结构
  • 中间代码表示及其好处
  • 三地址代码
  • 指令集合
  • 三地址指令的四元式表示方法
  1. 中间代码生成

三地址代码

PreviousSDD的应用NextSSA(静态单赋值)

Last updated 4 months ago

AST表示

AST是一种高级的程序表示(贴近源语言层面),语言相关(与源语言语法紧密关联),适合一些类型检查。但是不紧凑、缺少控制流信息(不利于分析与优化)。

所以我们需要一种中间代码表示,易于分析和优化。它与具体语言无关(通用)、与具体机器无关(通用++)。

编译器前端的逻辑结构

前端是对源语言进行分析并产生中间表示,处理与源语言相关的细节,与目标机器无关。

前端后端分开的好处:不同源语言、不同的机器可以得到不同的编译器组合,可复用的分析/优化的逻辑。

中间代码表示及其好处

形式:多种中间表示(Intermediate Representations,IRs),不同层次。抽象语法树、三地址代码。

好处:可以复用,为新的机器建立编译器,只需要做从中间代码到新的目标代码的翻译器(前端独立);可以进行高层次的优化,优化与源语言和目标机器都无关。

静态类型检查和中间代码生成的过程都可以用语法制导的翻译来描述和实现。

三地址代码

目标:接近大多数目标机器的执行模型(机器码)。支持大多数目标机器提供的数据类型和操作。提供有限度的、高于机器码的抽象表达能力,更容易表达出大多数(命令式)高级语言的特性。

特征:以指令为单位;每条指令只有有限数量的运算分量;支持基本数据类型及其运算;支持符合数据类型(如数组、结构体)及其操作;支持函数。

每条指令右侧最多可以有一个运算符:x = y op z (接近机器码,易于从机器角度优化;大大减少组合情况的数量,易于处理)。

允许的运算分量:

  • 变量:源程序中的名字作为三地址代码的地址

  • 常量:源程序中出现或生成的常量

  • 编译器生成的临时变量(也可与源程序变量等同视之)

指令集合

三地址指令的四元式表示方法

在实现时,可以使用四元式/三元式/间接三元式/静态单赋值来表示三地址指令。

四元式:可以实现为记录(或结构)

单目运算符不使用arg2,param运算不使用arg2和result,条件转移/非条件转移将目标标号放在result字段。

数组操作的四元式表示:

  • 读数组:x = y[i]

  • 写数组:x[i] = y

AST表示
一个编译器前端的逻辑结构
例子
四元式的例子