中间代码生成——控制流语句的翻译 II

如何生成更短、更高效的代码?

先看我们已经实现的两个示例

在我们生成的代码中,会出现多余的br指令

解决方法

直接用布尔表达式改变控制流

使用控制流跳转间接表明布尔表达式的值

父节点为子节点准备跳转指令的目标标签

子节点通过继承属性确定跳转目标

具体实现

继承属性 B.true B.false S.next 指明了控制流的跳转目标

$P \rightarrow S$

S.next 为语句 S 指明了跳出S的目标

$S \rightarrow assign$

代表了表达式的翻译,包括数组引用

IF 语句

红线框出来的的语句,在理解上应该拆分为两句话,即

  1. B.false = S.next,即B为false时,goto S.next

  2. S1.next = S.next,即S1执行完,goto S.next

EXAMPLE

1
2
3
4
if(true)//B
//S1
if(false)//B11
assign//S11

S.next = L0
B.true = L1
B.false = S1.next = S.next = L0
B11.true = L3
B11.false = S1.next = S.next = L0

IF-ELSE 语句

EXAMPLE

1
2
3
4
5
6
7
if (true)
if (true)
Assign
else
assign
else
assign

WHILE 语句

相比于if- else语句,while语句中多添加了begin的标签,便于跳转回开头

EXAMPLE

1
2
3
4
5
while (true)
if (false)
assign
else
assign

$S \rightarrow S1, S2$

EXAMPLE

1
2
3
4
5
if (true)
assign
else
assign
assign

Generate Goto

! 语句

短路求值

Rel

EXAMPLE

布尔表达式的作用

布尔值 vs. 控制流跳转

根据 E 所处的上下文判断 E 所扮演的角色, 调用不同的代码生成函数函数 jump(t, f): 生成控制流代码函数 rvalue(): 生成计算布尔值的代码, 并将结果存储在临时变量中