刘坚 编译原理基础 学习笔记(4)中间代码+符号表

中间代码

(1)后缀式(逆波兰表示)
        典型特征是操作数在前,操作符紧跟其后。例如:a+b*c -> abc*+

(2)三地址码
        result:=arg1 op arg2 / result:=op arg1或op arg2。
        形式上是最多仅由一个二元运算组成的赋值句。
        例如x:=a+b*c可以是
                T1:=b*c
                T2:=a+T1
                x:=T2

        它的实现为三元式或四元式。
                三元式:(op,arg1,arg2),表示:=arg1 op arg2
                四元式:(op,arg1,arg2,result),表示result:=arg1 op arg2,这为优化代码提供了方便。

(3)树的优化表示:DAG
        它可以识别表达式中的公共子表达式。构造时,查询要构造的节点是否已存在。若存在,则返回该节点指针即可,若不存在才构造。
        以a+a*(b-c)+d*(b-c)为例,它的DAG是这样的


符号表

        符号表是连接声明与引用的桥梁。在声明时,一个名字的相关信息被写入符号表。
        1. 符号表的条目
                每个声明的名字在符号表中占据一栏,之后是属性。
                构成名字的字符串有两种储存方式:a.直接储存 b.间接储存。
                间接储存的方式可以延伸。对于一个复杂的属性,可以另外开辟空间,然后把指向该空间的指针放在此属性在符号表中的对应位置即可。
        2. 名字的作用域
                a.静态作用域原则。即仅从静态读程序就可以确定作用域
                b.最近嵌套原则。名字的声明在离其最近的内层起作用

实现符号表的数据结构
        1. 线性表
                为了正确反映名字的作用域,线性表应有栈的性质。当从某个作用域退出时,从栈顶把该作用域中的所有名字踢掉,放在临时表里。进入某作用域时,把需要的名字加入。只有确认某名字永远不会被使用时才会把这个名字真正删除。

        2. 散列表
                在正常散列表的结构上,增加了一个作用域链
                        hash link:连接所有具有相间hash 值的元素,表头在表头数组中。
                        scope link:链接所有在同一作用城中的元素,表头在作用域链中。
                在散列表里可以进行如下操作:
                        (I)查找。首先计算做散列函数,然后从散列函数所指示的入口进入某个线性表,在线性表中沿hash link,像查找单链表中的名字一样进行查找。
                        (2)插入。首先查找,以确定要插入的名字是否已在表中,若不在,则要将其分别沿hashlink和scope link 插入到两个链中,方法都是插在表头,即两个表均可看做是栈。
                        (3)删除。把以作用域链接在一起的所有元素从当前符号表中删除,保留作用域链所链的子表,为后继工作使用(如果是临时删除,则下次使用时将该元素直接沿作用域链加入到.散列链中即可)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值