前面介绍了表项管理和组织,也介绍了对于一些畸形数据结构的符号表如何管理组织的方案,那么现在遇到了一种最为常见的问题:对于程序的不同层次段中,同名变量的可见性是如何通过符号表来严格约束并实现的?
对于具有分程序型结构的语言程序,不同层次分程序中定义的标识符号具有不同的作用域和不同的可视性规则。通常对于具有分程序结构的语言可用两种方式组织它们的符号表:一是对每个分程序建立一个独立的分表结构的符号表;一是把各分程序符号组织在一张单表结构的符号表中(但对于同名变量每时刻只有一个可用条目存储在有效表项中,其他表项等在外围,即所谓下推链)。
分表结构的组织管理,其基本思想是,每当编译程序扫描到一个分程序结构开始时,为该分程序建立一张符号表,在该分程序中定义的标识符,都被登录在该符号表中。而当编译程序扫描到一个分程序的结束时,编译程序释放为该分程序所建立的符号表。这种符号表的分表结构与源程序的分程序层次结构是完全一致的,这种层次结构是编译过程中动态建立和动态消亡的。根据分程序作用域和可视规则。编译程序扫描到某个分程序时,符号的登录是在为该分程序所建立的符号表中进行,而符号的查找是首先在该分程序符号表中进行;若没有查到,再根据分程序的层次结构,逐层向外地依次查找各层符号表。一直到查到为止。若所有符号表都已查完仍未找到,则表示有词法错误。
图1. 可见性解决方案之一:分表结构
单表结构的组织管理其基本思想是,所有分程序中定义的标识符都集中在单张符号表中。为了实现分程序构造中标识符的作用域和可视性规则的要求。在这种单表组织的符号表中,由于分层的分程序结构,因此需要强调三个主要的特定要求。
1. 程序层次域:首先,为了标志一个符号所属的分程序层次,在符号表中可设立一个属性域用来登录符号所在分程序的层次。(通常编译系统在扫描分程序结构的源程序时,设立一个记录当前扫描位置的分程序层次的状态量。每当一个标识符被定义并被登录符号表时,当时的表达分程序层次的状态量作为该标识符的分程序层次被登录到该符号的层次属性域中。)
2. 该层程序体登录登出的变量清理:在编译程序扫描进入一个分程序时,表示分程序层次的状态量要增加一层,使进入分程序后定义的标识符登录符号表时,有相应的层次量作为层次属性登录。与进入分程序相比,在退出一个分程序时,这种单表结构的管理要复杂得多。退出一个分程序时,不但要把表示分程序层次的状态量降低一层,而且需要把符号表中,所有在退出的分程序中登录的符号项清除。这种要求对排序组织或散列组织的符号表来说是一个十分繁琐的工作。
上面便是最简单的下推链演示过程,每个时刻只有符号表内的符号信息才是有效的,处在符号表的外部等待符号是无效的。
总结而言:采用单表结构时,下推链域的构造用来处理解决分程序构造中同名标识符声明的可视性规则,采用分表结构不存在下推问题。分表结构很适合基于对象的语言的编译系统。