2020-编译原理-IR3-回填技术
IR3-回填技术
- B 还不知道S.next的指令地址,如何跳转?
- 再扫描一遍中间代码,将标号替换成指令(相对) 地址
- 可否在生成中间代码的时候就填入指令地址?
子节点挖坑、祖先节点填坑
- 目前的方法是通过一边扫描得到包含Label的中间代码,然后我们可以通过再次扫描一遍中间代码来生成每一个Label的指令地址,我们的目标是一次扫描完成了上述的两部分工作。
- 比如
if (B) S
:这时候我们得到的是L: goto B.false
,我们替换为指令地址,则为100: goto ___
,并且放入B.false
中,然后向上传递,直到一个有父节点指导目标位置,然后填充进去即可。
1. 针对布尔表达式的回填技术
M的作用是得到这段代码的第一条指令地址。
- 综合属性B.truelist 保存需要跳转到B.true 的指令地址
- 综合属性B.f alselist 保存需要跳转到B.f alse 的指令地址
- 是个数组
注意100和101指令对应nextinstr
- 回填:函数,代表的是M的第一个地址,也就是我们要将中的所有的坑都填为
- 代表的是计数器+1
2. 例子
x < 100 || x > 200 && x != y
3. 具体语句使用填坑技术的生成式
3.1. if/else控制流语句翻译
3.2. while控制流语句翻译
注意N的跳转位置和next属性
nextinstr:是生成的过程中的地址的计数器,表示的是gen(“goto _”)的地址
3.3. 不包含跳转的语句翻译
3.4. switch语句翻译
switch-case先把标签生成好
2020-编译原理-IR3-回填技术
https://spricoder.github.io/2021/01/16/2020-Compilation-Principle/2020-Compilation-Principle-IR3-%E5%9B%9E%E5%A1%AB%E6%8A%80%E6%9C%AF/