符号表的内容与作用域分析
c语言符号表的用法
在C语言中,符号表(Symbol Table)是一种用于存储程序中变量、函数和其他符号信息的表格。
符号表在编译器和链接器的工作中起着重要的作用。
编译器在编译过程中会创建符号表,以记录程序中定义和引用的符号信息。
符号表中的每个条目都包含符号的名称、类型、作用域等信息。
链接器在链接过程中会使用符号表,以解析符号引用并确定符号的地址。
链接器会查找符号表,找到符号的地址,并将其替换为相应的内存地址。
以下是符号表的一些常见用法:
1.变量和函数声明:在C语言中,变量和函数的声明信息会被存储在符号表中。
例如,在函数定义中,函数名、参数类型和返回类型会被存储在符
号表中。
2.符号引用解析:编译器在编译过程中会解析符号引用,并将它们与符号表中的条目关联起来。
链接器在链接过程中会解析符号引用,并查找符号
表以确定符号的地址。
3.作用域管理:符号表中的条目可以包含符号的作用域信息,以帮助编译器和链接器管理符号的作用域。
例如,局部变量和函数参数的作用域限定
在它们被声明的块内。
4.类型检查:编译器可以使用符号表中的类型信息进行类型检查。
例如,编译器可以检查变量是否被赋予正确的类型,或者函数参数是否与函数声
明中的类型匹配。
5.优化:编译器可以使用符号表中的信息进行优化。
例如,编译器可以识别重复的计算并消除它们,或者优化循环结构以提高程序的性能。
总之,符号表是C语言编译器和链接器的重要组成部分,它用于存储程序中的符号信息,并帮助编译器和链接器进行各种任务,如解析符号引用、管理作用域、进行类型检查和优化等。
符号表简介
符号表简介符号表的作用:连接声明与引用的桥梁,记住每个符号的相关信息,如作用域和绑定等,帮助编译的各个阶段正确有效地工作。
对符号表设计的基本要求:目标是合理存放信息和快速准确查找。
1.正确存储各类信息。
2.适应不同阶段的需求;3.便于有效地进行查找、插入、删除和修改等操作;4.空间可以动态扩充;4.3.1 符号表条目每个声明的名字在符号表中占据一栏,称为条目,用于存放名字的相关信息。
符号表中的内容:保留字、标识符、特殊符号(包括算符、分隔符等)等等。
不同类别的符号存放在不同的子表中,如变量名表、过程名表、保留字表等。
存放方式:关键字+属性。
例:下述符号的关键字应是,名字+类型,称为组合关键字:int x; struct x { float y, z; };为C构造的符号表中,组合关键字至少应该包括三项:名字+作用域+类型。
当一个名字x在同一作用域中允许有多于一个的声明,则对x的引用时需要根据上下文确定x到底属于哪个对象。
因此有些程序设计语言在语法上规定了不允许这样的声明,以简化编译时的处理。
4.3.2构成名字的字符串的存储定长数据与变长数据,直接存放与间接存放。
名字(直接存储)名字(间接存储)属性sort 101 proc, ...a 106 int, ...readarray 108 proc, ...118 boolean, ...draw_a_red_line_for_object_asort#a#readarray#draw_a_red_line_for_object_a #↑100间接存储的方法实际上解决了复杂信息的存储问题,将其推广到属性,则任何一个复杂的属性,均可以为其另辟空间(空间本身可以是复杂结构,如数组的内情向量等),而仅需要将指向此空间的指针放在此属性在符号表中的对应位置即可。
4.3.3 名字的作用域程序设计语言的名字可以出现在不同的范围内,并且可以具有不同的意义。
两种划分范围的方式:并列的和嵌套的。
c语言 程序符号表
在C语言中,符号表(Symbol Table)是编译器在编译过程中用来存储变量、函数、宏等符号信息的数据结构。
符号表对于编译器的语义分析和代码生成阶段非常重要,它可以帮助编译器识别和解析标识符,并进行类型检查、函数链接等操作。
在C语言的编译器中,符号表通常是一个表格或哈希表结构,其中存储了以下类型的符号信息:
1.变量符号:包括变量的名称、类型、作用域等信息。
2.函数符号:包括函数的名称、参数类型、返回类型等信息。
3.宏定义符号:包括宏的名称、宏的参数和宏的替换文本等信息。
4.其他符号:例如结构体、联合体、枚举等类型的名称和成员信息。
在编译过程中,编译器会根据源代码中的标识符,将其添加到符号表中,并记录相关的符号信息。
同时,编译器还会对符号表中的信息进行验证和更新,以确保类型安全和正确的链接。
需要注意的是,具体的符号表实现方式可能会因编译器而异,但它们的基本原理和功能是相似的。
编译原理符号表的作用
编译原理符号表的作用介绍编译原理中的符号表是一个重要的数据结构,用于存储程序中的标识符及其相关信息。
标识符可以是变量、常量、函数名等,在编译过程中需要进行词法和语义分析,符号表提供了一个地方来管理这些标识符,并为编译器的其他模块提供必要的信息。
作用符号表在编译过程中起着关键作用,它具有以下几个主要作用。
1. 标识符的声明符号表记录了程序中所有标识符的声明情况,包括标识符的类型、作用域等信息。
对于变量,符号表可以记录其数据类型和内存地址;对于函数,符号表可以记录其参数列表、返回值类型等。
编译器可以通过符号表查找标识符的声明信息,并根据需要进行语义检查和代码优化。
2. 标识符的引用和解析编译过程中,标识符可能会被多次引用,符号表用于解析标识符的引用。
编译器可以根据符号表中的信息确定标识符的类型、作用域等,从而进行语义检查和类型推导。
如果编译器在符号表中找不到对应的标识符,就会报错或警告,提示可能存在的错误。
3. 作用域管理符号表还可以用于管理标识符的作用域。
在程序中,不同的代码块可能定义了相同名称的标识符,符号表可以通过作用域信息来区分这些标识符。
当编译器遇到一个标识符时,它可以在符号表中查找该标识符的作用域,并根据作用域规则来解析标识符的含义。
4. 错误检测和提示符号表还可以用于错误检测和提示。
编译器可以通过符号表判断标识符是否已经定义或声明,以及是否满足相应的语义规则。
如果标识符在符号表中已经存在多个定义,编译器可以发现这种错误,并给出相应的错误提示信息。
符号表的组织结构为了高效地实现符号表的作用,通常采用哈希表或树形结构来组织符号表。
下面是一些常见的符号表组织结构。
1. 线性表符号表可以使用线性表结构进行组织,例如数组、链表等。
线性表结构简单直观,适用于较小规模的符号表。
但对于大规模的符号表,线性表的查找效率较低。
2. 哈希表哈希表是一种基于键值对存储的数据结构,可以快速地查找和插入数据。
符号表中的标识符可以作为哈希表的键,对应的信息可以作为值进行存储。
c语言符号表
C 语言符号表C 语言符号表是一个重要的编译器数据结构,它用于存储和管理程序中的各种符号。
符号是指程序中的变量、函数、常量、类型等具有标识作用的名称。
符号表的作用是在编译过程中,为符号分配内存地址、类型、作用域等属性,并在需要时查找和修改符号的相关信息。
本文将从以下几个方面简述 C 语言符号表的概念、结构、功能和实现方法:符号表的概念和分类符号表的结构和组织方式符号表的功能和操作符号表的实现方法和技术符号表的概念和分类符号表的概念符号表是一种映射关系,它将程序中的符号名称映射到其对应的属性集合。
属性集合包括了符号的内存地址、数据类型、作用域、存储类别、初始化值等信息。
例如,下面的 C 语言代码片段中,定义了一个全局变量globalA,一个静态变量globalB,一个函数funcA和一个主函数main:/*** 全局变量*/int globalA =2022;/*** 静态变量*/static int globalB =2023;int funcA() {int localFuncAValue =13;return0;}int main(int argc, char*argv[]) {int localMainValue =14;return0;}对于这段代码,编译器会为每个符号创建一个符号表项,并填充其属性。
一个可能的符号表如下:符号名称内存地址数据类型作用域存储类别初始化值globalA1000int全局外部2022globalB1004int全局静态2023funcA2000int()全局外部-main3000int(int, char**)全局外部-localFuncAValue-4(%rbp)int局部(funcA)自动-localMainValue-4(%rbp)int局部(main)自动-可以看到,每个符号表项由一个符号名称和一个属性集合组成。
属性集合可以根据不同的编译器设计而有所差异,但一般都包含了上述几个基本属性。
编译原理符号表
编译原理符号表符号表是编译器中一个非常重要的数据结构,用于存储程序中的标识符(如变量、函数名等)和对应的属性信息(如数据类型、作用域等)。
在编译器的各个阶段,都需要使用符号表来进行词法分析、语法分析、语义分析等操作,因此符号表设计的好坏直接影响到编译器的质量和效率。
一般来讲,符号表可以被看作是一个以标识符为键、以属性信息为值的映射表。
在编译器的词法分析阶段,源代码中的每个标识符都会被扫描并加入符号表中,同时为每个标识符生成一个唯一的“id”(也称为“符号表条目”)作为在后续处理中访问符号表的索引。
在编译器的语法分析和语义分析阶段,编译器会利用符号表进行语法分析和语义检查。
例如,在语法分析阶段,编译器需要判断变量是否被正确声明和使用,因此需要在符号表中查找变量的属性信息;而在语义分析阶段,编译器需要对表达式进行类型检查或者函数调用进行参数匹配,因此也需要在符号表中查找相关的属性信息。
需要注意的是,符号表的实现需要考虑到标识符的作用域、重复定义、名称空间等问题。
一般来说,编译器需要支持不同作用域之间的变量共存和访问,因此需要为不同的作用域维护不同的符号表。
当在一个新作用域中遇到相同的标识符时,编译器应该创建新的符号表条目;而在同一作用域中出现重复定义时,编译器应该抛出错误信息。
同样需要注意的是,符号表的实现也需要考虑到数据结构的效率和空间占用。
一些常用的实现方式包括基于哈希表的实现、基于树的实现(如平衡树、二叉查找树等)等。
在编译器优化阶段,符号表的实现也会影响编译器生成的目标代码的质量和效率。
例如,在常量表达式优化中,编译器使用符号表来维护常量的值和类型信息,从而可以直接进行常量表达式的求值,而不必在运行时才计算。
总的来说,在编译器中,符号表是一个极其重要的数据结构,对于编译器的性能和代码质量有着重要的影响。
因此,在设计和实现编译器时,需要认真考虑符号表的性能和可扩展性,并且根据具体的编程语言特性进行相应的优化。
C++编译器符号表有哪些内容?
#define CONSTANT_Methodref 10
#define CONSTANT_InterfaceMethodref 11
#define CONSTANT_String 8
#define CONSTANT_Integer 3
cp_info **constant_pool; // 常数表,又称变长符号表,
u2 access_flags; // Class的声明中使用的修饰符掩码,
u2 this_class; // 常数表索引,索引内保存类名或接口名,
如果文中有任何错误的地方,拜托你一定要指点我,谢谢了!
符号表存储的内容有哪些?从编译器来看,符号表与编译的各个阶段都有交互,符号表的内容也会在编译器的不同阶段包含不同的内容【一般来讲,在词法分析,语法分析阶段编译器都是填充符号表,在语义分析阶段更多得操作是从符号表中查询数据,当然还有时节点的各种属性(类型,作用域,分配空间大小,(函数)的参数类型)等。对符号表的具体使用方法每个编译器都不同。
field_info **fields是类域数据的指针数组,指针数组个数为fields_count,结构体field_info定义如下:
struct field_info
{
u2 access_flags; //域修饰符掩码
u2 name_index; //域名在常数表内的索引
#define ACC_NATIVE 0x0100
#define ACC_INTERFACE 0x0200
#define ACC_ABSTRACT 0x0400
#define ACC_STRICT 0x0800
u2 super_class; // 常数表索引,索引内保存父类名,
符号表
• 作用:记录源程序中各种名字的属性和
特征等有关信息。 • 内容:名字,有关信息(属、类型等) • 表项的建立: • 运用:语义检查、产生中间代码、地址 分配的依据
6.1 符号表的作用
在编译的各个阶段,每当遇到名字时, 都要查找符号表。 因此,合理组织符号表,使其占用的存储 空间较少、易于访问,对提高编译的效 率很重要。
(名字,所在过程编号) • 例如,Pascal(嵌套结构型语言) 的符号 表组织:每当近入一层过程时,要为在 此过程中新说明的标识符建立一张子符 号表。
6.5 符号表的内容
• 符号表的信息栏中记录了每个名字的有
关性质,如类型、种属、大小、以及相 对数等。 • 不同的程序语言对于名字性质的定义各 有不同。 • 一个名字的有关信息常常是分几次填入 信息栏中的。 • 符号表中信息栏的具体组织取决于所翻 译的具体的源语言和目标机器。
• 符号表的表项包括名字栏和信息栏 查填符号表一般通过匹配名字来实现。 对符号表的操作一般有: • 对给定的名字,查询其是否已在表中; • 添加新名字; • 访问某个名字的某些信息; • 填加或更新某个名字的某些信息; • 删除一个或一组无用的项。
6.2 符号表的组织方式
最简单方式:表中各项各栏的长度固定。 间接方式:符号表中的相应栏存指针,指向 存储具体信息的位置。 符号表
的作用域范围。如,嵌套过程中说明的 名字,其作用范围局限于该过程。因此, 同一个标识符在不同的地方可能被说明 为标志不同的对象,具有不同的性质, 要求分配不同的存储空间。 • 作用域分析:使得标识符在不同的作用 域得到正确的引用。
最近嵌套作用域规则: 最近嵌套作用域规则:
• 过程中的局部变量的名字是一个二元组
编译原理符号表的原理及典型实例
05
符号表的设计与实现
符号表的数据结构设计
符号表的数据结构应满足高效、 易扩展和易维护的要求,通常 采用哈希表、二叉树等数据结
构实现。
符号表应包含符号名称、符 号类型、符号属性等信息, 以便在编译过程中快速查找
和识别符号。
符号表还应支持动态添加、删 除和修改等操作,以适应源代
码中符号的变化。
符号表的实现算法
常量名的符号表实例
总结词
常量名符号表实例展示了如何使用符号表来管理程序中的常量。
详细描述
常量名符号表记录了常量的名称、类型和值等信息。通过符号表,编译器能够方 便地查找常量的定义和使用,并进行相应的语义分析和代码生成。在处理常量时 ,符号表有助于编译器优化程序的性能,例如常量折叠和常量传播等。
04
编译原理符号表的原 理及典型实例
目录
• 编译原理符号表概述 • 符号表的原理 • 符号表的典型实例 • 符号表在编译过程中的应用 • 符号表的设计与实现
01
编译原理符号表概述
符号表的概念
符号表是一种用于存储程序中标识符 信息的数据结构,主要用于编译过程 中对标识符进行跟踪和管理。
符号表中的每个条目都包含有关标识 符的信息,如名称、类型、作用域等。
如果符号表中存在该标识符的信息,编译器就可以 使用这些信息来生成相应的代码。
符号表的更新
01
在编译过程中,符号表可能会被更新以反映源代码的变化。
02
当源代码中添加、删除或修改标识符时,符号表中的相关信息
也需要相应地更新。
更新符号表的过程通常涉及到在哈希表中插入、删除或修改相
03
应的条目。
03
符号表的典型实例
典型实例
资料:第八章符号表
第八章 符号表编译过程中编译程序需要不断汇集和反复查证出现在源程序中各种名字的属性和特征等有关信息。
这些信息通常记录在一张或几张符号表中。
符号表的每一项包含两部分,一部分是名字(标识符),另一部分是此名字的有关信息。
每个名字的有关信息一般指种属(如简单变量、数组、过程等)、类型(如整、实、布尔等)等等。
这些信息将使用于语义检查、产生中间代码以及最终生成目标代码等不同阶段。
编译过程中,每当扫描器识别出一个单词后,编译程序就查阅符号表,看它是否已在其中。
如果它是一个新名就将它填进表里。
它的有关信息将在词法分析和语法-语义分析过程中陆续填入。
符号表中所登记的信息在编译的不同阶段都要用到。
在语义分析中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的说明是否相一致)和产生中间代码。
在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的依据。
对于一个多遍扫描的编译程序,不同遍所用的符号表也往往各有不同。
因为每遍所关心的信息各有差异。
本章重点:符号表的一般组织和使用方法。
第一节 符号表的组织和使用 栏。
表格的形式是:信息栏通常包含许多子栏和标志位,用来记录相应名字的种种不同属性。
由于查填符号表一般都是通过匹配名字来实现的,因此,名字栏也称主栏。
主栏的内容称为关键字(key word )。
虽然原则上说,使用一张统一的符号表也就够了,但是,许多编译程序按名字的不同种属分别使用许多符号表,如常数表、变量名表、过程名表等等。
这是因为,不同种属名字的相应信息往往不同,并且信息栏的长度也各有差异的缘故。
因而,按不同种属建立不同的符号表在处理上常常是比较方便的。
对于编译程序的符号表来说,它所涉及的基本操作大致可归纳为五类:1、对给定名字,确定此名是否在有中;2、填入新名;3、对给定名字,访问它的有关信息;4、对给字名字,填写或更新它的某些信息;5、删除一个或一组无用的项。
不同种类的表格所涉及的操作往往也是不同的。
编译原理符号表
编译原理符号表1. 引言编译原理是计算机科学领域中一个重要的研究方向,它研究的是将高级语言程序转化为机器语言的过程。
在编译器中,符号表是一种常用的数据结构,用于存储程序中的各种符号及其相关信息。
本文将深入探讨编译原理符号表的概念、作用、设计方法以及常见的符号表实现方式。
2. 符号表的概念和作用2.1 符号表的定义符号表是编译器中用于存储程序中各种符号信息的数据结构。
它一般由编译器自动生成和维护,用于支持语法分析、语义分析和代码生成等编译过程。
2.2 符号表的作用符号表在编译器的各个阶段都发挥着重要的作用:•语法分析阶段:符号表用于识别和存储各种变量、函数和类型的声明信息,以支持后续的语义分析过程。
•语义分析阶段:符号表用于检查变量和函数的引用是否合法,并记录其类型信息和作用域等属性,以支持类型检查和语义约束的验证。
•代码生成阶段:符号表用于存储中间代码和目标代码中的符号引用和符号定义的映射关系,以支持代码生成和目标代码优化等过程。
3. 符号表的设计方法3.1 符号表的数据结构符号表的数据结构通常由符号表项组成,每个符号表项用于存储一个符号及其相关信息。
常见的符号表项包括符号名称、符号类型、作用域、内存地址等。
3.2 符号表的组织方式符号表的组织方式可以有多种选择,常见的包括线性表、哈希表、树和图等。
选择合适的组织方式可以提高符号表的查询效率和插入删除的性能。
3.3 符号表的查询算法符号表的查询算法是指根据给定的符号名称,在符号表中进行查找并返回对应的符号表项。
常见的查询算法有线性搜索、二分搜索和哈希搜索等,选择合适的查询算法可以提高符号表的查询效率。
4. 常见的符号表实现方式4.1 线性表实现线性表实现是符号表最简单的一种实现方式,它可以使用数组或链表来存储符号表项。
线性表实现的优点是简单易懂,缺点是查询效率较低,随着符号表规模的增大,性能下降明显。
4.2 哈希表实现哈希表实现是一种常用的符号表实现方式,它通过哈希函数将符号名称映射到符号表项存储的位置。
编译原理符号表的原理及典型实例
四、符号表的数据结构
有序表——符号表项按照符号的字符代码串 的值的大小排列
………………… …a…………… …………b…… …a…………… …………d…… …c…………… …………b…… ……
二、符号表的内容
标识符的名字 与标识符有关的信息 类型信息(包括种类和属性) 地址码 层次信息 行号信息 ……
二、符号表的内容 例:Pascal语言的名字信息表nametab
name kind lev typ normal ref adr/val/size link
0 1 tx→
指向同一程序体中定义的上一个名字 名字所在的程序体的静态层次。规 adr, 当名字为变量名时(包括形参,存入该变量(或形参)在相应活动记录 一个布尔量,用于标明名字是否为变量形参 当名字为数组类型或数组变量名时,ref指向该数组在数 名字的类型,类型有整型(ints)、字符型 名字种类,可以是常量 名字标识符 在nametab中的位置,每个程序体在 中分类的存贮单元的相对地址;对于过程名,填入他们相应代码的入口地 定主程序的层次为1,主程序中定 名,当名字是否为变量形参名时填入false, 组信息表中的位置;当名字为过程名时,ref指向该过程 (chars)、布尔型(bool)、数组(arrays),对 址(constant)、变量(variable)、 nametab中登记的第一个名字的link 义的层次为2,依次类推 val, 当名字为变量名时,填入他们的相应值 其他情况填入true或不填 在程序体表(btab)中的位置;其他情况ref为0 于无类型的名字填入notype 为0 类型(type)、过程(procedure) size, 当名字为类型名时,填入该类型数据所需存贮单元的数目
编译原理第八章 符号表
8.3 名字的作用范围(Fortran)
• Fortran 局部、全局
• 执行时过程(函数)不
Name
Information
嵌套,局部区域只有一
···
局
个现行段;
···
部 • 编译时,尽管查填符号
表过程只限于局部,但
考虑到地址分配的全局
性,需将每个程序段符
号表保存在外存中,采
• 定长方式 • 间接方式 (1)名字的间接存储 (2)信息的间接存储
Name ● ●
Information
如何组织
方式
6 S A MP L E 3 S U M
Name
Information ● ●
数组信息表 维数 首地址 维1
内情向量表
··· ···
以数组为例 维n
如何组织
• 对于名称:把所有标识符都存放在一个 独立的字符串数组,主栏只放一个指示 器和一个整数(名字的长度)
var f, g: real; procedure B3(y:real) const b=5; procedure B4 … end B4 end B3
end B2 end B1
8.3 名字的作用范围 (Pascal)
top
(14)…
B4 (13)…
0
h (12)… 13
sp b (11)…
12
y (10)…
最近使用优先查找 (链头)
较难
中 排序整理 折半查找
二叉树
较难
中 构造排序树,查找时 依子树次序逼近。
杂凑(哈希
难
表)
高 杂凑函数: 名称于位置的映射 基于计算的查找。
数据结构的知识
第六章(2)符号表的管理
}
} a = 1, b = 1 printf(“a = %d, b = %d\n”, a, b);
}
33
2.在语言程序的局部化单位中,标识符的出现分为定 义性出现和使用性出现。
⑴定义性出现的标识符:局部化单位的声明部分出现 的标识符,其作用是确定该标识符的属性信息,如 名字,类型,存储位置等。一个标识符在一个局部 化单位只能被声明一次。
28
❖对于散列表,新符号的登录是通号表的目的:
判断该符号的存在性; 获取该符号的语义属性. ❖符号表的查找算法:顺序查找、折半查找、杂凑查 找.
30
6.3.3 符号表的局部化处理
一、问题的引出
1.源语言程序的局部化单位 程序中允许有声明的 部分称为一个局部化单位,通常是一个子程序(函数、 过程)或分程序:
19
6.3.1 符号表的建立和查找
一.符号表的初始化 在编译过程中某个时刻,符号表的状态反
映了该时刻被编译的语言程序正被编译的位置 的状态.具体来说主要是反映了在该时刻被编译 的语言程序中可视标识符的状态. 符号表的初始化,在对语言程序开始编译的时刻, 定义建立符号表的初始状态.
20
1.符号表的表长是渐增变化的情况: ❖线性组织和二分法组织的符号表,其表的长度在编译开始时 通常为0,而随着符号的逐步登录,表长增长. ❖按这类方法组织的符号表,其初始化方法只需将表尾推向表
一、符号表的总体组织
符号表的每一项包含两部分:标识符的名字;该名字的信 息。
不同类别的标识符所包含的信息是不同的。 符号表的总体组织既可以采用多表结构,也可以采用单表
结构,也可以二者折中。究竟采用哪种结构并没有统一的规 定,编译程序可根据实际处理语言的需要进行选择。
符号表
3
二 符号表分类
名字有多类,所含信息差异较大,为便于组织与使用,一般把符 号表分为如下几类分别进行管理: 常量表;标号表;变量表;过程名表等.
三 符号表的基本操作
1>查找 2>插入 3>访问 4>修改 5>删除 这些操作在数据结构中已经详细介绍过,这里就不再赘述.
4
四 符号表的组织
为了提高查填速度,符号表一般组织成哈希表.这里介绍一种 经过变异后的哈希表,基本结构如下: 名字 信息 指针 哈希映射 1 0 2 3 i avail 剩余空间 N-1 哈希表分成两个部分:映射空间,符号空间. 映射函数 f (key) 的值域为: 0.. N -1. 映射空间中的内容为指针, 指向符号在符号空间的位置.
5
例如:x,y,z,x1 是程序中说明的变量,编译扫描说明语句时依次把各 变量放入符号表. 假设 哈希函数由各变量名的首字母的位序决定, 则符号表如下: 符号表 hash 表 0 null 1 2 3 4 名字 x y z x1 剩余空间 信息 指针 null
23 24 25
4 2 3
avail
null null 1
7
六 pascal 符号表的组织
pascal 是一种子程序结构的语言,允许嵌套定义子程序,并且 允许同一标识符在不同层次的子程序中代表不同的名字.这就引 出名字的作用域问题,编译时必须保证引用名字的正确性. 例如: program exam;
var i , j , k :integer;
procedure sub1; var i , j :real; begin .......... i ..........; .......... j ..........; .......... k .........; end;
编译原理符号表和词法分析
扫描源程序
识别单词
转换成属性字
六、词法分析(续一)
词法分析的两种处理结构
字符
单词
源程序
词法分析
L1程序
源程序
字符
符号表
单词
词法分析
语法分析
回送单词
符号表
七、取单词
1、单词的种类
单词由字符组成。 <字符>::=<字母>|<数字>|<特定符号>|<无效字符> <字母>::=a|b|c|..z|A| B|C|...|Z <数字>::=0|1|2|3|...|9 <特定符号>::=+|-|*|/|:=|<>|<|…. <无效字符>::=<回车符>|<换行符>|<制表符> symbol=(ident,constsy,notop,mul,div,add,sub….) 单词的机内表示采用长度统一的二元形式(token字) (单词种别码,单词的自身值)
七、取单词 流程图
开始
跳过空格符和回车符
N 字母
Y 读标识符
数字 N Y
查保留字表
取数
查到 N
Y identsy
保留字sy
constsysy
特殊符号 N Y
特殊符号sy
error
结束
八、读标识符
1、标识符的文法规则 <标识符>::=<字母>{<字母>| <数字> } <字母>::=a|b|c|..z|A| B|C|...|Z <数字>::=0|1|2|3|...|9
变量名符号表
ENTER过程完成。
说明部分的分析与处理(程序)
• 说明类型的定义: • object= (constant, variable,procedur) • (定义纯量/枚举类型) • 名字表的定义 table:array[0..txmax] of
record name:alfa; • case kind:object of
表也是一个栈,栈顶指针为level。当进入一个新过程时,level增加1;每当退 出一个过程时,level减1。DISPLAY(level)总是指向当前正在处理的最内层的 过程的子符号表在栈符号表中的起始位置。
.在符号表的信息栏中引入一个指针域(previous)用以链接它在同一过程内 的前一域名字在表中的下标(相对位置)。每一层的最后一个域名字,其 previous之值为0。这样,每当需要查找一个新名字时,就能通过
地址ble表的下标指针tx补充说
明:
tx 6 (9)
LE 1
V BLOCK
tx ...
0
(6)
LE 0 V BLOCK
主程
序
tx是BLOCK的 实际值参
BLOCK(LEV+1,TX, …) (递归进入分程序)
第1次调用block BLOCK(0, 0, …)
编译程序按名字的不同种属分别使用许多符号 表,如常数表、变量名表、过程名表等等。
SUBROUTINE INCWAP(M,N)
10 K=M+1
M=M+4 N=K RETURN END
经编译头三阶段后所产生的主要表格有: 符号 名表SNT、常数表CT、入口名表ENT、标号 表LT和四元式表QT
符号名表SNT
几种通常都是需要的。 1 符号名 2 符号的类型 3 符号的存储类别 4 符号的作用域及可视性 5 符号变量的存储分配信息 6 符号的其它属性(1) 数组内情向量 (2) 记录结构型的成员信息(3) 函数及过程
cmake 编译 符号表
cmake 编译符号表
在CMake编译过程中,符号表(symbol table)是一个重要的概念。
符号表是编译器在编译过程中生成的一种数据结构,用于记录程序中定义和引用的符号(如变量、函数等)的信息。
在CMake编译过程中,符号表的作用主要体现在以下几个方面:
1.符号解析:符号表用于解析程序中符号的引用,确定符号的名称、类型和作用域等信息。
这样,编译器就能够正确地处理符号的引用,生成正确的目标文件。
2.链接过程:在链接阶段,链接器会使用符号表来解析不同目标文件之间的符号引用关系,将各个目标文件组合成一个可执行文件或库文件。
如果存在多个目标文件都定义了同一个符号,链接器会根据符号表的记录来决定保留哪个定义。
3.调试信息:符号表还包含了程序的调试信息,如变量名称、函数名称等。
这些信息对于后续的调试过程非常重要,可以帮助开发人员更好地理解程序的运行状态和问题所在。
在CMake中,可以通过生成器模型来控制符号表的生成和使用。
具体来说,CMake支持多种生成器,如Visual Studio、Makefile等,每个生成器都有自己的符号表生成方式。
例如,在Visual Studio生成器中,符号表会被直接嵌入到目标文件中;而在Makefile生成器中,符号表会被写入到一个单独的文件中,该文件随后会被链接器使用。
总的来说,符号表是CMake编译过程中不可或缺的一部分,它有助于编译器正确处理符号引用、链接不同目标文件以及提供调试信息。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
0 1
level→
btab
lastpar last psize vsize 0 1
bx→
7
数组信息表atab
用于记录每个数组的详细信息
inxtyp eltyp elref low high elsize size 1 2
ax→
数组的数下组标元类素型类型当元元素数素数组为组下数信数数限组息组组数时在上元组,at限素a本它b的身指表体的向中积体该积 的位置,其他情况为0
一个PASCAL过程
过程头; 说明段(由一系列的说明语句组成);
begin 执行体(由一系列的执行语句组成);
end
16
最近嵌套原则
X
一个在子程序B1中说明的名字X
●
只在B1中有效(局部于B1)
●
如果B2是B1的一个内层子程序
●
且B2中对标识符X没有新的说明, 则原来的名字X在B2中仍然有效
20
nametab 21
22 23
P21 b1 b2
19 0 21
24
PL语言的中间代码
指令格式: opcod l a
opcod:操作码 l:第一操作数,程序体层数 a:第二操作数,相对地址
编译时如何确定变量的层数(地址)? 运行时如何根据指令中变量的层数和相对
地址确定变量的存储单元?
end.
14
符号表组织
FORTRAN的符号表组织
一个FORTRAN程序由一个主程序段和若干个 辅程序段组成
把局部名和全局名分别存在不同的地方
15
符号表组织
FORTRAN的符号表组织 嵌套结构语言的符号表组织
如PASCAL、ALGOL、ADA
PASCAL程序本身可以看成是一个操作系统所调 用的过程,过程可以嵌套和递归
址
3
PL 语言编译程序的符号表
表格的定义
名字表(nametab) 程序体表(btab) 层次显示表(display) 数组信息表(atab) 中间代码表(code)
4
名字表(nametab)
名字表nametab:登记程序中出现的各种名 字及其属性
name kind lev typ normal ref adr/val/size link
name kind lev typ normal ref adr/val/size link
程0 序体表btab和层次显示表display 1
tx 程→序体表btab
记录个程序体的总信息,用于对源程序中定义的名字的 作用域进行分析;对名字表进行管理
lastpar last psize vsize 0 1
编译原理
第八章 符号表
1
第八章 符号表
符号表的组织与作用 整理和查找 符号表的内容 名字的作用范围
2
8.4 符号表的内容
符号表的信息栏中登记了每个名字的有关 性质
类型:整、实或布尔等 种属:简单变量、数组、过程等 大小:长度,即所需的存储单元字数 相对数:指分配给该名字的存储单元的相对地
m ints ints 0 1 20 1 20
ax→
9
中间代码表code
用于存放编译程序所产生的每条中间代码
opcod
l
a
操作码
第一操作数, 程序体层数
第二操作数, 相对地址
10
第八章 符号表
符号表的组织与作用 整理和查找 符号表的内容 名字的作用范围
11
8.3 名字的作用范围
在许多程序语言中,名字都有一个确定的作用范 围
i2
0
22
17
j2
16
18
a
17
19
c
18
20 P21
19
nametab 21 b1
0
22
b2
21
23
22
display 00 11 2 23 34
program P; var a,b : integer; procedure P1 (i1, j1:integer); var c,d : integer … end; procedure P2 (i2, j2:integer); var a,c : integer; procedure P21; var b1,b2 : boolean; … end; … end; …
运行时如何根据指令中变量的层数和相对 地址确定变量的存储单元?
20
program P; var a,b : integer; procedure P1 (i1, j1:integer); var c,d : integer … end; procedure P2 (i2, j2:integer); var a,c : integer; procedure P21; var b1,b2 : boolean; … end; … end; …
0 1 ▪动tax记d→r,录当中名分字类为的变存量贮名单时元(包的括相形对参地)址,;存对入于该过变程量名(或,形填参入)在他相们应相活应
代▪▪当 组 在vsia码z名信程le,的,当字息序当名入名为表体名(型名c口字字o中表数字(字地t标n为名 (于y为c的(组种址spb常识h一 名 其t字 无类eat位类类a量a符)n个 , 他型的 类r、名 定 义b置型,s名t指在n为名))布 当 情类 型过、a字 主 的中时;或可向 n0m时尔名况型的a,程布变所程层的当数以同em,量字填t,名填(尔量在序次位一ae名组是填pbt入,是入类字程ra型(的的为置入中字变常ovb他用否t序型填a该c中登(程层2;r为量量br们eu体,于为i类有入记的oda序次其e名过的中bo依型或u的位标变整n体为他相时程lr定oe)数第置此e不明量型、应的1情t),名义)据、一,y,类填名形(值数p静况的ir时所个每类nee主推字参组上t态r需f名个,se指程是名一()存字f程层ar、为向e序个否 时r贮的序次rf字0该 指名a中单l体为 填i。yn符字数向元在s定k变 入规)型数,组该量fa目对在过l形se数程参5,
bx→
指向本本指程程向序序本体体程所中序有最体形本后中参程一最所序个后需体名一体所字个积有在形、局式包部参数在据所 na括mne连taa接mb数e中t据a的b所位中占置的需空位空间置间大小
6
程序体表btab和层次显示表display
层次显示表display
描述正在处理的各嵌套层,对程序体表进行管理
var A:integer;
…
begin
…
end
begin
…
end
B(bool)
18
名字作用域分析
两种做法
引入"过程编号"属性。查找时,先查找本过程 编号的名字,查不到则查找外层过程编号的名 字,…,等等
按"栈"式思想组织符号表。查找时,从后往前 查找,碰到的第一个名字就是所需查找的名字
19
25
本章小结
符号表的组织与作用 整理和查找 符号表的内容 名字的作用范围
26
作业
《编译原理大作业实习》
阅读
第三节 PL 语法分析 分析PL编译程序的数据结构及相关程序
预习
第四节 PL语义分析及中间代码产生
27
0 1
15
6
read
5
7
write
6
8
a
0
12
2
pfuvprvoanraogcrrtcriiaaoe,j,mnd:biunp:Ptroeei;sngiPetteir1o;gn(e(i1ird;,:ja1lf:ain):tiengteegre)r;; bveagrinc,d : integer
3
n…ametab[0].name:=id; j:=level;
14 17 20
9
b
8
10
P1
9
11
i1
0
12
j1
11
13
c
12
14
d
13
enrde;peat
prvpoariwc:or=hecbidaleteua,dcbnrue[a:rdmiePnise2Ptptea2(lgiab12ey[;,i[r]jj;.]2n]:a.ilmnatseet<;g>eidr)d; o 4
… real X,Z COMMON /C/A1,B1
… END
13
program P; var a,b : integer; procedure P1(i1, j1:integer); v…ar c,d : integer end; procedure P2(i2, j2:integer); var a,c : integer; procedure P21; va…r b1,b2 : boolean; e…nd; e…nd;
end.
0
name link
btab
1
char
0
2 integer 1
0
3 boolean 2
0 01235674
4
false
3
5
true
4
0 1
6
read
5
7
write
6
108905
8
a
0
1012 2
1102341
9
b
8
10
P1
9
11
i1
0
3 1067
12
j1
11
13
c
12
12096708
14
d
13
end.
21
level
display
00 11 23 34
program P; var a,b : integer; procedure P1 (i1, j1:integer); var c,d : integer … end; procedure P2 (i2, j2:integer); var a,c : integer; procedure P21; var b1,b2 : boolean; … end; … end; …