本次笔记内容:
6-8 布尔表达式的回填
6-9 控制流语句的回填
6-10 SWITCH语句的翻译
6-11 过程调用语句的翻译

本节课幻灯片,见于我的 GitHub 仓库:第14讲 中间代码生成_4.pdf

文章目录

  • 布尔表达式的回填
    • 回填(Backpatching)
    • 非终结符B的综合属性
    • 函数
    • 布尔表达式的回填
    • 举例
  • 控制流语句的回填
    • 文法与综合属性
    • S → if B then S1
    • S → if B then S1 else S2
    • S → while B do S1
    • S → S1 S2
    • S → id = E ; | L = E ;
    • 举例
  • switch语句的翻译
    • switch语句的翻译
    • switch语句的另一种翻译
    • 增加一种case指令
  • 过程调用语句的翻译
    • 文法
    • 过程调用语句的代码结构
    • 过程调用语句的SDD
    • 例:翻译以下语句f(b*c-1,x+y,x,y)

布尔表达式的回填

回填(Backpatching)

基本思想: 生成一个跳转指令时,暂时不指定该跳转指令的目标标号。这样的指令都被放入由跳转指令组成的列表中。同一个列表中的所有跳转指令具有相同的目标标号。等到能够确定正确的目标标号时,才去填充这些指令的目标标号。

非终结符B的综合属性

B.truelist:指向一个包含跳转指令的列表,这些指令最终获得的目标标号就是当B为时控制流应该转向的指令的标号。

B.falselist:指向一个包含跳转指令的列表,这些令最终获得的目标标号就是当B为时控制流应该转向的指令的标号。

函数

makelist(i):创建一个只包含 i 的列表, i 是跳转指令的标号,函数返回指向新创建的列表的指针。
merge(p1, p2):将 p1 和 p2 指向的列表进行合并,返回指向合并后的列表的指针
backpatch(p, i):将 i 作为目标标号插入到 p 所指列表中的各指令中。这就是回填函数

布尔表达式的回填


如上,两条 gen 指令的目标标号等待回填,因此,我们把他们放到相应的列表中。第一条 gen 跳转指令其目标标号是 B 的真出口,因此将其放入 B.truelist 中。这里 nextquad 是指,及即将生产的指令的标号。





如上图,先画结构图,把真出口、假出口关系梳理明白。以此,把哪些指令属于 turelist 哪些属于 falselist 整理好。

为了记下 B2 的第 1 条指令的标号,我们在非终结符 B2 前插入一个标记非终结符 M 。M关联的语句动作,任务就是记录下 B2 的第 1 条指令的标号。这里为 M 定义了一个综合属性 quad

因此,这个 M.quad 需要回填到 B1.falselist 中。

由图可得,B 的 truelist 由 B1.truelist 与 B2.truelist 合并而成,因此有 merge 动作。

分析同理如上。

举例

我们准备翻译这句话:

a < b or c < d and e < f

采用自底向上的分析。

从左到右扫描。 ttruelist简写。

根据逻辑运算符优先级,and 高于 or ,因此遇到 and 先将 and 移入。

栈顶的 B and B 被归约为 B ,并且用其中的 M.quad 回填 B1.truelist 中的指令 102 号指令,值为 104 。

继续依照语法分析、回填如上。

控制流语句的回填

文法与综合属性

S → if B then S1


先来画翻译方案的示意图,接着编写 SDT 。

S → if B then S1 else S2

S → while B do S1

S → S1 S2

S → id = E ; | L = E ;


赋值语句中不包含跳转指令,所以 S.nextlist 为空。

举例

while a < b doif c < 5 thenwhile x > y do z = x + 1;elsex = y;


从左向右扫描输入串,构建注释分析树。

最终,我们将顺带着生成控制流语句的三地址码

自然式形式如上右部分。

switch语句的翻译

switch语句的翻译


switch 的代码结构图如右所示。根据代码结构图可以生成翻译方案,如下。

如上,每一个跳转指令,其四元式的第四个分量,都不是目标标号(如红色框框),而是存放目标标号的地址,因此,需要在做一趟处理,将地址与标号绑定起来。

在这个翻译方案中,分支测试指令是与各个 S 的代码混合在一起的。事实上,当分支测试较多时,可以将分支测试指令集中在一起,这样便于生成高效的分支测试代码。

因此,给出另一种翻译方案。

switch语句的另一种翻译


在代码生成阶段,根据分支的个数以及这些值是否在一个较小的范围内,这种条件跳转指令序列可以被翻译成最高效的n路分支

增加一种case指令


为了方便代码生成器检测代码,因此生成一种新的指令:case指令。

过程调用语句的翻译

文法


call为过程调用关键字。

过程调用语句的代码结构


过程调用的代码主要是由表达式的代码组成的。可以将param指令统一整理到后面。

过程调用语句的SDD


由结构图构建 SDD 如上左。

例:翻译以下语句f(b*c-1,x+y,x,y)


对于 b*c-1,我们生成其三地址码:

  • t1=b∗ct_1 = b*ct1​=b∗c
  • t2=t1−1t_2 = t_1 - 1t2​=t1​−1

其中,t2t_2t2​就是第1个参数表达式的值,我们把t2t_2t2​放到队列 Q 中。

接下来计算第2个参数表达式的值:

  • t3=x+yt_3 = x+yt3​=x+y

t3t_3t3​就是第2个参数表达式的值,我们把t3t_3t3​放到队列 Q 中。

第3、4个参数表达式就存放在其本身(即xxx,yyy)中。因此把xxx,yyy放在队列中。

然后,生成4条 param 指令

param t2
param t3
param x
param y
# 最后,生成过程调用指令
call y, 4

【编译原理笔记14】中间代码生成:布尔表达式的回填,控制流语句的回填,switch语句的翻译,过程调用语句的翻译相关推荐

  1. 【编译原理笔记20】代码生成:代码生成器的主要任务,一个简单的目标机模型,指令选择,寄存器的选择,寄存器选择函数getReg的设计,窥孔优化

    本次笔记内容: 9-1 代码生成器的主要任务 9-2 一个简单的目标机模型 9-3 指令选择 9-4 寄存器的选择 9-5 寄存器选择函数getReg的设计 9-6 窥孔优化 本节课幻灯片,见于我的 ...

  2. 编译原理笔记(二)之词法分析

    编译原理笔记(二)之词法分析 1. 词法分析中的若干问题 1.1 基本概念 1.2 记号的属性 1.3 词法分析器的作用与工作方式 1.4 输入缓冲区 2. 模式的形式化描述 2.1 字符串与语言 2 ...

  3. zucc 编译原理 笔记

    zucc 编译原理 笔记 lec02 lec03 lec04

  4. 【编译原理笔记13】中间代码生成:控制流语句及其SDT,布尔表达式及其SDT,控制流翻译的例子

    本次笔记内容: 6-5 控制流语句SDT 6-6 布尔表达式SDT 6-7 控制流的栗子 本节课幻灯片,见于我的 GitHub 仓库:第13讲 中间代码生成_3.pdf 文章目录 控制流语句及其SDT ...

  5. 【编译原理笔记12】中间代码生成:简单赋值语句的翻译,数组引用的翻译

    本次笔记内容: 6-3 简单赋值语句的翻译 6-4 数组引用的翻译 本节课幻灯片,见于我的 GitHub 仓库:第12讲 中间代码生成_2.pdf 文章目录 简单赋值语句的翻译 赋值语句翻译的任务 赋 ...

  6. 【编译原理笔记01】什么是编译,编译系统各结构作用

    资源Bilibili AV17649289 编译原理 哈尔滨工业大学 陈鄞 本次笔记内容: 1-1 什么是编译 1-2 编译系统的结构 1-3 词法分析 1-4 语法分析概述 1-5 语义分析概述 1 ...

  7. 了解编译原理-笔记小结

    这是之前学习编译原理过程中做下的笔记. 因能力有限,在很多地方都理解不到位,特别是对于词法分析与语法分析的过程感觉特别晦涩. 分享这个笔记也是为了自己做个总结,算是一个小的提纲吧,都没怎么深入解析编译 ...

  8. 编译原理笔记 导言和目录

    本学期编译原理的学习也差不多快结束了,在学习过程中也做了不少笔记. 为了准备即将来到的考试,我想把学习笔记再整理一遍.借此机会创建了这个专栏--为了满足创建专栏之前必须发布15篇以上的原创文章,我还特 ...

  9. 编译原理拉链回填技术c语言,编译原理笔记1:概述编译相关的基本知识

    本系列为个人编译原理学习笔记,谬误之处恳请高人指点,感激不尽! 内容整理自西安电子科技大学 王小兵.张南.鱼滨老师的编译原理课程. 编译器的工作步骤 在开始说任何东西之前,我们先来大致看一下编译器是怎 ...

最新文章

  1. eclipse插件 --js
  2. Linux系统调优概述
  3. Spring MVC--接收JSON格式的数据
  4. centos7 redis5.0以前版本 集群部署示例 - 第一篇
  5. java jmeter_使用Jmeter中的Java Request进行性能测试
  6. 【转】iOS 10 UserNotifications 使用说明
  7. 设计师需要收藏|一起来看看UI设计的配色专辑
  8. 阅读bulid to win感想
  9. Lazyload 延迟加载效果(转载)
  10. Ample Sound Ample Guitar Semi Hollow Mac - 半空心体式吉他
  11. 【优化算法】闪电连接过程优化算法(LAPO)【含Matlab源码 1444期】
  12. 微信小程序 ui框架(辅助)
  13. 内存超频时序怎么调_内存超频(ddr4内存时序多少为好)
  14. 什么是串口并行,串口接行
  15. Delphi 金额转大写
  16. 今年新型城镇化新看点:加快户籍改革 建设新型智慧城市
  17. 端午节之苍南懒人游 (*^__^*) ……
  18. python动物农场小说网站爬虫_中文编程,用python编写小说网站爬虫
  19. 【C++学习笔记】函数基础和参数传递
  20. 针对勒索病毒WannaCrypt微软官方应对指南

热门文章

  1. Linux 下使用Postgre中的命令,要使用postgres这个用户
  2. win7下,令人头疼的 classpnp.sys (附带:安装系统时蓝屏;0x0000007b)。
  3. mysql show sleep_mysq解决sleep进程过多的办法
  4. java.lang unsupported classversion解决方法
  5. 解决ajax无法给js全局变量赋值的问题
  6. Android studio R文件丢失或错误解决方法
  7. 通过Android上的意图启动Google地图路线
  8. 如何在JUnit4中按特定顺序运行测试方法?
  9. win11系统如何绕过tpm检测进行安装 Windows11绕过tpm安装的解决方法
  10. ros自定义service消息.srv文件中增加自定义.msg消息