【编译原理笔记14】中间代码生成:布尔表达式的回填,控制流语句的回填,switch语句的翻译,过程调用语句的翻译
本次笔记内容:
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
采用自底向上的分析。
从左到右扫描。 t
为truelist
简写。
根据逻辑运算符优先级,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语句的翻译,过程调用语句的翻译相关推荐
- 【编译原理笔记20】代码生成:代码生成器的主要任务,一个简单的目标机模型,指令选择,寄存器的选择,寄存器选择函数getReg的设计,窥孔优化
本次笔记内容: 9-1 代码生成器的主要任务 9-2 一个简单的目标机模型 9-3 指令选择 9-4 寄存器的选择 9-5 寄存器选择函数getReg的设计 9-6 窥孔优化 本节课幻灯片,见于我的 ...
- 编译原理笔记(二)之词法分析
编译原理笔记(二)之词法分析 1. 词法分析中的若干问题 1.1 基本概念 1.2 记号的属性 1.3 词法分析器的作用与工作方式 1.4 输入缓冲区 2. 模式的形式化描述 2.1 字符串与语言 2 ...
- zucc 编译原理 笔记
zucc 编译原理 笔记 lec02 lec03 lec04
- 【编译原理笔记13】中间代码生成:控制流语句及其SDT,布尔表达式及其SDT,控制流翻译的例子
本次笔记内容: 6-5 控制流语句SDT 6-6 布尔表达式SDT 6-7 控制流的栗子 本节课幻灯片,见于我的 GitHub 仓库:第13讲 中间代码生成_3.pdf 文章目录 控制流语句及其SDT ...
- 【编译原理笔记12】中间代码生成:简单赋值语句的翻译,数组引用的翻译
本次笔记内容: 6-3 简单赋值语句的翻译 6-4 数组引用的翻译 本节课幻灯片,见于我的 GitHub 仓库:第12讲 中间代码生成_2.pdf 文章目录 简单赋值语句的翻译 赋值语句翻译的任务 赋 ...
- 【编译原理笔记01】什么是编译,编译系统各结构作用
资源Bilibili AV17649289 编译原理 哈尔滨工业大学 陈鄞 本次笔记内容: 1-1 什么是编译 1-2 编译系统的结构 1-3 词法分析 1-4 语法分析概述 1-5 语义分析概述 1 ...
- 了解编译原理-笔记小结
这是之前学习编译原理过程中做下的笔记. 因能力有限,在很多地方都理解不到位,特别是对于词法分析与语法分析的过程感觉特别晦涩. 分享这个笔记也是为了自己做个总结,算是一个小的提纲吧,都没怎么深入解析编译 ...
- 编译原理笔记 导言和目录
本学期编译原理的学习也差不多快结束了,在学习过程中也做了不少笔记. 为了准备即将来到的考试,我想把学习笔记再整理一遍.借此机会创建了这个专栏--为了满足创建专栏之前必须发布15篇以上的原创文章,我还特 ...
- 编译原理拉链回填技术c语言,编译原理笔记1:概述编译相关的基本知识
本系列为个人编译原理学习笔记,谬误之处恳请高人指点,感激不尽! 内容整理自西安电子科技大学 王小兵.张南.鱼滨老师的编译原理课程. 编译器的工作步骤 在开始说任何东西之前,我们先来大致看一下编译器是怎 ...
最新文章
- eclipse插件 --js
- Linux系统调优概述
- Spring MVC--接收JSON格式的数据
- centos7 redis5.0以前版本 集群部署示例 - 第一篇
- java jmeter_使用Jmeter中的Java Request进行性能测试
- 【转】iOS 10 UserNotifications 使用说明
- 设计师需要收藏|一起来看看UI设计的配色专辑
- 阅读bulid to win感想
- Lazyload 延迟加载效果(转载)
- Ample Sound Ample Guitar Semi Hollow Mac - 半空心体式吉他
- 【优化算法】闪电连接过程优化算法(LAPO)【含Matlab源码 1444期】
- 微信小程序 ui框架(辅助)
- 内存超频时序怎么调_内存超频(ddr4内存时序多少为好)
- 什么是串口并行,串口接行
- Delphi 金额转大写
- 今年新型城镇化新看点:加快户籍改革 建设新型智慧城市
- 端午节之苍南懒人游 (*^__^*) ……
- python动物农场小说网站爬虫_中文编程,用python编写小说网站爬虫
- 【C++学习笔记】函数基础和参数传递
- 针对勒索病毒WannaCrypt微软官方应对指南
热门文章
- Linux 下使用Postgre中的命令,要使用postgres这个用户
- win7下,令人头疼的 classpnp.sys (附带:安装系统时蓝屏;0x0000007b)。
- mysql show sleep_mysq解决sleep进程过多的办法
- java.lang unsupported classversion解决方法
- 解决ajax无法给js全局变量赋值的问题
- Android studio R文件丢失或错误解决方法
- 通过Android上的意图启动Google地图路线
- 如何在JUnit4中按特定顺序运行测试方法?
- win11系统如何绕过tpm检测进行安装 Windows11绕过tpm安装的解决方法
- ros自定义service消息.srv文件中增加自定义.msg消息