布尔表达式的文法与代码结构在编译原理中属于**中间代码生成**阶段的重要内容

布尔表达式的文法与代码结构在编译原理中属于中间代码生成阶段的重要内容,主要用于将高级语言中的逻辑判断(如 ifwhile 中的条件)转换为带有控制流信息的中间表示(如四元式),并利用“短路求值”机制优化执行效率。


一、布尔表达式的上下文无关文法(CFG)

常见的布尔表达式文法可定义如下(经过左递归消除以适用于自顶向下分析):

E → E1 or T     { E.tc = Merge(E1.tc, T.tc); E.fc = T.fc; }
  | T           { E.tc = T.tc; E.fc = T.fc; }

T → T1 and F    { T.tc = F.tc; T.fc = Merge(T1.fc, F.fc); }
  | F           { T.tc = F.tc; T.fc = F.fc; }

F → not F1      { F.tc = F1.fc; F.fc = F1.tc; }
  | ( E )       { F.tc = E.tc; F.fc = E.fc; }
  | rel         { F.tc = NewLabel(); F.fc = NewLabel();
                  Gen('if', rel.op, 'goto', F.tc);
                  Gen('goto', '', '', F.fc); }

其中:

  • rel 表示关系表达式(如 a < b
  • tc:真出口(true chain),当表达式为真时跳转的目标标签链
  • fc:假出口(false chain),当表达式为假时跳转的目标标签链
  • NewLabel():生成新的标签
  • Gen(op, arg1, arg2, result):生成一条四元式
  • Merge(c1, c2):合并两个出口链,返回合并后的链头
  • Backpatch(chain, label):将链中所有待填地址回填为 label

二、关键概念解析

1. 短路计算(Short-Circuit Evaluation)
  • A and B:若 A 为假,则不计算 B
  • A or B:若 A 为真,则不计算 B
  • 编译时通过控制流跳转实现,无需实际求值
2. 真出口(tc)与假出口(fc)

每个非终结符(如 E、T、F)携带两个属性:

  • tc:指向“应跳往真分支”的标签链(即该子表达式为真时需跳转的位置)
  • fc:指向“应跳往假分支”的标签链

这些不是立即确定的地址,而是待回填的跳转链表(拉链法)

3. 拉链与回填技术
  • 拉链(Chaining):将尚未确定目标地址的跳转指令组织成链(通过链接字段指向下一条待填指令编号)
  • 回填(Backpatch):当目标地址确定后,遍历链中所有指令并填写正确地址

例如:

def Backpatch(chain, label):
    while chain:
        instruction[chain.index].target = label
        chain = chain.next

三、翻译示例:E → E¹ and E²

语义动作:

E.tc =.tc
E.fc = Merge(.fc,.fc)
Backpatch(.tc,.begin_label)   # 若E¹为真,继续计算E²

说明:

  • 只有当 为真时才需要评估
  • 所以要把 的真出口(tc)回填到 的起始位置
  • E 整体为真的出口是 为真的出口
  • E 整体为假的出口是 为假的出口合并而成

四、常见语句的翻译

1. if (B) S1
  • B.true_chain 回填到 S1 起始
  • B.false_chain 是整个 if 结束后的出口
  • 无 else 时,直接回填 B.fcnext_instruction
2. if (B) S1 else S2
  • B.tcS1.begin
  • B.fcS2.begin
  • S1.chainS2.chain 合并为后续语句入口
3. while (B) S
  • 生成循环开始标签 L1
  • Btc 指向 S.begin
  • Bfc 指向循环结束 L2
  • S.chain 回填到 L1 实现循环
  • 使用 Gen('goto', '', '', L1)S 后跳回

五、四元式示例(基于GEN函数)

假设表达式:(a < b) or (c > d)

生成的四元式可能如下:

100: if a < b goto 102
101: goto 103
102: goto 105          ; // 真出口直接跳过整个or的假分支
103: if c > d goto 105
104: goto 106
105: ...               ; // 真出口汇聚点
106: ...               ; // 假出口

注意:实际中使用链式管理,避免立即指定具体标号。


在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bol5261

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值