编译原理习题Ch2.8
编译原理习题Ch2.8
📘 Exercise 2.8.1
❖ Problem(题目)
For-statements in C and Java have the form:
1 | for ( expr1 ; expr2 ; expr3 ) stmt |
其中:
expr1
:循环开始前执行一次(初始化)expr2
:每次迭代前的判断条件,若为 0 则退出expr3
:每轮循环末尾执行(通常是自增)stmt
:循环体
等价于:
1 | expr1; |
任务:定义一个类 For
来表示 for
语句,类似于图 2.43 中的 If
类。
✅ Answer(答案)
1 | class For extends Stmt { |
🧠 Explanation(解释)
这个类表示 for
循环的语义为:
E1
是开始前执行的表达式(初始化变量)。start
是循环体的开始标签。E2
是判断是否继续循环,如果false
(例如为0
)就跳出循环。- 执行语句
S
,然后再执行E3
(如i++
),再跳回start
。 - 如果条件失败,就跳转到
end
,即循环结束。
📘 Exercise 2.8.2
❖ Problem(题目)
C 语言没有布尔类型。演示 C 编译器如何将 if 语句转换成三地址代码(three-address code)。
✅ Answer(答案)
默认 if 的翻译使用:
1 | emit("ifFalse " + E.rvalue().toString() + " goto " + after); |
但 C 没有布尔类型,判断条件为 0(假)或非 0(真),所以可以改成:
1 | emit("ifEqual " + E.rvalue().toString() + " 0 goto " + after); |
或者简化为:
1 | emit("ifEqualZero " + E.rvalue().toString() + " goto " + after); |
🧠 Explanation(解释)
- 在 Java 或其他语言中,有布尔类型(如
true
,false
),可以直接判断if (cond) {...}
。 - 但在 C 中,条件
cond
是一个整数表达式,0
表示假,非0
表示真。 - 所以 C 的
if (E)
实际上是:“如果E == 0
,则跳过”。 - 因此,if 语句的生成必须显式地和
0
比较,使用ifEqual
或ifEqualZero
等三地址跳转语句。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Totoroの旅!
评论