符号表之二:组织和运营策略

1.符号表的几种组织形式

前面的文章 《符号表之一:符号属性》也可以看到不同符号之间的语义属性数目和内容是存在差异的,那么如果运营符号表呢?显然有两个很明显的思路:

1. 分而治之:创造多个符号表,每个符号表内的符号是属性完全相同的;(组织方法分散,虽然单个表内的运营较为简单,但是子表过多,增加了很多工作量


图1. 分而治之:分散子表

2. 集权管理:牺牲空间,添加冗余,将所有符号放在一个表内。(管理倒是集中了,但是不同符号间存在很大差异,为了囊括所有符号的所有属性,必然是需要添加冗余的,这种方法导致符号表过于臃肿,甚至可能导致符号表是稀疏的


图2. 集权管理:统一大表

3. 近者合并,诸侯鼎力:所以简单的思路是两个方案折中,放宽“同类符号”的标准,比如属性虽然不完全相同,但是差异不大的,也可以放在同一个表内,这样便可以降低子表数目的同时,减少单个表的臃肿程度


图3. 诸侯鼎力:近似者合并

从上述讨论可看到,为便于符号表的组织管理,每一张符号表的表长通常为定长的。即每张符号表可看成是一个多元组,每个元组由若干个成员(属性)组成,元组之间有相同的成员个数和一致的排列。元组之间的区分必须是表项中唯一标识该项的栏,这在符号表中就是”符号”这一栏,也就是表的”关键字栏”。对于变量、函数及过程来说,它们的”标识符”就是作为它们记录在表中的关键字(即”符号”),这也是为什么编译器会对变量名或函数名进行再次修饰的原因。

2.符号表的运营策略

既然上面已经提到了采用第三种方案“近者合并,诸侯鼎力”的策略后,那么表项填入的方式可以有几种呢?

1. 线性组织(数组类型):按照符号被扫描到的顺序填入符号表,这种线性表管理简单但是比较难过的是,这种数组需要预先划分空间,即表项存在上限,所以对于符号个数不确定的情况,不能采用线性表。不过对于事先能够确定符号个数或符号个数不多(公认小于20)时采用线性组织是非常好的。

2.排序组织(链表类型):线性组织最大优点是【填入】时很简单,但不足的是符号表后期的索引较为低效,基本只能靠遍历。前面说道符号表的组织形式直接决定了后期语义处理等阶段的效率。所以很自然的便是提出排序组织,按照符号名升序排列,这样子可以使用二分查找来加速后期的搜索速度。

3. 哈希映射(哈希):如果想把后期的搜索速度提升到极致,那么显然散列哈希是一个极端的做法,通过完全牺牲空间来换取时间。考虑到现今内存空间的增加,为了提高编译速度,目前绝大多数的编译程序都是采用散列哈希做法来进行表现组织。

3.符号表的外延扩展

前面提到了符号表为了管理方便,所以表项的表长是固定的,但是如果符号的某个属性的属性值范围较大,比如 string_name最小1字符最大32字符,那么如果依据了表长固定的原则,那显然只能采用最大字符上限作为该域的size设置,但一旦这样,必然会导致该项存在较大的冗余,空间浪费严重。那么解决方案也很明显:从传值变成传地址(指针)就可以了。

学术点的说法:”由于程序中的标识符长短不一,有时可能差别很大,用等长结构会产生溢出或冗余。希望既保证关键字段的等长,又要减少甚至消除冗余,可采用关键字池的索引结构,即添加一层【地址指针项】。(Linux函数调用临时栈上的形参输入方式也是这样)“


图4. 符号名域借助”地址指针“的组分扩展

除了符号名域这种借助”地址指针“的组分扩展,还有一种类似前面介绍过的”拉链“方式的一种符号间关系组织,比如说要标识函数标识符和归属于它的形参之间的隶属关系,则可以通过链表链接的方式来进行关系组织,末尾标”空“来代表检索到头。比如以func1 (para1, para2, para3)func2 ()为例介绍组分链接关系。


图5. 链表式组织符号间关联关系

而对于这种存在扩展组分的情况,除了这种拉链式的解决方案,还有一种更通用的方案,这便是建立外延扩展数据结构来全局性的指出关联关系。这种方式虽然清晰,但是显然管理和运营成本也是很高的,很厚重!


图6. 外延设置扩展数据结构说明符号间关联关系

总结来看,可以看到随着现今硬件设施的性能提升,对于空间效率的重视已经越来越弱,而牺牲空间来获取尽可能呢大的时间效率提升是诸多程序的设计诉求,这也进一步地提出了对小到数据结构大到整体架构的更严格的要求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值