step3 实验指导

词法语法分析

如果你使用工具完成词法语法分析,修改你的语法规范以满足要求,自行修改词法规范,剩下的交给工具即可。

语义检查无需修改。

如果你是手写分析,TODO

IR 生成

我们同样引入一类 IR 表示二元操作。 执行二元操作的 IR 时,两个操作数需要位于栈顶,然后它们被弹出、进行相应操作,再把结果压入栈顶。

不妨规定二元操作的右操作数在栈顶,左操作数在右操作数下面,那么有如下例子:

3-10 翻译成 push 3 ; push 10 ; sub 三条指令。

    +------------+ 栈顶
    |     10     |
    +------------+    ---------->   +------------+ 栈顶
    |     3      |     执行 sub     |     -7     |
    +------------+                  +------------+
    |   ......   |                  |   ......   |
指令 参数 含义 IR 栈大小变化
add 无参数 弹出栈顶两个元素,压入它们的和 减少 1
sub 无参数 弹出栈顶两个元素,压入它们的差,顺序如上 减少 1
muldivrem 无参数 ……乘除模 减少 1

类比 step2,生成 IR 时 Visitor 遍历 AST 遇到二元操作,需要(注意 1. 和 2. 的顺序)

  1. 首先生成左操作数的 IR(左操作数入栈,栈顶是左操作数)
  2. 然后生成右操作数的 IR(右操作数入栈,栈顶是右操作数)
  3. 根据操作不同生成对应的二元 IR

上面的 3 步执行完后,栈大小比执行第 1. 步以前增加 1,栈顶就是二元操作的结果。 这符合我们在 step1 中的假设:

考虑源代码中某个表达式被翻译成了一系列 IR 指令,那么从任何初始状态出发执行这些 IR 指令, 完成后 IR 栈大小增加 1,栈顶就是表达式的值。

汇编生成

仿照 step2 所说,用 gcc 自己确定 sub/mul/div/rem 的汇编。

IR 汇编
add lw t1, 4(sp) ; lw t2, 0(sp) ; add t1, t1, t2 ; addi sp, sp, 4 ; sw t1, 0(sp)
sub,mul,div,rem ……

任务

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

总结

本节重点是执行过程中栈的变化,以及上面提到的 step1 的假设,参见上面 IR 生成一节。

results matching ""

    No results matching ""

    results matching ""

      No results matching ""