step2 实验指导

我们按照上一节划分的编译器阶段,分阶段给出 step2 实验指导。

词法语法分析

如果你使用工具完成词法语法分析,修改你的规范以满足要求,剩下的交给工具即可。 语法规范已经给出,词法规范的变化也很简单,新增三个 token:-~!

你的规范和我们的要求等价、能通过测试即可,不用完全一样。

语义检查无需修改。

如果你是手写分析,TODO

IR 生成

显然,我们要引入一类 IR 表示一元操作。 一元操作 IR 的含义是:弹出栈顶,对弹出的值做某个一元操作,再把操作的结果值压入栈顶。 换言之,就是直接对栈顶做某个操作。

指令 参数 含义 IR 栈大小变化
neg 无参数 栈顶取负 不变
not 同上 栈顶按位取反 不变
lnot 同上 栈顶取逻辑非 不变

和 step1 一样,这一节所讲的领悟意思即可。 你不用照着实现。 例如你可以把三条指令变成一条 Unary(op),其中 op"-""~""!"。 你甚至也不必显式转成 IR。

和 step1 一样,采用 Visitor 模式遍历 AST 来生成 IR。除了 step1 的要求,step2 还要求你遍历 AST 时,

  • 遇到一元表达式的时候,先生成子表达式的 IR,然后再根据操作类型生成一个 negnotlnot

所以,~!--3 会翻译成 push 3 ; neg ; neg ; lnot ; not 五条 IR 指令。

汇编生成

很简单,如下表。

IR 汇编
neg lw t1, 0(sp) ; neg t1, t1 ; sw t1, 0(sp)
not ……
lnot ……

要知道每个操作生成什么样的汇编,可以参考 gcc 的输出。 例如我们想知道取负的汇编,那我们用 gcc 编译 int foo(int x) { return -x; }, 结果如下(记得加 -O3),我们就知道取负是 neg 目标寄存器, 操作数寄存器

foo:
    neg    a0,a0
    ret

仿照上面,自己确定 notlnot 的汇编。

任务

  1. 改进你的编译器,支持本节引入的新特性,通过相关测试。
  2. 实验报告中回答思考题。

总结

本节内容不多,也很简单。

results matching ""

    No results matching ""

    results matching ""

      No results matching ""