符号 table 词法分析后的内容

Symbol table content after Lexical analysis

假设我有一个包含以下内容的 C 源代码文件:

int i = 21 + 10;    

int blah(){
    int i = 21;
    return i + 10;
}

main(){
    int i;
    i += i + 10;    
}

在词法分析阶段结束时,Symbol table的内容是什么? i10 会有多个条目还是词法分析器只放置唯一值?

据我了解,令牌流将包含 所有 个令牌,但我不确定符号 table.

词法分析只是将源代码字符流分解为表示语言原子(单词)的标记流。

一般来说,没有符号 table 是由词法分析器为语言构建的。

C 因为有预处理器,所以比较特殊。 C 预处理器必须在读取预处理器指令时收集宏的名称及其对应的值。通常(可能会有所不同)C 预处理器(至少我们有,请参阅我的简历)通过将源分解为标记流来运行,并处理那些以“#”开头的行中的标记(例如预处理器行)。由于源流依赖于扩展的宏,扩展宏需要预处理器知道它的扩展,预处理器在宏定义的全局范围内记录宏名称和宏体,因为它遇到这样的定义。它 使用 宏名称来扩展宏调用并评估它在词法分析时遇到的预处理器条件。但是预处理器不会构建任何其他符号 tables.

忽略预处理器,通常符号 table 是在解析源文本之后构建的,当然如果编译器要进行任何类型的全局分析。如果编译器生成抽象语法树 (AST),这是最简单的。一些编译器,尤其是那些动态生成代码的编译器(现在很少见),可能会在解析和遇到应该进入范围的条目时构建符号 table。

由于 weak parsing technology. Such technology cannot distinguish, by pure parsing, certain obscure syntax (notably " X* Y; ") 的广泛使用,C 编译器再次出现常见的特殊情况。为了区分它们,需要有关某些符号是否为类型声明的信息;解析技术较弱的编译器会将符号作用域中至少类型名称的集合纠缠到解析过程中。这使得这种弱解析器的代码很难理解。提供的链接清楚地表明实际上不需要缠结,因此可以在精心设计的编译器中将解析与符号 table 构造完全隔离。

使用足够复杂的语言(例如 C++),不解析整个源文本就无法构建符号 tables。 "namespace" 的概念意味着在源文件中的最后一个声明之前可能不会遇到名称空间的条目。在这种情况下,在处理完最后一个条目之前,该名称空间(显然是符号范围)的内容无法完成。

如果这一切看起来很混乱,那确实是。你问的是一个一般性问题,它必须解决数百种编程语言的问题,其中许多语言都有关于何时定义符号以及如何使用它们来解释程序源文本的其余部分的奇怪规则。

最终总结:

  • 一般来说,词法分析器不构建符号 table,它们构建标记流。
  • 一般来说,解析器不构建符号 table,它们构建 AST。
  • 一般来说,符号table是在构造AST之后构造的。
  • 一般来说,每个编译器在遵守上述规则方面会有所不同。