【问题标题】:In which language is the C# compiler written?C# 编译器是用哪种语言编写的?
【发布时间】:2015-02-15 06:31:41
【问题描述】:

我查看了http://referencesource.microsoft.com/ 的源代码,似乎所有源代码都在 C# 中。

我还查看了新 C# 编译器平台 (Roslyn) 的源代码,它也是 C# 中的。这怎么可能? C# 语言编译器是用 C# 编写的吗?还是我错过了一些明显的东西?如果 C# 编译器是用 C# 编写的,那么它是如何工作的?

【问题讨论】:

  • 许多编译器是用它们编译的语言编写的 - Google bootstrapping 了解更多信息。
  • 我认为 original 编译器是用 C++ 编写的。
  • 嗯,一个锤子可以用另一个锤子来锻造。以前的版本...
  • 您发布的链接是框架库的源代码链接,而不是编译器。

标签: c# compiler-construction roslyn


【解决方案1】:

最初的 C# 编译器不是用 C# 编写的,而是用 C 和 C++ 编写的。新的 Roslyn 编译器是用 C# 编写的,但最初是使用旧编译器编译的。新编译器完成后,就可以编译自己的源代码:这称为bootstrapping

【讨论】:

  • 那么当必须对“原始编译器”进行更改时,是否必须使用旧编译器编译(用C,C++编写)?跨度>
  • “原始编译器”无需更改,新版本将被修改
  • @CriketerOnSO,新编译器将替换旧编译器,因此无需修改旧编译器。但如果 MS 想这样做,他们会像以前那样用 C++ 编译器重新编译旧的编译器。
  • @ThomasLevesque 自托管是引导的最终结果。
  • @SriramSakthivel,编译器的代码不能使用新关键字,至少在有理解它们的编译器之前不能。您总是使用旧版本的编译器来构建新版本。
【解决方案2】:

编译器是实用程序 - 它们将编程语言文本转换为机器代码。如果编程语言描述的软件恰好是编译器.....

编译器还可以为其他架构生成机器代码。例如,Apple 使用基于 Intel 的服务器机架编译 iOS。编译器不必运行它生成的 ARM 代码,只需将其写入磁盘即可。

编译器 2.0 必须用编译器 1.0 可以处理的语言编写,但它肯定可以创建具有更新功能(如优化)的编译器 2.0。然后,您可以使用编译器 2.0 重新编译源代码并制作更好的版本。同样,编译器不知道它正在制作另一个版本的自己。

如果我们回到时间的迷雾中足够远,那么我们确实会到达没有编译器的地步——高级语言的第一次迭代。然后我们必须拿出铅笔和操作码书并在汇编中编写第一个。我们是如何编写第一个汇编程序的?直接输入机器代码,可能在打孔纸带上,或前面板上的翻转开关。

【讨论】:

  • 纸带只是通过纸上的孔翻转开关。 :-)
  • 纸带作为一种存储技术将永远起飞。它太复杂且容易出错,而且如果阅读器短路,它很容易烧毁,这会彻底破坏你的程序。
【解决方案3】:

编译器只是一个程序,就像任何其他程序一样。它没有什么神奇或特别之处。它需要一些输入并产生一些输出。在这种特殊情况下,输入恰好是 C#,输出恰好是 CIL,但这与输入是一系列纳税申报表和输出是报告没有什么不同。

【讨论】:

  • 不一样——它更容易,-)。
  • @PeterSchneider:人们喜欢把编译器当作神话般的魔法生物,但归根结底,它们只是将输入转换为输出的程序。地球上几乎每个程序都会解析一些输入,试图理解它,并将其转化为一些输出。从某种意义上说,每个输入都是用某种语言编写的程序,每个程序都是一个编译器。
  • 我完全同意。我只想说,税法是一团糟。相比之下,形式语言通常以适合自动化的方式很好地定义。这使得一个简单的编译器可以说比处理税收的程序更容易编写。尽管 Eric Lippert 可能会不同意 C# 编译器,但请参阅。 blogs.msdn.com/b/ericlippert/archive/2010/02/04/…。来自一次性 C 编译器。
  • @PeterSchneider:啊,对不起,我把你的评论误解了 180° :-D
  • 我最喜欢这个答案,因为它最直接地解决了 OP 的想法。它清除了围绕“全能”编译器的迷雾。
【解决方案4】:

你用任何可用的语言编写一种语言,并为它创建一个新的编译器。现在这个程序我们可以称之为 C# Compiler V 1.0 能够读取和编译具有当前保留字集的任何 C# 代码。现在,你说,好吧,我想介绍一个以前不存在的新功能,比如 where 语句。好的,您使用 C# Compiler V 1.0,它显然在任何地方都没有 where 语句,并将代码编译成新版本的 C# Compiler V 2.0。

您可能会在这里问:但是等等,C# Compiler V 1.0 中没有 where 语句。现在,编译器是如此的野兽,它完成了一项非常具体的工作,你不需要超过 C# 所能提供的 20% 的功能。当然,有时考虑像 yield 这样的新功能很棘手,但除非 yield 用更简单的术语表达,否则无论如何你都无法轻松实现它您使用的编译语言。

一旦您的 C# Compiler V 2.0 创建完成,即使您不需要 where 语句并且它甚至可能没有在 C# Compiler V 2.0 的代码中的任何地方使用,您仍然可以使用重新编译它您的新编译器和从 C# Compiler V 2.0 的 C# Compiler V 2.0 代码生成的 C# Compiler V 2.0 是您的新 C# Compiler V 2.0 编译器。

在您执行此操作之前,因为您的新编译器可以理解新语法,您有权调整编译器代码本身并添加任何可以编译到其中的内容,如果您认为它会改进任何内容。但是,新语法可以改进编译器本身的可能性很小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    • 2015-12-28
    • 2018-12-26
    • 1970-01-01
    • 2011-03-01
    • 2011-07-16
    • 2011-03-20
    相关资源
    最近更新 更多