符号表

  编译程序时放在符号表里的不光是内存地址函数/变量的对应关系,还有很多在编译时要用到的信息。比如该节点的各种属性(类型,作用域,分配空间大小,(函数)的参数类型)等等。

符号表与编译的各个阶段都有交互。对符号表的具体使用方法每个编译器都不同。         目标文件中的符号表用来输出函数/变量符号信息,供连接时给其他模块引用。这种符号表中主要包含

函数/变量的名称和地址对应关系,其中的地址一般是位置无关码(PIC码)。  ( 节点是指分析树上的某个节点。看看编译的书你即可明白。:)        

  位置无关码是指代码中出现的内存地址和具体运行环境无关(相对地址),这样的代码可被loader载入内存中的任意某个位置运行。从而增加了程序的灵活性。动态连接库中的代码全是

位置无关码,因为动态连接库也需要这种能力。

 

 

   在编译程序中符号表用来存放语言程序中出现的有关标识符的属性信息,这些信息集中反映了标识符的语义特征属性。在词法分析及语法在分析过程中不断积累和更新表中的信息,

并在词法分析到代码生成的各阶段,按各自的需要从表中获取不同的属性信息。不论编译策略是否分趟,符号表的作用和地位是完全一致的。   

  ① 收集符号属性

    收集符号属性 编译程序扫描说明部分收集有关标识符的属性,并在符号表中建立符号的相应属性信息。

    例如,编译程序分析到下述两个说明语句   int A;   float B[5];   

       则在符号表中收集到关于符号A的属性是一个整型变量,关于符号B的属性是具有5个浮点型元素的一维数组。

  ② 上下文语义的合法性检查的依据   

      上下文语义的合法性检查的依据 同一个标识符可能在程序的不同地方出现,而有关该符号的属性是在这些不同情况下收集的。

特别是在多趟编译及程序分段编译(在PASCAL及C中以文件为单位)的情况下,更需检查标识符属性在上下文中的一致性和合法性。通过符号表中属性记录可进行相应上下文的语义检查。   

例如,在一个C语言程序中出现   

    …   

    int i [3,5]; //定义整型数组i   

    …   

    float i[4,2]; //定义实型数组i,重定义冲突   

    …   

    int i [3,5]; //定义整型数组i,重定义冲突   

    …   

    编译过程首先在符号表中记录了标识符i的属性是3×5个整型元素的数组,而后在分析第二、第三这两个定义说明时编译系统可通过符号表检查出标识符i的二次重定义冲突错误。

本例还可以看到不论在后二句中i的其它属性与前一句是否完全相同,只要标识符名重定义,就将产生重定义冲突的语义错误。

  ③ 作为目标代码生成阶段地址分配的依据    

    作为目标代码生成阶段地址分配的依据 每个符号变量在目标代码生成时需要确定其在存储分配的位置(主要是相对位置)。

语言程序中的符号变量由它被定义的存储类别(如在C、FORTRAN语言中)或被定义的位置(如分程序结构的位置)来确定。

  首先要确定其被分配的区域。例如,在C语言中首先要确定该符号变量是分配在公共区(extern)、文件静态区(extern static)、

函数静态区(函数中static)、还是函数运行时的动态区(auto)等。

  其次是根据变量出现的次序,(一般来说)决定该变量在某个区中所处的具体位置,这通常使用在该区域中相对区头的相对位置确定。

而有关区域的标志及相对位置都是作为该变量的语义信息被收集在该变量的符号表属性中

posted @ 2013-07-18 21:54  z折腾  阅读(3764)  评论(0编辑  收藏  举报