假设我有一个包含以下内容的C源代码文件:
int i = 21 + 10;
int blah(){
int i = 21;
return i + 10;
}
main(){
int i;
i += i + 10;
}
在词法分析阶段结束时,Symbol表的内容是什么? i
和10
会有多个条目,或者词法分析者只会放置唯一值吗?
据我了解,令牌流将包含所有标记,但我不确定符号表。
答案 0 :(得分:4)
词法分析只会将字符的源代码流分解为代表语言原子(单词)的标记流。
通常,词法分析器不会为语言构建符号表。
由于预处理器,C是相当特殊的情况。在读取预处理程序指令时,C预处理程序必须收集宏的名称及其对应的值。通常(可能会有所不同)C预处理器(至少是我们的,看到我的生物)通过将源分解为令牌流来操作,并处理那些以"#"开头的行中的令牌。 (例如预处理器线)。由于源流依赖于扩展宏,并且扩展宏需要预处理器知道它的扩展,因此预处理器在宏定义的全局范围内记录宏名称和宏体关联,因为它遇到这样的定义。它使用宏名称来扩展宏调用并评估它遇到的预处理器条件,因为它是lexing。但预处理器不构建任何其他符号表。忽略预处理器,通常在解析源文本后构建符号表,当然,如果编译器要进行任何类型的全局分析。如果编译器生成抽象语法树(AST),这是最简单的。有些编译器,特别是那些即时生成代码的编译器(现在很少见),可能会在解析和遇到应该进入范围的条目时构建符号表。
由于weak parsing technology的广泛使用,C编译器再次出现了一个常见的特殊情况。这种技术cannot distinguish, by pure parsing, certain obscure syntax (notably " X* Y; ")。为了区分这种情况,需要有关某些符号是否为类型声明的信息;具有弱解析技术的编译器然后将符号范围中至少类型名称的集合纠缠到解析过程中。这使得这种弱解析器的代码很难理解。所提供的链接清楚地表明,实际上并不需要纠缠,因此在精心设计的编译器中,一对一可以干净地将解析与符号表构造隔离开来。使用足够复杂的语言(如C ++),如果不解析整个源文本,就无法构建符号表。 "命名空间"的概念表示在源文件中的最后一个声明之前可能不会遇到命名空间的条目。在这种情况下,在处理完最后一个条目之前,无法完成该命名空间的内容(显然是符号范围)。
如果这一切看起来都很混乱,那就是。您要问的是一个必须解决数百种编程语言问题的一般性问题,其中很多都有关于何时定义符号以及如何使用它们来解释其余程序源文本的奇怪规则。
最终摘要: