符号表原理介绍(详细)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

§6.1 符号表的作用和地位
二、上下文语义的合法性检查的依据 上下文语义的合法性检查的依据 语义的合法性检查
同一个标识符可能在程序的不同地方出现,而有关该符号的属 性是在不同情况下收集的。通过符号表中属性记录可进行相应 上下文的语义检查。 例如: 例如 int i [3][5]; float i[4][2]; int i [3][5]; 1. 2. 首先在符号表中记录i的属性是3×5个整型元素的数组 在分析第二、第三个说明时,通过符号表检查出标识符i的二次 二次 重定义冲突错误 重定义
§6.2 符号的主要属性及作用
(2) 动态存储区 根据变量的局部定义和分程序结构,编译程序设置动态存储区来 适应这些局部变量 局部变量的生存和消亡。局部动态变量 局部动态变量的生存期是定义 局部变量 局部动态变量 该变量的局部范围,即在该定义范围之外此变量已经没存在的必 要。及时撤销时这些单元的分配可以回收,从而提高程序运行时 的空间效率。 对变量存储分配的属性除了存储类别之外还要确定其在所在存储 区的具体位置的属性信息。通常在符号表中存放具体位置的信息 是按该变量的存储区类分别依出现先后的次序(扫描源程序的次 序)排列下相对该存储区表头的相对位移量来表示的。
§6.2 符号的主要属性及作用
(2) 分程序(或复合语句)结构 // 第一层头,定义的局部整型变量a {int a; ; … // 第二层头,定义的局部字符型变量a {char a; ; … // 第三层头 { … {float a; // 第四层头,定义的局部实型变量a ; … // 第四层尾 } …a… // 引用第二层定义的局部字符型变量a // 第三层尾 } // 第二层尾 } // 第一层尾 }
§6.2 符号的主要属性及作用
外部变量)被指定分配到该公共静态存储区 公共静态存储区中。 公共变量(外部变量 公共变量 外部变量 公共静态存储区 C/C++中的外部变量就属于这类共静态存储区的分配。在公共静 态区中的变量具有的生命周期是该程序运行的全过程,且其作用 域亦是整个语言程序。 编译程序为局部静态量 局部静态量可设立若干个局部静态区 局部静态区。 局部静态量 局部静态区 对外部静态量 外部静态量,为每个程序文件建立一个局部静态区,对内部静 外部静态量 内部静 态量,则为每个具有内部静态量定义 具有内部静态量定义的函数或过程,建立一个局 态量 具有内部静态量定义 局 部静态区。 部静态区 被Static所定义的符号变量具有的生命周期也是该程序运行的全 过程。但被Static定义的变量若在函数之外则为所在之文件中所 有函数可视。而若变量在函数内被定义为Static,则它仅为所在 函数可视。分别分配不同的静态变量,这仅是编译处理上的问题, 与语言无关。
§6.1 符号表的作用和地位
一、收集符号属性
编译程序扫描说明部分 说明部分,收集有关标识符的属性 标识符的属性,并 说明部分 标识符的属性 属性信息。 在符号表中建立符号的相应属性信息 属性信息 例如: 例如 编译程序分析到下述两个说明语句 int A; float B[5]; 则在符号表中收集到关于符号A的属性是一个整型 整型变 整型 量,关于符号B的属性是具有5个浮点型元素的一维数 组。
§6.1 符号表的作用和地位
三、目标代码生成阶段地址分配的依据 目标代码生成阶段地址分配的依据 地址分配
符号变量由被定义的存储类别 被定义的位置 被定义的存储类别或被定义的位置 被定义的存储类别 被定义的位置决定。 符号变量在目标代码生成时需确定存储分配的位置。 首先, 首先,要确定其被分配的区域。例如,在C/C++语言中首先要确 定该符号变量是分配在公共区(extern)、文件静态区(extern static)、函数静态区(函数中static)、还是函数运行时的动态 区(auto)等。 其次, 其次,根据变量出现的次序。一般来说,决定该变量在某个区中 相对区头的相对位置 所处的具体位置,这通常使用在该区域中相对区头 相对位置 相对区头 相对位置确 定。 区域的标志及相对位置 相对位置都是作为该变量的语义信息被收集在该变 区域的标志 相对位置 量的符号表属性中。
对于外部量a,b,c依次相对公共静态区头 公共静态区头的相对位置分别是0, 公共静态区头 4,8。 说明: 说明: 1) 2) 3) 4) 虽然a是整形量,只需要2个字节,但因为b是实形量,它本身 需要4个字节,而且b的地址也必须是4的倍数 的倍数的字节号。 的倍数 c是一个结构变量,其中占最大字节数的结构分量是e,需要4 个字节,因此c必须是依4的倍数 的倍数的字节号作为它的地址。 的倍数 d和e是cc的结构分量,其位置属性由结构c来决定,因此d,e的 相对位移量分别是0,4。 对于局部量来说,上面的原则是相同的,所不同的仅是相对不 不 同的区头。 同的区头
§6.2 符号的主要属性及作用
五、符号变量的存储分配信息
根据符号变量的存储类别 存储类别定义及出现的位置 次序,确定每一个 位置和次序 存储类别 位置 次序, 变量应分配的存储区 存储区及在该区中的具体位置 具体位置,用相对区头的位移 位移 存储区 具体位置 量表示。 通常一个编译程序有两类存储区: ⑴ 静态存储区 该存储区单元经定义分配后成为静态单元 静态单元,在整个运行过程中是 静态单元 不可改变的。 作静态分配的变量具有整个程序运行过程的生命周期。因此编译 程序可以设置一个固定的空间 设置一个固定的空间作为静态存储区。但由于不同的静 设置一个固定的空间 不同的静 态变量具有不同的可视性,编译程序也可以设置几个不同的固定 态变量具有不同的可视性 空间作为静态区。 根据变量存储类别及作用域规则,这类静态存储区通常又可分为 公共静态区和若干个局部静态区 局部静态区。 公共静态区 局部静态区

5.
§6.2 符号的主要属性及作用
二、符号的类型
标识符都具有数据类型。 符号的类型属性 类型属性是在符号的定义中得到的。变量符号的类型属性 类型属性 决定了该变量的数据在存储空间的存储格式 存储格式,还决定了 决定了在该变量 决定了 存储格式 决定了 上可以施加的运算操作 运算操作。 运算操作 符号表设置一个符号类型 符号类型域,存放该符号的类型。对复合数据类 符号类型 型,通常还需要设置该类型的扩展成分 扩展成分,以存放复合类型的完整 扩展成分 存放复合类型的完整 的类型属性。 的类型属性
§6.2 符号的主要属性及作用
例: int a; float b; struct cc{ int d; float e; // 外部定义的整型变量a // 外部定义的实型变量b // 外部定义的结构类型cc, cc的第一个结构分量d // cc的第二个结构分量t … // 外部定义的结构型变量c
3)
§6.2 符号的主要属性及作用
2. 可视性
已知,作用域就是在一定围内该变量是可引用的,这就是变量可 可 视性的作用域规则。可视性不仅仅取决于它的作用域,还有两种 视性 情况影响到一个变量的可视性。 ⑴ 函数的形式参数 int a; // 外部定义的变量a ; int func(a,b) // 内部定义的局部变量a, 屏闭了外部的a float a; ; int b; ; { …a… // 引用的是内部的变量 内部的变量a 内部的变量 }
}c; … 其中a,b,c是三个外部量,d,e是结构分量,则在符号表中, 这5个变量项有关存储位置的属性信息将如图。这儿cc是一个结 构标记,作为标识符它要登入到符号表中,但它只是一个类型 标识符,因此没有地址分配的问题。
§6.2 符号的主要属性及作用
符号表中变量分配相对位置属性的表示
§6.2 符号的主要属性及作用
§6.2 符号的主要属性及作用
三、符号的存储类别
1) 2) 大多数语言对变量的存储类别定义采用二种方式: 用 关 键 字 指 定 。 如 C/C++ 中 用 Static定 义 静 态 存 储 变 量 , 用 regist定义寄存器存储变量。 根据定义变量说明在程序中的位置 位置来决定。如C/C++语言中, 位置 在函数体外 函数体外缺省存储类关键字所定义的变量是外部变量,即程 函数体外 序的公共存储变量,而在函数体内 函数体内缺省存储类关键字所定义的 函数体内 变量是内部变量。 符号表设置一个符号存储类别 符号存储类别域,存放该符号的存储类别。区 符号存储类别 别符号存储类型的属性是编译过程语义处理、检查和存储分配 的重要依据。符号的存储类别还决定了符号变量的作用域 可 作用域、可 作用域 视性和它的生命周期 生命周期等问题。 视性 生命周期
§6.2 符号的主要属性及作用
四、符号的作用域及可视性
1. 作用域 在程序中起作用的范围。定义该符号的位置及存储类别关键字 决定了该符号的作用域。 例如: 例如: C/C++语言中 1) 2) 外部变量的作用域是整个程序 整个程序,因此一个外部变量符号的定义 整个程序 在整个程序中只能出现一次。 在函数外说明的静态变量的作用域是定义该静态 静态变量的文件 文件, 静态 文件 而在函数内部定义的静态变量,其作用域仅仅是该变量定义所 在的函数 函数。 函数 与局部量不同的是,这些内部静态量在其作用域之外,仍然保 持存在。
§6.2 符号的主要属性及作用
函数形式参数可以和外层定义的变量重名,但类型定义可以完全 不同。该函数同时是这两个变量的作用域。 为了在函数中不但能看到float a,而且也能看到int a,在C/C++的 中增加了一个语法记号∷,使得int a也可见。 ∷ 上例可改写如下: 上例可改写如下: int a; int func (a, b) float a; int b; { … … a… //引用float a …∷a… //引用int a ∷ }
§6.2 符号的主要属性及作用
语言符号分为: 语言符号分为:
• • • 关键字(保留字) 操作符 标识符
它们之间的主要属性有较大差别,通常建立不同的符号表。 有些编译程序也将关键字符号与标识符符号建立在同一符号表中。 不同的语言定义的标识符属性不尽相同。
§6.2 符号的主要属性及作用
一、符号名
标识符可以是一个变量的名字或一个函数的名字。 1. 2. 3. 标识符通常由若干个字符组成的字符串来表达。 符号表设置一个符号名域 符号名域存放标识符,通常是符号表的关键字 符号名域 关键字 域。 标识符是变量、函数的唯一标志 唯一标志,一般不允许重名。符号名与 唯一标志 在符号表中的位置一一对应,用符号在表中的位置来替换符号 名,即内部代码。 重名标识符按照该标识符在程序中的作用域 可视性 作用域和可视性 重名标识符 作用域 可视性规则进行 相应的处理。而在符号表运行过程中 在符号表运行过程中,表中的标识符名始终是 在符号表运行过程中 唯一的标志。 唯一 在一些允许操作重载的语言中,函数名、过程名是可以重名的, 通过参数个数 类型 参数个数和类型 函数返回值类型来区别,以达到它们 参数个数 类型以及函数返回值类型 函数返回值类型 在符号表中的唯一性。
§6.2 符号的主要属性及作用
为确立符号的作用域和可视性,符号表属性中除了需要符号的存 储类别之外,还需要表示该符号在程序结构上被定义的层次。 符号表中设置一个表达符号所在层次的属性域 所在层次的属性域,存放该符号的定 所在层次的属性域 义层次。 无论是作为函数形参的定义也好,或作为分程序中的局部定义也 好,都可统一地用定义层次 定义层次来区分。 定义层次 一般来说,若把外部变量视为0层的话,则函数内部作为第1层, 依次向内嵌套定义的分程序分别为2,3,…层。 在C/C++程序中,函数之间是并列定义的,因此每个函数内部都 定义为第一层,而函数内的分程序也可以是并列定义的,对于并 列定义的分程序当然具有相同的层次号。
编译程序分析到下述两个说明语句int则在符号表中收集到关于符号a的属性是一个整型变量关于符号b的属性是具有5个浮点型元素的一维数61二上下文语义的合法性检查的依据同一个标识符可能在程序的不同地方出现而有关该符号的属性是在不同情况下收集的
编译原理
第六章 符号表
§6.1 符号表的作用和地位
在编译程序中符号表用来存放语言程序中出现的有关 标识符的属性信息 属性信息,这些信息集中反映了标识符的语 属性信息 语 义特征属性。 在词法分析 语法分析 词法分析及语法分析 词法分析 语法分析过程中,不断积累和更新表中 的信息。 在词法分析到代码生成的各阶段 各阶段,按各自的需要从表 各阶段 中获取不同的属性信息。
相关文档
最新文档