📜  编译器中的符号表

📅  最后修改于: 2021-06-28 06:49:42             🧑  作者: Mango

先决条件–编译器的阶段

符号表是由编译器创建和维护的重要数据结构,用于跟踪变量的语义,即它存储有关范围的信息和有关名称的绑定信息,有关各种实体实例的信息,例如变量和函数名称,类,对象, 等等。

  • 它建立在词法和语法分析阶段。
  • 该信息由编译器的分析阶段收集,并由编译器的综合阶段使用以生成代码。
  • 编译器使用它来实现编译时间效率。
  • 它由编译器的各个阶段使用,如下所示:
    1. 词法分析:在表中创建新表条目,例如关于令牌的条目之类的示例。
    2. 语法分析:在表中添加有关属性类型,范围,维度,参考线,用途等的信息。
    3. 语义分析:使用表中的可用信息检查语义,即验证表达式和赋值在语义上正确(类型检查)并相应地进行更新。
    4. 中间代码生成:参考符号表以了解分配了多少时间和哪种类型的运行时,该表有助于添加临时变量信息。
    5. 代码优化:使用符号表中的信息进行机器相关的优化。
    6. 目标代码生成:使用表中存在的标识符的地址信息生成代码。

符号表条目–符号表中的每个条目都与在不同阶段支持编译器的属性相关联。
存储在符号表中的项目:

  • 变量名和常量
  • 过程和函数名称
  • 字面量常量和字符串
  • 编译器生成的临时文件
  • 源语言中的标签

编译器从Symbol表中使用的信息:

  • 数据类型和名称
  • 申报程序
  • 存储偏移
  • 如果是结构或记录,则指向结构表。
  • 对于参数,参数是按值传递还是按引用传递
  • 传递给函数的参数的数量和类型
  • 基址

符号表的操作–符号表上定义的基本操作包括:

实施符号表–
以下是用于实现符号表的常用数据结构:-

  1. 列表 –
    • 在此方法中,数组用于存储名称和相关信息。
    • 在所有存储记录的末尾维护一个指针“可用” ,并在它们到达时按顺序添加新名称
    • 要搜索名称,我们从列表的开头开始直到可用的指针,如果找不到,则会出现错误“使用未声明的名称”
    • 插入新名称时,我们必须确保它不存在,否则会发生错误,即“多个定义的名称”
    • O(1)的插入速度很快,但是大表的查找速度很慢–平均O(n)
    • 优点是占用的空间最少。
  2. 链表–
    • 此实现使用链表。链接字段添加到每个记录。
    • 名称的搜索按链接字段的链接所指向的顺序进行。
    • 维护指针“ First”以指向符号表的第一条记录。
    • O(1)的插入速度很快,但是大表的查找速度很慢–平均O(n)
  3. 哈希表 –
    • 在哈希方案中,维护两个表-哈希表和符号表,这是实现符号表的最常用方法。
    • 哈希表是一个索引范围为0到tablesize – 1的数组。这些条目是指向符号表名称的指针。
    • 要搜索名称,我们使用哈希函数,该函数将导致0到tablesize – 1之间的任何整数。
    • 插入和查找可以非常快– O(1)。
    • 优点是可以进行快速搜索,而缺点是实现起来很复杂。
  4. 二进制搜索树–
    • 实现符号表的另一种方法是使用二叉搜索树,即我们添加两个链接字段,即左子和右子。
    • 所有名称都被创建为根节点的子节点,并且始终遵循二进制搜索树的属性。
    • 插入和查找平均为O(log 2 n)。