编译原理--静态语义分析和中间代码生成
符号表和类型表
符号表
如图上所示是符号表要写的内容
一般常考的是类型标识符和变量标识符的写法
- 其中类型标识符很好识别,就是前面写了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 __
这样的形式比较容易
本文作者:次林梦叶的小屋
本文链接:https://www.cnblogs.com/cilinmengye/p/17944261
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2023-01-03 STL----vector