先决条件–编译器的阶段
符号表是由编译器创建和维护的重要数据结构,用于跟踪变量的语义,即它存储有关范围的信息和有关名称的绑定信息,有关各种实体实例的信息,例如变量和函数名称,类,对象, 等等。
- 它建立在词法和语法分析阶段。
- 该信息由编译器的分析阶段收集,并由编译器的综合阶段使用以生成代码。
- 编译器使用它来实现编译时间效率。
- 它由编译器的各个阶段使用,如下所示:
- 词法分析:在表中创建新表条目,例如关于令牌的条目之类的示例。
- 语法分析:在表中添加有关属性类型,范围,维度,参考线,用途等的信息。
- 语义分析:使用表中的可用信息检查语义,即验证表达式和赋值在语义上正确(类型检查)并相应地进行更新。
- 中间代码生成:参考符号表以了解分配了多少时间和哪种类型的运行时,该表有助于添加临时变量信息。
- 代码优化:使用符号表中的信息进行机器相关的优化。
- 目标代码生成:使用表中存在的标识符的地址信息生成代码。
符号表条目–符号表中的每个条目都与在不同阶段支持编译器的属性相关联。
存储在符号表中的项目:
- 变量名和常量
- 过程和函数名称
- 字面量常量和字符串
- 编译器生成的临时文件
- 源语言中的标签
编译器从Symbol表中使用的信息:
- 数据类型和名称
- 申报程序
- 存储偏移
- 如果是结构或记录,则指向结构表。
- 对于参数,参数是按值传递还是按引用传递
- 传递给函数的参数的数量和类型
- 基址
符号表的操作–符号表上定义的基本操作包括:
实施符号表–
以下是用于实现符号表的常用数据结构:-
- 列表 –
- 在此方法中,数组用于存储名称和相关信息。
- 在所有存储记录的末尾维护一个指针“可用” ,并在它们到达时按顺序添加新名称
- 要搜索名称,我们从列表的开头开始直到可用的指针,如果找不到,则会出现错误“使用未声明的名称”
- 插入新名称时,我们必须确保它不存在,否则会发生错误,即“多个定义的名称”
- O(1)的插入速度很快,但是大表的查找速度很慢–平均O(n)
- 优点是占用的空间最少。
- 链表–
- 此实现使用链表。链接字段添加到每个记录。
- 名称的搜索按链接字段的链接所指向的顺序进行。
- 维护指针“ First”以指向符号表的第一条记录。
- O(1)的插入速度很快,但是大表的查找速度很慢–平均O(n)
- 哈希表 –
- 在哈希方案中,维护两个表-哈希表和符号表,这是实现符号表的最常用方法。
- 哈希表是一个索引范围为0到tablesize – 1的数组。这些条目是指向符号表名称的指针。
- 要搜索名称,我们使用哈希函数,该函数将导致0到tablesize – 1之间的任何整数。
- 插入和查找可以非常快– O(1)。
- 优点是可以进行快速搜索,而缺点是实现起来很复杂。
- 二进制搜索树–
- 实现符号表的另一种方法是使用二叉搜索树,即我们添加两个链接字段,即左子和右子。
- 所有名称都被创建为根节点的子节点,并且始终遵循二进制搜索树的属性。
- 插入和查找平均为O(log 2 n)。