编译原理学习笔记—CH6中间代码生成

本章要解决的问题

        声明以及语句的语义效果的实现(三地址指令或四元式的生成)

主要的知识点:

  • 声明语句的翻译
    • 符号表的建立和使用
    • 变量的类型声明语句的翻译,主要工作是
      • 将类型表达式填入变量表
      • 计算各变量的相对偏移地址
    • 类型推导(忽略)
      • 类型推导(inference)、类型综合(synthesis)、
      • 类型合一(unification:求最大公共子集
  • 表达式翻译及数组元素的寻址
    • 在语义规则中利用类型表达式计算数组下标
      • 两种方法
        • 主要使用第一种:a\left [ i_1 \right ]\left [ i_2 \right ]=Base+i_1*w_1+i_2*w_2
  • 控制流语句的翻译
    • if then else语句为代表,其他的控制流问题比如布尔表达式的短 路计算、循环语句,case语句等在概念上都是一样的。
    • 主要了解“.true” 、 “.false”尤其是“.next”的作用。
  • 并链与回填
    • 这个问题的产生在于语句标号和语句序号的不同。三地址语句使用 的是语句标号,四元式使用的是语句序号。语句标号是可以任意指 定的,不重复就可以,而语句序号是严格依序递增的。当一个跳转 语句向序号更大的语句(程序末尾方向)跳转时,无法得知跳转目 的地的序号(不知道离目的地有多远),需要等待跳转目的地的中 间指令生成时才能知道这个序号。并链就是跳到同一个目的地的跳 转语句手拉手排队,一起等通知。
    • 对一个跳转语句,如果当前产生式中无法得知跳转目的地的序号, 那么就需要等待回填,等待回填的话再问问自己,当前有人和我去 同一个地方吗?如果有,那么咱们就并链等待回填,等待回填的语 句记录在truelistfalselistnextlist里,truelistfalselist分别是条 件为真或为假时的等待回填的跳转语句(的链头),nextlist是其 他语句(主要是复合语句)的跳转语句的链头。
  • .true, .false, .next要么产生是自己决定,要么继承自环境。
  • .truelist, .falselis, .nextlist,都是下级向上级汇报。
  • 并不是所有指向小序号的goto都不回填(例如while循环体的
  • nextlis)。序号的大小不是决定因素,目的地是否由当前产生式决
  • 定才是决定因素。
  • 做题时注意保留修改痕迹,给出尚未回填的list

1.三地址代码-Three-address Code(TAC) 

地址可以具有的形式:

  • 名字,A name(source-program names).
  • 常量,A constant.
  • 编译器生成的临时变量,A compiler-generated temporary.

1.1TAC类型和形式

二元算术和逻辑操作x = y \text{ op } z
一元操作x = op \text{ y}
复制x=y
unconditional jump无条件转移
goto \text{ L}
条件转移\text{if x goto L}\\ \text{if False x goto L}\\ \text{if x rel.op y goto L}
函数调用p(x_1,x_2,x_3...x_n)\\ param \text{ }x_1\\ param \text{ }x_2\\ param \text{ }x_3\\ ...\\ param \text{ }x_n\\ call \text{ }p, n
返回returnreturn y
Indexed copy instructions
索引的复制指令
x = y[i]\\ y[i]=x
取地址x=\& y
解引用x=*y\\ *x = y

1.2(语句标号与语句序号)Symbolic Labels vs. Position Numbers

1.3四元式Quadruples

2.类型和声明Types and Declarations

 类型的应用可以分为:

  1. 类型检查,&&左右两边应该是bool
  2. 翻译时的应用,根据类型确定所需内存空间大小

2.1类型表达式type expression

类型表达式包括:

  1. 基本类型
  2. 类型构造算子作用域类型表达式

 上面的笛卡尔积的部分用来表示如函数参数

其中上箭头表示指针

2.2类型等价Type Equivalence

2.2.1按结构等价

及具有相同的实现方式

2.2.2按名称等价

3.表达式翻译Translation of Expressions

  • 表达式翻译及数组元素的寻址
    • 在语义规则中利用类型表达式计算数组下标
      • 两种方法
        • 基于类型表达式的方法(龙书第二版,简单)
        • 基于矩阵结构的方法(龙书第一版,复杂)

 3.1表达式中的运算

SDD使用S.code & E.addr & E.code, code代表三地址代码, addr代表值地址 

3.2增量翻译Incremental Translation

简单来说,放弃了使用code属性拼接三地址指令,每生成一个新的三地址指令就将其输出。增量的输出。

 3.3数组元素寻址Addressing Array Elements

这里默认下标从0开始。

其中 w_i 是已经计算好的,存放在符号表中的数值,所以在生成三地址代码时不应该再次计算

注意:当下标不从0开始时,

 3.4数组引用翻译Translation of Array References

gen()代表产生三地址语句 

例子 :  

4.控制流

4.1布尔表达式

用途:

  1. 改变控制流,如if(E) S; 执行到S说明E为true
  2. 计算逻辑值,将true or false赋值给其他变量

 注意B的结合律和op的优先级,

4.1.1 short circuit code 短路代码(跳转代码)

两个例子:

 

B1是false的时候应该继续计算B2,所以B1.false是一个newlabel()

疑问 :什么是translation scheme

答 : L-SDD 或 S -SDD 

\left \{ B_1.true = B.true,B_1.false = newlabel() \right \}B_1||\left \{ B_2.true = B.true, B_2.false = B.false \right \}B_2\left \{ B.code = B_1.code||label(B_1.false)||B_2.code \right \}

 你可能会有疑问:为什么\left \{ B.code = B_1.code||label(B_1.false)||B_2.code \right \},中间要接上一个label(B1.false),因为在B1.code中最后有一个goto B1.false,而B1.false是新分配的标签也就是newlabel()。

例子: 

 4.2控制流语句(flow of control statements)

注意whlie循环中S_1.next等于begin,以及每一个语句中标签的附加位置

5.并链和回填

 有.truelist\\ .falselist\\ .nextlist在同一个list中的跳转指令具有相同的目标标号。主要看产生式行为

其中merge(p1,p2)是将p2尾指向p1头,并返回p2头,同时需要更新接收的goto 0;

做题时需要将goto 0中的0划去然后回填,保留修改痕迹。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值