什么是反向补丁 (Backpatching)?
在为给定表达式生成三地址码时,它可以指定 goto 语句中标签的地址。在一遍扫描中很难分配这些标签语句的位置,因此使用两遍扫描。在第一遍扫描中,它可以不指定这些地址;在第二遍扫描中,它可以填充这些地址。因此,对不完整转换的填充称为反向补丁 (Backpatching)。
使用反向补丁的一遍代码生成
反向补丁可用于为布尔表达式和控制流语句生成一遍程序。在此,非终结符 B 的综合属性 truelist 和 falselist 用于处理布尔表达式的跳转代码中的标签。
具体来说,B.truelist 将是一个跳转或条件跳转指令列表,如果 B 为真,则应在其中添加控制跳转到的标签。B.falselist 同样是最终获得控制跳转到标签的指令列表,此时 B 为假。
当为 B 生成程序时,对真假存在的跳转将保持不完整,标签字段未填充。这些初步跳转位于 B.truelist 和 B.falselist 指向的列表上(视情况而定)。
同样,语句 S 具有综合属性 S.nextlist,指示跳转到 S 代码之后指令的列表。它可以将指令生成到指令数组中,标签将是此数组中的索引。为了操作跳转列表,我们使用三个函数:
**Makelist (i)** - 创建一个新列表,其中仅包含 i,它是指令数组中的一个索引;makelist 返回指向新生成的列表的指针。
**Merge(p1,p2)** - 连接 p1 和 p2 指向的列表,并返回指向连接列表的指针。
**Backpatch (p, i)** - 将 i 插入到 p 指向的记录上的每个指令的目标标签中。
布尔表达式的反向补丁
它可以创建一个适合在自下而上分析期间为布尔表达式生成代码的翻译方案。语法中的非终结符标记 M 生成一个语义操作,以便在适当的时间获取要创建的下一条指令的索引。语法如下:
B → B1| | MB2|B1&& MB2|! B1|(B1)|E1rel E2|True|False
M → ϵ
控制流语句
控制语句是改变语句执行流程的语句。例如,If、If-else、Switch-Case、while-do 语句。在编程语言中,布尔表达式通常用于
**改变控制流** - 布尔表达式用作改变控制流的语句中的条件表达式。此类布尔表达式的值隐含在程序中达到的位置。例如,if (E) S,如果到达语句 S,则表达式 E 必须为真。
**计算逻辑值** - 布尔表达式可以描述真或假值。可以使用带有逻辑运算符的三地址指令并行计算此类布尔表达式,就像算术表达式一样。