Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1092999
  • 博文数量: 104
  • 博客积分: 3715
  • 博客等级: 中校
  • 技术积分: 1868
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-30 08:38
文章分类

全部博文(104)

文章存档

2013年(1)

2012年(9)

2011年(41)

2010年(3)

2009年(3)

2008年(47)

分类:

2008-08-10 23:03:31

这一章主要讲了中间表示生成相关的东西。
基本上可以分为三个方面:1、中间表示有哪些;2、静态检查;3、利用语法制导技术将源代码翻译为中间表示。
中间表示:
最常见的中间表示基本上是抽象语法树AST。这个大家都熟悉,而且每个编译器都隐式或显式地构造。这种中间表示非常接近源语言,它本身就是源语言中结构的自然表示。树的一个重要的变种是DAG,在表达式方面有独到之处。另外,SSA似乎已经是一个很重要的中间表示了。GCC4用的就是SSA做主要的中间表示。GCC的GIMPLE是一种三地址码。
静态检查:
主要是类型检查。还会检查一些其它的语法或语义的东西。
语法制导翻译已经在Chapter5中讲过,这里是一些比较具体的应用。

1、选一个中间表示:中间表示一般是某种图形表示和三地址码的组合。语法树是一种图形表示,它的一个节点代表源程序中的一个结构,而该节点的子节点则代表子结构。三地址码的名字来源于其形式x = y op z,每一条指令中最多有一个操作符。当然,还有一些用于控制流的指令。
2、表达式翻译:含有多个操作符的表达式会被翻译为一系列完成单个操作的指令。翻译的方法是语法制导的翻译模式。在生成式E -> E1 op E2中添加动作。这些动作可以为E创建一个节点,并以E1和E2的节点作为其字节点,也可以直接生成三地址指令。这时需要编译器生成一些临时的名字。一般来讲,每一个子表达式都有一个唯一的名字(Value Number)。
3、类型检查:表达式E1 op E2的类型由op的类型以及E1、E2的类型确定。强制是隐式的类型转换,例如将int转换为float。中间表示中要显式的表示这些类型转换。
4、使用符号表实现声明:声明指定了一个名字的类型。类型的宽度表示一个类型需要的存储空间。当有了宽度信息,每一个名字相对于存储块的相对地址就可以被计算出来。这些信息被存放在符号表中。
5、数组:为了高效访问,数组的元素存储在连续的区域中。多维数组被平坦化了,使得它们像一维数组一样访问。数组的类型用于计算数组元素的地址。
6、为布尔表达式生成跳转码:在短路计算中,布尔表达式的值是隐含地表示在跳转中的。在布尔表达式用于控制流时,这种代码很有用。用于赋值操作时,布尔表达式的值也可以通过跳转到t=true或t=false来计算。
7、补丁:补丁是一个一遍分析的技术。其想法是,将不完整的jump维护在若干个list中,当跳转的目的可以确定的时候,在把这些jump补充完整。
8、结构体内部定义了一个新的独立的作用域。函数则定义了一个嵌套的作用域。
阅读(1574) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~