The Decaf Book
  • Introduction
  • 语言规范
  • Java 框架分阶段指导
    • 本章导引
    • PA1-A:语法分析器的自动构造
      • 阶段任务
      • 词法分析
      • 抽象语法树
      • 文法分析
    • PA1-B:基于 LL(1) 的语法分析器半自动构造
      • 阶段任务
      • LL(1) 文法分析
      • 错误恢复
    • PA2:语义分析
      • 阶段任务
      • 类型、符号和作用域
      • 访问者模式
      • 符号表构建
      • 类型检查
    • PA3:中间代码生成
      • 阶段任务
      • TAC 程序
      • 面向对象机制
      • 控制流的翻译
    • PA4:中间代码优化
      • 实验内容
      • 基本块
      • 数据流分析概述
      • 数据流优化概述
      • 公共表达式提取
      • 复写传播
      • 常量传播
      • 死代码消除
  • Scala 框架分阶段指导
    • 本章导引
    • PA1:语法分析器的自动构造
      • 阶段任务
      • 词法分析
      • 抽象语法树
      • 文法分析
      • 访问者模式
    • PA2:语义分析
      • 阶段任务
      • 类型、符号和作用域
      • 符号表构建
      • 类型检查
    • PA3:中间代码生成
      • 阶段任务
      • TAC 程序
      • 面向对象机制
      • 控制流的翻译
    • PA3-JVM:JVM 字节码生成
      • 阶段任务
      • JVM 字节码简介
      • 翻译过程
    • PA4:中间代码优化
      • 实验内容
      • 基本块
      • 数据流分析概述
      • 数据流优化概述
      • 公共表达式提取
      • 复写传播
      • 常量传播
      • 死代码消除
  • Rust 框架分阶段指导
    • 本章导引
    • PA1-A:语法分析器的自动构造
      • 实验内容
      • lalr1使用指导
        • 编写lexer
        • impl块的可选属性
        • 产生式和语法动作
        • 解决冲突
        • 一个完整的例子
      • 抽象语法树
      • 框架中部分实现的解释
      • 文件结构
    • PA1-B:基于 LL(1) 的语法分析器半自动构造
      • 实验内容
      • lalr1使用指导
      • 错误恢复
      • 文件结构
    • PA2:语义分析
      • 实验内容
      • 语义分析
      • 符号表
      • visitor模式
    • PA3:中间代码生成
      • 实验内容
      • 中间代码
      • 中间代码中的类型信息
      • 运行时存储布局
      • 面向对象机制
      • tacvm简述
    • PA4:中间代码优化
      • 基本块
      • 数据流分析概述
      • 数据流优化概述
      • 公共表达式提取
      • 复写传播
      • 常量传播
      • 死代码消除
    • PA5:寄存器分配
      • 实验内容
      • 图着色基本原理
      • 着色算法
      • 预着色节点
      • 干涉图节点合并
      • 调用约定
Powered by GitBook
On this page
  • 实验概览
  • 组织结构

Was this helpful?

  1. Rust 框架分阶段指导

本章导引

本书的这一部分介绍 Rust 框架各阶段实验的主要任务以及框架中一些重要的实现方法。

by MashPlant

实验概览

同其他版本的框架一样,本框架也需要经历以下几个阶段:

  1. 词法分析/语法分析

    利用parser generator来实现lexer和parser的构造,包含以下两个部分:

    • pa1a 使用lalr(1)文法,配合终结符的优先级和结合性,很方便地构造parser

    • pa1b 使用ll(1)文法,很不方便地构造parser,还要求进行一定程度的错误恢复

    孰难孰易,一目了然

  2. 语义分析

    对ast进行类型检查,并将ast中的语法元素(如变量引用)以恰当的方式组织起来,方便后续中间代码生成。

  3. 中间代码生成

    将ast翻译成中间代码,我们使用的中间代码为三地址码(tac, Three Address Code)。

  4. 数据流分析

    在中间代码的层次上利用数据流分析进行一定程度的优化。

  5. 目标代码生成

    实现编译器后端,将中间代码翻译成目标代码,我们选择的目标代码是mips。

关于decaf语言本身的规范,可以参考专门的文档,这里就不重复列举了。

组织结构

实验框架是一个模块化的系统,以rust的crate为分界,将编译器的各逻辑模块分隔开。除了软件工程方面的考虑外,这样做一个很大的好处在于减少了对单个模块的修改后的编译时间,这在一定程度上缓解了rustc相比于javac的编译时间的劣势。

完成所有pa之后,我们的编译器的组织结构如下,其中箭头表示依赖关系,Compiler部分是我们实现的编译器部分,Parser Generator部分是如何组织的其实我们的实验不用关心,这里只是单纯的列一下。

  • common:提供一些通用的配置和工具

  • syntax:提供ast各个节点的定义,也提供了类型的定义(也许放在这里不太合适,这样做是为了避免crate间循环引用)

  • typeck:执行语义分析,类型检查

  • tac:提供tac的定义和相关数据结构

  • tacgen:将ast翻译为tac

  • tacopt:将tac划分为流图,并执行一些基于数据流的优化

  • codegen:实现编译器后端,目前实现了mips代码的生成

  • print:提供各种结果或中间结果(如ast,tac,asm)的输出

  • driver:将各个crate的内容整合起来,组成一个可执行文件并执行测试

得益于模块化的实验框架,这个编译器更像是一个编译器库而非一个不可分割的独立的可执行程序,因此实验结果的测试不需要依赖于python脚本之类的工具,直接在rust里执行就可以。

driver crate中包含测试相关的代码,最终实验结果的检查是在test.rs中,通过需要修改Pa enum的取值来确定具体执行哪个pa阶段的测试。我给测试结果的输出加上了颜色,不过经测试颜色的输出可能不太正常,如果遇到这样的情况,在测试前加上一行color::control::set_override(false);即可关闭测试结果的颜色效果。

PreviousRust 框架分阶段指导NextPA1-A:语法分析器的自动构造

Last updated 5 years ago

Was this helpful?

arch