2020-编译原理-IR2-中间代码继承

IR2-中间代码继承

1. 控制流语句与布尔表达式的中间代码继承

label(xxx)表示名为xxx的标签

Sif (B) S1Sif (B) S1 else S2Swhile (B) S1\begin{array}{l} S \rightarrow if\ (B)\ S_1 \\ S \rightarrow if\ (B)\ S_1\ else\ S_2\\ S \rightarrow while\ (B)\ S_1 \\ \end{array}

1.1. 生成式转化为语义规则示例

1.2. 一些语句得到的中间代码示例

继承属性S.next:S的下一条指令

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

S.codeS.next:\begin{aligned} &S.code \\ &S.next: \\ \end{aligned}

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

assign.code\begin{aligned} &assign.code \\ \end{aligned}

BB为真,则newlabelnewlabel,否则跳出S1S_1,上面写法不好,会给人在属性的类型上带来歧义,第二行应该是如下两行:

B.false=S.nextS1.next=S.next\begin{array}{l} B.false = S.next \\ S_1.next = S.next \\ \end{array}

翻译为中间代码如下

B.codeB.true: S1.codeB.false(S.next):\begin{aligned} &B.code\\ &B.true:\ S_1.code\\ &B.false(S.next):\\ \end{aligned}

  1. 左侧的goto S.next代表了执行完S1后,跳过else S2继续执行
  2. 由此右侧的代码可以翻译为如下的伪代码,其中第一行代表SStruetrue的位置为BB,第二行为S1S_1truetrue的位置为BB,第一个assignassignS11S_{11},第二个assignassignS12S_{12},剩下的一个assignassign所在行为S2S_2

B.codeB.true:S1.codegoto S.nextB.false:S2.codeS.next:\begin{aligned} &B.code \\ &B.true: S_1.code \\ &\qquad\qquad goto\ S.next \\ &B.false: S_2.code \\ &S.next:\\ \end{aligned}

  1. 继续进行翻译,同样的规定,其中第一行代表S,true的位置为B,第二行为S1,true的位置为B,第一个assign为S11,第二个assign为S12。
  2. 中间代码格式

begin:B.codeB.true:S1.codegoto beginB.false:\begin{aligned} &begin: B.code \\ &B.true: S_1.code \\ &\qquad\qquad goto\ begin\\ &B.false: \\ \end{aligned}

中间代码如下

S1.codeS1.next:S2.code\begin{aligned} &S_1.code \\ &S_1.next: S_2.code \\ \end{aligned}

1.3. 生成式与语义规则对应表

2. 短路求值

中间代码示例

B1.codeB1.false:B2.codeB1.true(B.true/B2.true):B2.false:\begin{aligned} &B_1.code \\ &B_1.false: B2.code \\ &B_1.true(B.true/B_2.true):\\ &B_2.false:\\ \end{aligned}

中间代码示例

B1.codeB1.true:B2.codeB2.true(B.true):B1.false(B2.false/B.false):\begin{aligned} &B_1.code \\ &B_1.true: B2.code \\ &B_2.true(B.true):\\ &B_1.false(B_2.false/B.false):\\ \end{aligned}

rel是比较符号,得到的中间代码如下
中间代码示例

E1.codeE2.codeif E1.addr rel.op E2.addr goto B.truegoto B.falseB.true:B.false:\begin{aligned} &E_1.code \\ &E_2.code \\ &if\ E_1.addr\ rel.op\ E_2.addr\ goto\ B.true \\ &\qquad goto\ B.false\\ &B.true:\\ &B.false:\\ \end{aligned}

  1. 对于这个例子:E1.codeE_1.code是空,但是E1.addrE_1.addr是非空的
  2. 拆开分别分析,慢慢深入

3. 布尔表达式的作用: 布尔值vs. 控制流跳转

  1. 函数jump(t,f)jump(t, f): 生成控制流代码
  2. 函数rvalue()rvalue(): 生成计算布尔值的代码, 并将结果存储在临时变量中

  1. 为E生成跳转代码, 在真假出口处将true或false存储到临时变量


2020-编译原理-IR2-中间代码继承
https://spricoder.github.io/2021/01/16/2020-Compilation-Principle/2020-Compilation-Principle-IR2-%E4%B8%AD%E9%97%B4%E4%BB%A3%E7%A0%81%E7%BB%A7%E6%89%BF/
作者
SpriCoder
发布于
2021年1月16日
许可协议