赋值语句翻译
赋值语句 的翻译分两步:
- 计算 的值 → 产生计算表达式中间代码
- 赋值给 → 产生
(:=, E_value, _, V_addr)四元式
表达式翻译
- 变量引用 → 查符号表获取地址
- 运算 → 生成临时变量,产生四元式
示例:x := A + B * C
(*, B, C, T1)
(+, A, T1, T2)
(:=, T2, _, x)
控制流语句翻译
所有跳转通过三类指令实现:
J:无条件跳转JP:真跳转(条件为真时跳转)JF:假跳转(条件为假时跳转)
if 语句(两个标号)
if (E) S1
计算 E
JP E.true, L1 ; true → 执行S1
J, L2 ; false → 跳出
L1: S1的代码
L2:
if-else 语句(三个标号)
if (E) S1 else S2
计算 E
JP E.true, L1 ; true → 执行S1
JF E.false, L2 ; false → 执行S2
L1: S1的代码
J, L3 ; 跳过else
L2: S2的代码
L3:
重点 if/if-else 的标号设计与跳转指令。
while 语句(三个标号)
while (E) S
L1: 计算 E
JP E.true, L2 ; true → 进入循环体
JF E.false, L3 ; false → 跳出
L2: S的代码
J, L1 ; 回到条件判断
L3:
条件短路
短路求值:A && B 中若 为 false 则不再计算 。
重点 条件短路中 true 标号不可省略。即使无需跳转也必须分配标号,保持结构统一。
示例:if (A > B && B > C)
(>, A, B, T1)
JP T1, L1 ; A>B为true → 继续判断
JF T1, L2 ; A>B为false → 跳过
L1: (>, B, C, T2)
JP T2, L3 ; B>C为true → 执行if体
L2: (J, _, _, L4) ; else部分
L3: if体
L4:
for 循环翻译(四标号方案)
for (E1; E2; E3) S
E1的代码 ; 初始化
L1: 计算 E2 ; 条件判断
JP E2.true, L2 ; true → 进入循环体
J, L4 ; false → 退出
L2: S的代码 ; 循环体
L3: E3的代码 ; 增量
J, L1 ; 回到条件判断
L4: 退出
重点 for 循环四个标号:E1(初始化)、E2(条件判断)、E3(增量)、退出。
控制流嵌套示例(for 嵌套 for + if)
for (i = 1; i <= N; i++)
for (j = 1; j <= M; j++)
if (i == j)
a[i][j] = 0;标号分配:
i = 1 ; E1 初始化外层
L1: if i <= N goto L2 ; E2 外层条件判断
goto L4 ; 外层退出
L2: j = 1 ; E1' 初始化内层
L5: if j <= M goto L6 ; E2' 内层条件判断
goto L7 ; 内层退出
L6: if i == j goto L8 ; if 条件
goto L9 ; 条件不满足
L8: a[i][j] = 0 ; if 体
L9: j++ ; E3' 内层增量
goto L5 ; 返回内层条件
L7: i++ ; E3 外层增量
goto L1 ; 返回外层条件
L4: ; 程序退出
标号规则:外层循环四个标号(L1-L4),内层循环四个标号(L5,L6,L7,L9),if 两个标号(L8,L9),L9 复用作为内层增量起始。
switch-case 多分支
2N 个标号方案
每个 case 两个标号(条件判断 + 执行体),N 个 case 共 2N 个标号。
JP E=c1, L1 ; 判断是否等于c1
J, L_c2
L1: S1的代码
J, L_out
L_c2: JP E=c2, L2
J, L_out
L2: S2的代码
J, L_out
L_out:
N+1 方案
用跳转表实现,每个 case 一个标号 + 一个出口标号,共 N+1 个标号。
计算 E
case L1, L2, ..., LN ; 跳转表
L1: S1的代码 → J L_out
L2: S2的代码 → J L_out
...
L_out:
- break 的作用:跳转到 ,否则会顺序进入下一个 case