Back to all posts
Notes

Symbol Table

A symbol table stores identifier information in a compiler, supporting declaration tracking, type checking, scope management, and efficient lookup for code generation.

1. What is a Symbol Table?

符号表是什么?

Symbol Table is one of the most important data structures in a compiler.

符号表是编译器中最重要的数据结构之一。

It stores information about identifiers in the source program.

它用来存储源程序中各种 标识符(identifiers) 的信息。

A symbol table records the names used in a program and their associated attributes.

符号表记录程序中出现的名字,以及这些名字相关的属性信息。


2. Why do we need a Symbol Table?

为什么需要符号表?

Programs contain many named entities, such as:

  • variables
  • procedures / functions
  • data objects
  • classes

程序中有很多被命名的对象,比如:

  • 变量
  • 过程 / 函数
  • 数据对象

The compiler must keep track of them.

编译器必须跟踪并管理这些名字。

核心理解

编译器不是只“看到一个名字”就结束了,它必须知道:

  • this identifier refers to what

    这个标识符到底代表什么

  • what type it has

    它是什么类型

  • where it is valid

    它在哪个作用域有效

  • where it is stored

    它存在哪里


3. Main functions of the Symbol Table

符号表的主要作用

(1) Store declarations

保存声明信息

The compiler stores information about declared objects.

编译器要保存程序中所有被声明对象的信息。

(2) Support identifier checking

支持标识符检查

When an identifier is used, the compiler checks:

  • whether it has been declared
  • whether it is used correctly
  • whether the type is correct

当一个标识符被使用时,编译器要检查:

  • 是否已经声明
  • 使用是否合法
  • 类型是否正确

(3) Help code generation

帮助代码生成

The symbol table may store the store address of an object.

符号表还可能保存对象的 存储地址,方便后续生成目标代码。


4. What information is stored?

符号表中存什么?

这个是考试很容易考的重点。

(1) Identifier itself

标识符本身

The symbol table must store the identifier name itself.

符号表必须保存标识符名字本身。

Two possible methods:

  • store the string directly

    直接存字符串

  • store a pointer to a separate string area

    存指针,指向独立字符串区

难点理解

直接存字符串简单,但可能浪费空间。

Using a separate string area is more space-efficient.

使用独立字符串区通常更节省空间。


(2) Type information

类型信息

The symbol table stores type information.

符号表要保存 类型信息

Examples:

  • Boolean
  • Integer
  • Float

More complex cases:

  • arrays
  • procedures / functions
  • records

Arrays

For an array, we may need:

  • number of subscripts / dimensions
  • subscript type
  • range of subscripts

对于数组,可能要存:

  • 维数 / 下标个数
  • 下标类型
  • 下标范围

Procedures / Functions

For a procedure or function, we may need:

  • number of parameters
  • parameter types
  • return type (for functions)

对于过程 / 函数,可能要存:

  • 参数个数
  • 参数类型
  • 返回值类型(函数)

Records

For a record, we may need:

  • field names
  • field types

对于记录体 / 结构体,可能要存:

  • 字段名
  • 字段类型

(3) Scope and lifetime

作用域和生存期

The symbol table stores scope and lifetime information.

符号表要保存 作用域(scope)生存期(lifetime) 信息。

这两个词要分清:

  • scope = where the identifier can be used

    作用域 = 这个名字在哪些地方能用

  • lifetime = how long the object exists

    生存期 = 这个对象存在多久


(4) Store address

存储地址

The symbol table may also store the store address.

符号表还可以保存对象的存储地址。


(5) Other information

其他信息

Possible extra information includes:

  • pointers for printing identifiers in alphabetical order
  • lists of declaration/use positions

额外还可能保存:

  • 为了按字母顺序输出标识符而设置的指针
  • 标识符声明 / 使用位置列表

5. Efficiency requirements

效率要求

这部分很容易变成简答题。

Searching must be efficient

查找必须高效

The compiler repeatedly searches the symbol table when identifiers appear.

编译器每次遇到标识符时,都可能要查符号表。

Adding new entries must also be efficient

插入新条目也必须高效

When a new identifier is encountered, it must be added quickly.

当第一次遇到新标识符时,需要高效插入。

Meaning:

A symbol table must support efficient lookup and efficient insertion.

符号表必须支持高效查找和高效插入。


6. How is it used during compilation?

编译过程中怎么使用符号表?

课件提到两种方式。

Method 1

Lexical analyzer recognizes identifiers, and syntax analyzer accesses the symbol table.

词法分析器先识别 identifier,再由语法分析器去访问符号表。

Method 2

The lexical analyzer directly searches/inserts into the symbol table and returns a reference.

词法分析器直接查找/插入符号表,然后把表项引用返回给语法分析器。

你要抓住的点

无论哪种方式,本质都一样:

  • identifier is recognized
  • symbol table is searched
  • new entry may be inserted
  • later phases use the stored information

也就是:

  • 先识别名字
  • 再查表
  • 必要时插入
  • 后续阶段继续使用这些信息

7. Pre-loading the symbol table

预先装入符号表

The symbol table may be partially built before compilation starts.

符号表可以在正式编译前先装入一些内容。

Examples:

  • standard I/O routines in Pascal
  • imported package symbols in Java

例如:

  • Pascal 的标准输入输出函数
  • Java 中 import 进来的包符号

重点理解

符号表不一定只放“用户自己写的名字”,也可以预装:

  • built-in names
  • library routines
  • imported symbols

8. Data structures for implementation

符号表可用什么数据结构实现?

The PPT mentions:

  • binary trees
  • hash tables

Meaning:

A symbol table can be implemented using data structures such as binary trees or hash tables.

符号表可以用二叉树或哈希表等数据结构实现。

难点提醒

这里老师更看重的是你知道:

  • why efficiency matters

    为什么效率重要

  • why these structures are suitable

    为什么这些结构适合高效查找和插入


9. Scope, Block, and Scoping Rules

作用域、块、作用域规则

这部分是 重点 + 难点

Scope

Every declaration has a scope.

每个声明都有自己的 作用域

Block

A block is a program unit that defines the scope of declarations.

块(block) 是限定声明作用范围的程序单元。

Scoping rules

Scoping rules determine which declaration an identifier use refers to.

作用域规则 决定某次标识符使用到底对应哪一个声明。

中文直白理解

当程序里同名变量很多时,编译器必须根据 block 和 scoping rules 判断:

现在看到的这个 x,到底是哪一个 x。


10. Three block structures

三种块结构

这个地方很容易考比较题。

(1) Monolithic blocks

The whole program is one block.

整个程序只有一个块。

Characteristics:

  • an identifier can be declared only once
  • every identifier must be declared
  • no local scope

特点:

  • 标识符只能声明一次
  • 每个标识符都必须先声明
  • 没有局部作用域

(2) Flat blocks

There are global and local blocks, but no deeper nesting.

有全局和局部两层,但没有更深嵌套。

Characteristics:

  • global declarations cannot be duplicated
  • local declarations in the same block cannot be duplicated
  • an identifier must have either a local or global declaration

特点:

  • 全局声明不能重复
  • 同一局部块内不能重复声明
  • 使用时必须能在局部或全局找到声明

(3) Nested blocks

Blocks can be nested inside other blocks.

块可以嵌套在别的块里。

Used in languages such as:

  • Pascal
  • Ada
  • C
  • Java

Characteristics:

  • an identifier can only be declared once in the same block
  • when used, it must be declared in the current block or an enclosing block

特点:

  • 同一个块中一个名字只能声明一次
  • 使用时必须能在当前块或外层块中找到声明

11. Most-Closely Nested Rule

最近嵌套规则

这是这份 PPT 最重要的难点之一。

The declaration that applies to an identifier is the one found first when searching from the innermost enclosing block outward.

一个标识符真正对应的声明,是从它所在位置出发,按“由内到外”查找时找到的第一个声明。

中文解释

就是:

先看当前块,再看外层块,再看更外层块。最近的那个声明生效。

关键词

inner declaration hides outer declaration

内层声明会遮蔽外层声明。

这就是常说的 shadowing

例子理解

如果外层有:

int x;

内层又声明:

int x;

那么在内层使用 x 时,指的是 inner x,不是 outer x。

在内层中,外层那个 xhidden / shadowed


12. What must the Symbol Table do in nested scopes?

在嵌套作用域下,符号表必须完成什么任务?

(1) Find the correct declaration

找到正确声明

Given an occurrence of an identifier, the symbol table must determine which declaration it refers to.

给定一个标识符出现位置,符号表必须判断它对应哪个声明。

(2) Prevent duplicate declarations at the same lexical depth

防止同一词法层次重复声明

An identifier should not be declared more than once at the same lexical depth.

在同一 lexical depth 中,同名标识符不能重复声明。

(3) Handle hiding / shadowing correctly

正确处理遮蔽

The symbol table must allow inner declarations to hide outer ones according to scoping rules.

符号表必须根据作用域规则正确处理内层对外层的遮蔽。


13. Simple stack organization

简单栈式组织

The PPT mentions a simple stack organization for local variables.

课件提到可以用一种简单的 栈式组织 来处理局部变量。

Idea:

  • when entering a block/procedure, allocate space
  • when leaving, deallocate it

思想是:

  • 进入一个块/过程时分配空间
  • 离开时回收空间

难点理解

课件进一步指出:

it may be better not to physically remove symbol table entries, but to make them inaccessible outside the block.

更好的做法不一定是把表项物理删除,而是让它们在块外 不可访问

你要会讲

The important issue is visibility, not necessarily physical deletion.

关键问题是“可见性”,不一定是“物理删除”。


14. 考前最该背的高频句

下面这些句子很适合考试直接写。

定义类

A symbol table is a compiler data structure used to store identifiers and their attributes.

符号表是编译器中用来存储标识符及其属性的数据结构。

作用类

It supports declaration processing, semantic checking, and code generation.

它支持声明处理、语义检查和代码生成。

信息类

A symbol table may store identifier names, type information, scope, lifetime, and store addresses.

符号表可以存储标识符名字、类型信息、作用域、生存期和存储地址。

效率类

Efficient lookup and insertion are essential for symbol table implementation.

高效查找和高效插入是符号表实现中的关键要求。

作用域类

Scoping rules determine which declaration is associated with a given identifier use.

作用域规则决定一个标识符使用对应哪个声明。

最近嵌套规则

Under the most-closely nested rule, the applicable declaration is the nearest enclosing one.

根据最近嵌套规则,生效的声明是最近包围它的那个声明。


15. 重点与难点总表

Key Points vs Difficult Points

Key Points 重点

  • definition of symbol table

    符号表定义

  • functions of symbol table

    符号表作用

  • information stored in symbol table

    符号表保存的信息

  • efficiency requirements

    效率要求

  • possible data structures

    可用数据结构

  • scope / block / scoping rules

    作用域 / 块 / 作用域规则

  • monolithic, flat, nested blocks

    三种块结构

  • most-closely nested rule

    最近嵌套规则

Difficult Points 难点

  • difference between scope and lifetime

    scope 和 lifetime 的区别

  • how identifier lookup works in nested blocks

    嵌套块中如何查找标识符

  • how shadowing works

    遮蔽如何发生

  • why symbol table entries may remain but become inaccessible

    为什么条目可以不删除,但块外不可见


16. 一段考前速记版

Final Exam Quick Review

Symbol Table is a key compiler data structure that stores identifiers and their attributes.

符号表 是编译器核心数据结构,用于保存标识符及其属性。

Its main functions are:

  • storing declarations
  • checking identifier usage
  • supporting code generation

它的主要作用是:

  • 保存声明信息
  • 检查标识符使用
  • 支持代码生成

A symbol table may contain:

  • identifier name
  • type information
  • scope
  • lifetime
  • store address

符号表中可能包含:

  • 标识符名字
  • 类型信息
  • 作用域
  • 生存期
  • 存储地址

It must support efficient lookup and efficient insertion.

它必须支持 高效查找高效插入

In nested block languages, identifier lookup follows the most-closely nested rule: the nearest enclosing declaration is used.

在嵌套块语言中,标识符查找遵循 最近嵌套规则:使用最近的外层声明。

Share this post

Back to home

Comments