变量名和符号表

来源:互联网 发布:gnn网络 编辑:程序博客网 时间:2024/04/19 21:38
(一)变量名
变量名是给编译器看的,编译器根据变量是局部还是全局分配内存地址或栈空间,所谓的变量名在内存中不存在,操作时转换成地址数存放在寄存器中了。其实可以理解为是符号表起到了连接作用。

(二)符号表

 在编译程序中,符号表是用来存放源程序中出现的有关名字的属性信息,这些信息集中反映了名字的语义特征属性。符号表在编译全过程的地位和作用非常重要,是进行上下文合法性检查和语义处理及代码生成的依据。符号表总体结构的设计和实现是与源语言的复杂性(包括词法结构、语法结构的复杂性)有关,还与对于编译系统在时间效率和空间效率方面的要求有关。为此在本章中应对以下几个重点、难点问题作认真的学习,并切实掌握其中的内容。

一、掌握符号的类型、存储类别和作用域及可视性的概念

(1)符号的类型

    标识符中除过程标识符之外,函数和变量标识符都具有数据类型属性。对于函数的数据类型指的是该函数值的数据类型。基本数据类型有整型、实型、字符型、逻辑型(布尔型)及位组型等,符号的类型属性是在语言程序中该符号的定义中得到。变量符号的类型属性决定了该变量的数据在存储空间的存储格式,还决定了在该变量上可以施加的运算操作。

(2)符号的存储类别

    多数语言对变量的存储类别定义采用二种方式。
    一种是用关键字指定。例如在C语言中,用Static定义是属于文件的静态存储变量或属于函数内部的静态存储变量,用regist定义使用寄存器存储的变量。
    另一种方式是根据定义变量说明在程序中的位置来决定。例如在C语言中,在函数体外缺省存储类关键字所定义的变量是外部变量,即程序的公共存储变量,而在函数体内缺省存储类关键字所定义的变量是内部变量,即属于该函数所独有的私有存储变量(通常是动态分配的存储变量,详细情况参阅存储空间的组织管理)。
    符号表中设置一个符号存储类别域,存放该符号的存储类别。区别符号存储类型的属性是编译过程语义处理、检查和存储分配的重要依据。符号的存储类别还决定了符号变量的作用域、可视性和它的生命周期等问题。

(3)符号的作用域及可视性

    一个符号变量在程序中起作用的范围,称谓它的作用域。一般来说,定义该符号的位置及存储类关键字决定了该符号的作用域。例如,C语言中一个外部变量的作用域是整个程序,因此一个外部变量符号的定义在整个程序中只能出现一次,同名变量的说明可以出现多次那是为了使用和编译的方便。
    为确立符号的作用域和可视性。符号表属性中除了需要符号的存储类别之外还需要表示该符号在程序结构上被定义的层次。符号表中设置一个表达符号所在层次的属性域,存放该符号的定义层次。无论是作为函数形参的定义也好或作为分程序中的局部定义也好,都可统一地用定义层次来区分。一般来说,若把外部变量视为0层的话,则函数内部作为第1层,依次向内嵌套定义的分程序分别为2,3,…层。在C语言程序中函数之间是并列定义的,因此每个函数内部都定义为第一层,而函数内的分程序也可以是并列定义的,对于并列定义的分程序当然具有相同的层次号。

二、掌握符号表总体组织的选择原则

    第一种:把属性种类完全相同的那些符号组织在一起,构造出表项是分别为等长的多个符号表。
    这样组织的最大优点是每个符号表的属性个数和结构完全相同。则表项是等长的,并且表项中的每个属性栏都是有效的,对于单个符号表示来说,这样使得管理方便一致,空间效率高。但这样组织的主要缺点是一个编译程序将同时管理若干个符号表,增加了总体管理的工作量和复杂度。而且对各类符号共同属性的管理必须设置重复的运行机制。使得符号表的管理显得臃肿。
    第二种:把所有语言中的符号都组织在一张符号表中。组成一张包括了所有属性的庞大的符号表。
    这样组织方式的最大优点是总体管理非常集中单一,且不同种类符号的共同属性可一致地管理和处理。这样组织所带来的缺点是,由于属性的不同,为完整表达各类符号的全部属性必将出现不等长的表项,以及表项中属性位置的交错重叠的复杂情况,这就极大地增加了符号表管理的复杂度。为使表项等长且实现属性位置的唯一性,可以把所有符号的可能属性作为符号表项属性。这种组织方法可能有助于降低符号表管理复杂性,但对某个具体符号,可能增加了无用的属性空间,从而增加了空间开销。
    第三种:折衷方式是根据符号属性相似程度分类组织成若干张表,每张表中记录的符号都有比较多的相同属性。这种折衷的组织方式在管理复杂性及时空效率方面都取得折衷的效果,并且对复杂性和效率的取舍可由设计者根据自己的经验和要求及目标系统的客观环境和需求进行选择和调整。

三、掌握分程序结构的符号表组织

    对于具有分程序型结构的语言程序,不同层次分程序中定义的标识符号具有不同的作用域和不同的可视性规则。通常对于具有分程序结构的语言可用两种方式组织它们的符号表:一是对每个分程序建立一个独立的分表结构的符号表;一是把各分程序符号组织在一张单表结构的符号表中。例如,图9.1给出一个分程序结构的程序示例。 

{//第一层分程序
 int a;
     float b,d;
             {  //第二层分程序
      int c;
        float a;
                { //第三层分程序
          int d;
            float c;
                    { //第四层分程序
                float d;
              
                a=b+c+d;
              
      }
 }
}
}

图9.1  分程序结构的程序示例

(1)分表结构
    分表结构的组织管理,其基本思想是每当编译程序扫描到一个分程序结构开始时,为该分程序建立一张符号表,在该分程序中定义的标识符,都被登录在该符号表中。而当编译程序扫描到一个分程序的结束时,编译程序释放为该分程序所建立的符号表。图9.2给出了与上述分程序结构的程序示例相应的分表结构组织。
    根据分程序作用域和可视规则,编译程序扫描到某个分程序时,符号的登录是在为该分程序所建立的符号表中进行,而符号的查找是首先在该分程序符号表中进行;若没有查到,再根据分程序的层次结构,逐层向外地依次查找各层符号表。一直到查到为止。若所有符号表都已查完仍未找到,则表示有词法错误。

图9.2

(2)单表结构

    单表结构的组织管理,其基本思想是所有分程序中定义的标识符都集中在单张符号表中。为了实现分程序构造中标识符的作用域和可视性规则的要求。在这种单表组织的符号表中,由于分层的分程序结构,因此需要强调三个主要的特定要求。
    首先,为了标志一个符号所属的分程序层次,在符号表中可设立一个属性域用来登录符号所在分程序的层次。
    其次,在编译程序扫描进入一个分程序时,表示分程序层次的状态量要增加一层,使进入分程序后定义的标识符登录符号表时,有相应的层次量作为层次属性登录。
    最后,对于具有分程序结构的源程序,在不同的分程序中(指嵌套的分程序中)允许定义重名的标识符。如果有重名标识符,可用下推链来组织。图9.3给出了与上述分程序结构的程序示例相应的单表结构组织。

图9.3

0 0
原创粉丝点击