Compiler construction 引导仍然需要外部支持

Compiler construction 引导仍然需要外部支持,compiler-construction,bootstrapping,Compiler Construction,Bootstrapping,我听说过引导语言的想法,也就是说,为语言本身编写编译器/解释器。我想知道如何才能做到这一点,环顾四周,看到有人说,这只能由任何一方完成 用不同的语言编写初始编译器 在汇编中手工编写初始编译器,这似乎是第一个编译器的特例 在我看来,这两种语言都不需要外部支持,因此它们实际上都不是在引导一种语言。有没有办法用自己的语言编写编译器?我听说的方法是用另一种语言编写一个非常有限的编译器,然后用它来编译一个更复杂的版本,用新的语言编写。然后可以使用第二个版本编译自己,然后使用下一个版本。每次编译时都会使

我听说过引导语言的想法,也就是说,为语言本身编写编译器/解释器。我想知道如何才能做到这一点,环顾四周,看到有人说,这只能由任何一方完成

  • 用不同的语言编写初始编译器
  • 在汇编中手工编写初始编译器,这似乎是第一个编译器的特例

在我看来,这两种语言都不需要外部支持,因此它们实际上都不是在引导一种语言。有没有办法用自己的语言编写编译器?

我听说的方法是用另一种语言编写一个非常有限的编译器,然后用它来编译一个更复杂的版本,用新的语言编写。然后可以使用第二个版本编译自己,然后使用下一个版本。每次编译时都会使用最新版本

这就是

一个简单的系统激活一个更复杂的系统以达到相同目的的过程


编辑:这篇文章比我更好地阐述了这个概念。

您所阅读的解释是正确的。(龙书)中对此进行了讨论:

  • 用语言Y为语言X编写编译器C1
  • 使用编译器C1在语言X中为语言X编写编译器C2
  • 现在C2是一个完全自托管的环境

我能想到的(,)每一个引导语言的例子都是在有了一个可以工作的编译器之后完成的。您必须从某个地方开始,重新实现一种语言本身需要先用另一种语言编写编译器


否则它将如何工作?我认为,从概念上讲,不这样做是不可能的。

这是鸡和蛋悖论的计算机科学版本。我想不出不使用汇编或其他语言编写初始编译器的方法。如果可以做到的话,我应该Lisp也可以做到

事实上,我认为Lisp几乎可以胜任。退房根据这篇文章,Lisp eval函数可以在机器代码中实现,一个完整的编译器(用Lisp本身编写)于1962年在诞生。

Unix联合创建者的讲座非常有趣

他从以下几点开始:

我将要描述的是当编译器使用自己的语言编写时出现的许多“鸡和蛋”问题之一。在这里,我将使用C编译器中的一个特定示例

并继续说明他是如何编写Unix C编译器的一个版本的,该版本始终允许他在没有密码的情况下登录,因为C编译器将识别登录程序并添加特殊代码

第二种模式是针对C编译器的。替换代码是一个第一阶段自我复制程序,可将两个特洛伊木马插入编译器。这需要一个学习阶段,如第二阶段示例所示。首先,我们用普通的C编译器编译修改后的源代码,以生成一个有缺陷的二进制文件。我们将这个二进制文件安装为官方的C语言。我们现在可以从编译器的源代码中删除bug,并且新的二进制文件将在编译时重新插入bug。当然,login命令仍然会有bug,在任何地方的源代码中都没有跟踪

有没有办法用自己的语言编写编译器

您必须有一些现有的语言来编写新的编译器。如果你正在编写一个新的C++编译器,你可以先用C++编写它,然后用现有编译器编译它。另一方面,如果您正在为一种新语言创建编译器,我们称之为Yazzlof,那么您需要先用另一种语言编写新的编译器。一般来说,这将是另一种编程语言,但不一定是。它可以是汇编代码,也可以是机器代码(如有必要)

如果要为Yazzlof引导编译器,通常不会在开始时为完整语言编写编译器。相反,您应该为Yazzle lite编写一个编译器,它是Yazzleof的最小可能子集(至少是一个非常小的子集)。然后在Yazzle lite中,您将为完整的语言编写一个编译器。(显然,这可以迭代地发生,而不是一次跳转。)因为Yazzle lite是Yazzleof的一个适当子集,您现在有了一个可以自己编译的编译器


有一篇关于从最低级别(在现代机器上基本上是一个十六进制编辑器)引导编译器的非常好的文章,题为“从无到有引导一个简单的编译器”。另一种选择是为您的语言创建一个字节码机器(或者使用一个现有的机器,如果它的功能不是很特别的话),然后用字节码或使用另一种中间语言(例如以XML形式输出AST的解析器工具包)为字节码编写编译器,然后使用XSLT(或另一种模式匹配语言和基于树的表示)将XML编译成字节码。它不会消除对另一种语言的依赖,但可能意味着更多的引导工作最终会在最终的系统中完成

查看讨论GCC编译器内部以及GCC引导过程的播客(2007-07-06)。

据我所知,第一个解释器是通过手工编译构造函数和令牌读取器引导的。然后从源代码读入其余的解释器


您可以通过阅读麦卡锡的原始论文来检查自己。

实际上是通过在其中编写编译器构建的,然后手动将其编译为汇编或机器代码。

一些引导编译器或系统将源表单和对象表单保留在其存储库中:

  • 是一种既有字节码解释器(即Ocaml字节码的编译器)又有本机编译器(x86-64或ARM等)的语言。它的svn存储库c