编译原理第七章 语义分析和中间代码的产生

知识总结

语义分析

审查每一个语法结构的静态语义,即验证语法正确的结构是否有意义。

语义分析的范围:确定类型、类型检查、识别含义、控制流检查、一致性检查、相关名字检查。

中间语言

1、后缀式(逆波兰表示法):运算符在后

2、图表示法

(1)抽象语法树:后缀式实际上是抽象语法树的线性表示形式(后序表示)。

(2)无循环有向图(DAG):对表达式中的每个子表达式,DAG中都有一个结点。一个内部结点表示一个操作符,它的孩子表示操作数。

区别:在一个DAG中代表公共子表达式的结点具有多个父结点,而在一棵抽象语法树中公共子表达式被表示为重复的子树。

3、三地址代码

由x:=y op z形式的语句构成的序列。通常有三种表示方法:

(1)四元式:带有四个域op,arg1,arg2及result的记录结构,实际上就是一条三地址的指令

(2)三元式:由三个部分组成:算符OP、第一运算分量ARG1、第二运算分量:ARG2

  • 为了避免把临时变量填入符号表

(3)间接三元式:在三元式的基础上附加一张指示器表─间接码表,按运算的先后顺序列出有关三元式在三元式表中的位置

  • 为了便于代码优化处理

基于语法制导的翻译

1、赋值语句的翻译

2、布尔表达式的翻译

作为条件的布尔表达式,把它设计成两个出口:E.true 和 E.false

  • 对于IF语句,E.true   指向S1,   E.false指向S2;
  • 对于while语句E.true  指向循环的开始,   E.false指向while 的下一语句

3、数组元素的表达式和赋值句的翻译

一般编译程序对数组说明的处理是把数组的有关信息汇集在一个叫“内情向量”的表格中。

若数组A的元素存放在一片连续单元里,假定数组的每个元素的宽度为w,则一维数组A[i] 这个元素的起始地址为:base + (i – low)*w,可整理为:i*w + (base –low*w)

其中low为数组下标的下界,base是分配给数组的相对地址,即base为A的第一个元素A[low]的相对地址。

(1) i*w  是随数组下标变量而变化的部分,记为VARPART

(2)(base – low*w)是在数组中不变化的常数记为CONSPART

若二维数组A按行存放,则A[i1,i2]的相对地址:base + (( i1 – l1)*d2 + i2 – l2) *w

  • 数组的翻译方案是:产生两组计算数组元素地址的四元式:

一组是计算VARPART,并将计算结果放入临时变量T1,

另一组是计算CONSPART,并将计算结果放入临时变量T2,用T2[T1]表示数组元素的地址。

4、控制语句的翻译

仿照算术表达式的翻译来进行,对于控制语句中的条件表达式,必须结合控制语句作进一步的分析。

可以把作为控制条件的任何布尔表达式表示成仅含下列三种形式的四元式的序列:

  (jnz,a,--,p)  表示 if  a goto p

  (jrop,x,y,p)  表示 if  x rop y goto p

  (j,--,--,p)   表示 goto  p

  • 例:考虑如下语句:

   while a<b do

   if c<d then

      x:= y+z

   else

      x:=y-z

根据前面所述,生成代码为:

   L1 :if a<b goto L2

               goto Lnext

   L2 :if c<d goto L3

               goto L4

   L3 :t1 := y+z

               x:=t1

               goto L1

   L4 :t2:=y-z

               x:=t2

      goto L1

   Lnext:

总结感悟

      第七章感觉是这些章节里面难度最小的一章了,比较容易掌握,知识脉络也很清晰。重点就是掌握中间语言的各种表示方法和基于语法制导的翻译,如赋值语句的翻译、布尔表达式的翻译、数组的翻译以及控制语句的翻译。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值