编译原理--静态语义分析和中间代码生成

符号表和类型表
符号表

如图上所示是符号表要写的内容
一般常考的是类型标识符和变量标识符的写法
- 其中类型标识符很好识别,就是前面写了typedef的声明类型,如:



这些都是类型标识符
对于类型标识符,我们只要在符号表中记录 类型标识符名称|(自己命名这个类型的名称)|typeKind 即可
一般来说 我我们自己命名这个类型的名称时,一般将数组命名为Ap,将结构struct命名为Rp,然后下面我们要为这个类型标识符进行进一步的说明(这个就是类型表的工作了,下面会讲)
-
对于变量标识符:
-
我们一般要在符号表中写这个变量的类型
如果是基本类型,如 int写intPtr,float和double写realPtr,char写charPtr
如果是上面定义的类型标识符,就写我们自己命名的类型的名称;或者是一些复杂数据结构(如数组),那需要自己再命名 -
我们还要在后面写varKind, 表示这是一个变量标识符
-
同时还要写上dir/indir,表示这是否是可以直接得到的,一般都是dir
-
同时写上这个变量所处于的作用域层
-
后面再写上这个变量的偏移地址
-
举例

可以看到有两个类型标识符,我们将其分别命名为Ap和Rp(因为其分别为数组和struct).
然后c就是基本类型了,为intPtr
d是类型是定义的类型标识符,于是我们用我们命名的Rp
类型表
回顾上面我们定义的类型标识符名称,因为一般类型标识符有更多含义,是复杂数据结构,类型表的作用就是解释他:

一般我们用的是数组array和记录record(结构struct)
数组后面的ElemType是这个数组的类型定义,如int arr[20],那么这里就是intPtr
记录record 的recordTy是固定的,然后用指针指出结构体中的内容
举例
-
例一:

我们可以看到结构图rtp最后没有指针了可以以^结尾
在数组fptr中其每一个元素类型都是rtp -
例二:


需要注意的是如果在结构体里面都有类型标识符或复杂数据类型,需要自己再命名,同时写在类型表中做出解释。
同时需要注意这题的偏移量的计算
关于数组十分要注意的地方:

这里是15,而不是3
还有:

这里是200,而不是100
三地址代码中间表示

逆波兰式比较简单,而且数据结构学过我们就不多讲了
三地址代码形式一般如下:

三地址代码有3种表示方式: 三元式,间接三元式,四元式
一般如果要求要将一条代码语句转换成这几个表示方式,我们一般都是先将这条代码语句转换成三地址代码,然后再进行转换成上述的3种表示方式
三元式


间接三元式

三元式码表中是不存在重复的操作的,然后通过间接码表来说明执行的方式
四元表



注意下一元运算符的写法,而且取负还可以这么写
将代码语句转换为三地址代码


需要注意的上,红框中的goto看似是多余的,其实是固定写法

需要注意前面记得加上标号,从1开始即可
将代码语句转换为四元式

这里的j< 为 如果< 就跳转,是带条件的跳转操作
j是不带条件的跳转操作
再如:

那么首先关键是写出这个代码语句的三地址代码
个人认为是这么写的:

while 语句可以转换为if语句和goto 相互配合实现
if 语句 在写的时候写成:
if xxx goto __
goto __
这样的形式比较容易

浙公网安备 33010602011771号