编译器设计中的回补
Backpatching 基本上是一个完成未指定信息的过程。此信息属于标签。它基本上在代码生成过程中使用适当的语义动作。它可以在 goto 语句中指示标签的地址,同时为给定的表达式生成 TAC。这里基本上使用了两遍,因为在一遍中分配这些标签语句的位置非常具有挑战性。它可以在第一轮中使这些地址无法识别,然后在第二轮中填充它们。 Backpatching 是在不完整的转换和信息中填补空白的过程。
需要Backpatching:
Backpatching 主要用于两个目的:
1. 布尔表达式:
布尔表达式是其结果可以为真或假的语句。以数学家 George Boole 命名的布尔表达式是一个计算结果为真或假的表达式。让我们看一些常见的语言示例:
- 我最喜欢的颜色是蓝色的。 → 真的
- 我害怕数学。 → 假
- 2 大于 5。 → false
2. 控制语句流
在程序中执行语句的过程中,需要控制控制语句的流向。例如:
使用 backpatching 的一次性代码生成:
在单程中,回补可用于创建布尔表达式程序以及控制语句流。非终结符 B 的综合属性 truelist 和 falselist 用于处理布尔语句跳转代码中的标签。如果 B 为真,控制应该转到的标签应该添加到 B.truelist,它是跳转或条件跳转指令的列表。 B.falselist 是指令列表,当 B 为假时,这些指令最终获得分配控制的标签。为 B 生成程序时,存在到 true 和 false 的跳转以及标签字段留空。列表 B.truelist 和 B.falselist 分别包含这些早期跳转。
例如,一条语句 S 有一个综合属性 S.nextlist,它表示在 S 的代码之后立即跳转到指令的列表。它可以将指令生成到指令数组中,标签用作索引。我们利用三个函数来修改跳转列表:
- Makelist (i):创建一个仅包含 i 的新列表,该列表是指令数组的索引,并且 makelist 还返回指向新生成列表的指针。
- Merge(p1,p2):连接 p1 和 p2 指向的列表,并返回一个指向连接列表的指针。
- Backpatch (p, i):插入 i 作为目标标签,用于 p 指向的记录上的每个指令。
布尔表达式的回补:
使用翻译技术,它可以在自底向上解析期间为布尔表达式创建代码。在语法中,非终结标记 M 创建一个语义动作,该动作在适当的时间获取要创建的下一条指令的索引。
例如, Backpatching 使用布尔表达式产生规则表:
第一步:生成生产表
第 2 步:我们必须使用回补找到给定表达式的 TAC(三地址代码):
A < B OR C < D AND P < Q
第 3 步:现在我们将为表达式制作解析树:
控制语句的流程:
控制语句是那些改变语句执行顺序的语句。 If、If-else、Switch-Case 和 while-do 语句就是示例。布尔表达式常用于计算机语言中
- 改变控制流:布尔表达式是改变语句中控制流的条件表达式。这种布尔语句的值隐含在程序的位置中。例如,如果 (A) B,如果到达语句 B,则表达式 A 必须为真。
- 计算逻辑值:在自下而上的解析过程中,它可以通过翻译机制为布尔语句生成代码。语法中的非终结标记 M 建立了一个语义动作,该动作在适当的时刻形成以下指令的索引。
Backpatching 的应用:
- Backpatching 用于在一次传递中转换控制流语句。
- Backpatching 用于在自底向上解析期间为布尔表达式生成四元组。
- 它是在代码生成过程中填充标签的未指定信息的活动。
- 它有助于解决已植入代码中的正向分支。