编译器设计中控制语句的翻译是什么?
控制语句是可以改变语句执行流程的语句。
考虑语法
S → if E then S1
|if E then S1 else S2
|while E do S1
在这个语法中,E 是布尔表达式,根据它将执行 S1 或 S2。
以下表示显示了 if-then、ifthen-else 和 while do 指令的执行顺序。
- 𝐒 → 𝐢𝐟 𝐄 𝐭𝐡𝐞𝐧 𝐒𝟏
E.CODE 和 S.CODE 是生成三地址代码的一系列语句。
E.TRUE 是如果 E 为真则控制流到的标签。
E.FALSE 是如果 E 为假则控制流到的标签。
E 的代码如果 E 为真则生成跳转到 E.TRUE,如果 E 为假则生成跳转到 S.NEXT。
∴ 在下表中,E.FALSE=S.NEXT。
在下表中,为 E.TRUE 分配了一个新标签。
当执行 S1.CODE 时,控制将跳转到 S 之后的语句,即跳转到 S1.NEXT。
∴ S1. NEXT = S. NEXT。
"If E then S1" 的语法制导翻译。
产生式 | 语义规则 |
---|---|
𝐒 → 𝐢𝐟 𝐄 𝐭𝐡𝐞𝐧 𝐒𝟏 | E. TRUE = newlabel; E. FALSE = S. NEXT; S1. NEXT = S. NEXT; S. CODE = E. CODE | | GEN (E. TRUE '− ') | | S1. CODE |
- 𝐒 → 𝐈𝐟 𝐄 𝐭𝐡𝐞𝐧 𝐒𝟏 𝐞𝐥𝐬𝐞 𝐒𝟐
如果 E 为真,控制将转到 E.TRUE,即执行 S1.CODE,然后 S.NEXT 出现在 S1.CODE 之后。
如果 E.CODE 为假,则将执行 S2.CODE。
最初,E.TRUE 和 E.FALSE 都被视为新标签。当在标签 E.TRUE 上执行 S1.CODE 时,控制将跳转到 S.NEXT。
因此,在 S1 之后,控制将跳转到完整语句 S 的下一条语句。
S1.NEXT=S.NEXT
类似地,在 S2.CODE 之后,将执行 S 的下一条语句。
∴ S2.NEXT=S.NEXT
"If E then S1 else S2" 的语法制导翻译。
产生式 | 语义规则 |
---|---|
𝐒 → 𝐢𝐟 𝐄 𝐭𝐡𝐞𝐧 𝐒𝟏 𝐞𝐥𝐬𝐞 𝐒𝟐 | E. TRUE = newlabel; E. FALSE = newlabel; S1. NEXT = S. NEXT; S2. NEXT = S. NEXT; S. CODE = E. CODE | | GEN (E. TRUE '− ') | | S1. CODE GEN(goto S. NEXT) | | GEN (E. FALSE −) | | S2. CODE |
- 𝐒 → 𝐰𝐡𝐢𝐥𝐞 𝐄 𝐝𝐨 𝐒𝟏
另一个重要的控制语句是 while E do S1,即语句 S1 将一直执行,直到表达式 E 为真。当表达式 E 变为假时,控制将退出循环。
创建一个指向 E 的第一个指令的标签 S. BEGIN。标签 E.TRUE 附加到 S1 的第一个指令。如果 E 为真,控制将跳转到标签 E.TRUE 并执行 S1.CODE。如果 E 为假,控制将跳转到 E.FALSE。在 S1.CODE 之后,控制将再次跳转到 S. BEGIN,这将再次检查 E.CODE 是否为真或假。
∴ S1. NEXT = S. BEGIN
如果 E.CODE 为假,控制将跳转到 E.FALSE,这将导致执行 S 之后的下一条语句。
∴ E. FALSE = S. NEXT
" 𝐒 → 𝐰𝐡𝐢𝐥𝐞 𝐄 𝐝𝐨 𝐒𝟏 " 的语法制导翻译。
产生式 | 语义规则 |
---|---|
𝐒 → 𝐰𝐡𝐢𝐥𝐞 𝐄 𝐝𝐨 𝐒𝟏 | S. BEGIN = newlabel; E. TRUE = newlabel; E. FALSE = S. NEXT; S1. NEXT = S. BEGIN; S. CODE = GEN(S. BEGIN '− ') | | E. CODE | | GEN(E. TRUE '− ')| | S1. CODE | | GEN('goto' S. BEGIN) |