3

像 C 和 C++ 这样的语言依赖前向声明来解决类型或函数声明中的循环依赖关系。在 C# 中,这不再是必需的,因为声明捕获阶段分为两个阶段;一个捕获符号名称,另一个实际执行符号声明构造。

符号名称捕获阶段是否有标准名称?我会假设声明捕获将留给涉及解析声明中的所有符号的传统阶段

4

4 回答 4

2

C# 编译器实际上有一个声明阶段,它在其中构建符号表。Roslyn C# 编译器不是很清楚,因为并非所有事情都是在大范围的扫描阶段完成的。相反,每个符号都是根据需要单独构建的。但是,仍然需要将语法中的类型和成员声明转换为符号的步骤。绑定阶段在逻辑上紧随其后,使用声明的符号表解析对类型和成员名称的引用。

于 2012-04-17T00:20:56.930 回答
1

我认为这两个阶段被称为

  1. 解析
  2. 捆绑

解析是句法。绑定是为标识符和名称赋予意义。

C++ 也可以这样做。它只是被定义为不。

于 2012-04-13T16:11:07.817 回答
0

我发现了 Eric Lippert 的这篇博客文章,它对我正在寻找的东西给出了最好的解释:

C# 语言不要求在使用之前进行声明,这对用户和编译器编写者有两个影响。对用户的影响是,您不会只重新编译更改文件时更改的 IL;重新编译整个程序集。幸运的是,C# 编译器足够快,这很少是一个大问题。(另一种看待这一点的方式是,C# 中重新编译的“粒度”是在项目级别,而不是文件级别。)

对编译器编写者的影响是我们必须有一个“两遍”编译器。在第一遍中,我们寻找声明并忽略正文。一旦我们从 C++ 中的头文件中获得的声明中收集了所有信息,我们对代码进行第二次遍历并为主体生成 IL。

...

然后,我们执行“声明”传递,在其中记录程序中每个命名空间和类型声明的位置。至此,我们已经完成了第一阶段的源代码的查看;随后的每一次传递都超过了从声明中推导出的一组“符号”。

然后我们进行一次验证,验证所有声明的类型在其基本类型中没有循环。我们首先需要这样做,因为在随后的每一次传递中,我们都需要能够向上遍历类型层次结构,而不必处理循环。

http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx

于 2012-04-26T20:24:12.280 回答
0

微软将在 .Net 5 中引入 Roslyn,即编译器即服务。Roslyn 的这份概述将编译器在代码生成之前的三个步骤描述为:词法分析、句法分析和语义分析。Roslyn 项目的概述证实了这些描述,但语言不太精确。

于 2012-04-13T17:59:16.530 回答