编译中的声明捕获阶段
本文关键字:声明 编译 | 更新日期: 2023-09-27 18:31:13
C和C++这样的语言依赖于前向声明来解决类型或函数声明中的循环依赖关系。在 C# 中,不再需要这样做,因为声明捕获阶段分为两个阶段;一个捕获符号名称,另一个实际执行符号声明构造。
符号名称捕获阶段是否有标准名称? 我假设声明捕获将留给涉及解析声明中所有符号的传统阶段
C# 编译器实际上有一个声明阶段,用于生成符号表。Roslyn C# 编译器不是那么清楚,因为并非所有内容都是在大型扫描阶段完成的。相反,每个符号都是按需单独构建的。但是,仍然有一个步骤将语法中的类型和成员声明转换为符号。绑定阶段在逻辑上是在此之后,其中对类型和成员名称的引用使用声明的符号表进行解析。
我认为这两个阶段被称为
- 解析
- 捆绑
解析是语法的。绑定是为标识符和名称赋予含义。
C++也可以这样做。它只是被定义为不。
在.Net 5中,Microsoft将引入Roslyn,编译器即服务。Roslyn 的此概述将编译器在代码生成之前的三个步骤描述为:词法分析、句法分析和语义分析。Roslyn项目的概述证实了这些描述,但语言不太精确。
我找到了Eric Lippert的这篇博客文章,它对我正在寻找的内容给出了最好的解释:
C# 语言不要求声明在 用法,再次对用户和编译器产生两种影响 作家。对用户的影响是,您不能重新编译 更改文件时更改的 IL;整个组件是 重新 编译。幸运的是,C# 编译器的速度足够快,以至于 很少是一个大问题。(另一种看待这个问题的方法是 C# 中重新编译的"粒度"是在项目级别,而不是 文件级别。
对编译器编写器的影响是我们必须有一个"两遍" 编译器。在第一遍中,我们查找声明并忽略 机构。一旦我们从声明中收集了所有信息 我们会从C++的头球中得到的,我们进行第二次传球 并生成正文的 IL。
。
然后,我们进行"声明"传递,在其中记录有关 程序中每个命名空间和类型声明的位置。在 在这一点上,我们已经完成了第一阶段的源代码; 随后的每一次传递都超过了从 声明。
然后,我们执行一个传递,验证所有声明的类型都没有 循环的基本类型。我们需要首先这样做,因为在每一个 后续传递我们需要能够在没有 必须处理周期。
http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx