Nic*_*ury 2 compiler-construction lexical-analysis
假设我有一个包含以下内容的 C 源代码文件:
int i = 21 + 10;
int blah(){
int i = 21;
return i + 10;
}
main(){
int i;
i += i + 10;
}
Run Code Online (Sandbox Code Playgroud)
词法分析阶段结束时,符号表的内容是什么?是否会有多个条目i,或者10词法分析器是否仅放置唯一值?
据我了解,令牌流将包含出现的所有令牌,但我不确定符号表。
词法分析只是将源代码字符流分解为表示语言原子(单词)的标记流。
一般来说,词法分析器不会为某种语言构建符号表。
由于预处理器的原因,C 是相当特殊的情况。当读取预处理器指令时,C 预处理器必须收集宏的名称及其相应的值。通常(可能有所不同)C 预处理器(至少我们的预处理器是这样做的,请参阅我的简介)通过将源代码分解为标记流来进行操作,并处理以“#”开头的行中的标记(例如预处理器行)。由于源流依赖于扩展宏,并且扩展宏需要预处理器知道其扩展,因此预处理器在宏定义的全局范围内记录与其关联的宏名称和宏主体,当它遇到此类定义时。它使用宏名称来扩展宏调用并评估在词法分析时遇到的预处理器条件。但预处理器不会构建任何其他符号表。
忽略预处理器,通常在解析源文本后构建符号表,当然如果编译器要进行任何类型的全局分析。如果编译器生成抽象语法树(AST),这是最简单的。一些编译器,特别是那些动态生成代码的编译器(现在很少见),可能会在解析并遇到应该进入作用域的条目时构建符号表。
由于弱解析技术的广泛使用,C 编译器再次出现了常见的特殊情况。这种技术无法通过纯粹的解析来区分某些晦涩的语法(特别是“X*Y;”)。为了区分这种情况,需要了解某些符号是否是类型声明的信息;具有弱解析技术的编译器然后将符号范围中的至少类型名称的集合纠缠到解析过程中。这使得此类弱解析器的代码非常难以理解。提供的链接清楚地表明,缠结实际上并不是必需的,因此可以一一地将解析与精心设计的编译器中的符号表构造完全隔离开来。
对于一种足够复杂的语言,例如 C++,如果不解析整个源文本就无法构建符号表。“命名空间”的概念意味着直到源文件中的最后一个声明之前可能不会遇到命名空间的条目。在这种情况下,在处理最后一个条目之前,该名称空间(显然是符号范围)的内容无法完成。
如果这一切看起来很混乱,那么事实确实如此。您问的是一个一般性问题,它必须解决数百种编程语言的问题,其中许多语言对于何时定义符号以及如何使用它们来解释程序源文本的其余部分有奇怪的规则。
最后总结:
| 归档时间: |
|
| 查看次数: |
1724 次 |
| 最近记录: |