【问题标题】:How can a language's compiler be written in that language? [duplicate]一种语言的编译器如何用该语言编写? [复制]
【发布时间】:2011-03-01 05:42:05
【问题描述】:

可能的重复:
implementing a compiler in “itself”
Bootstrapping a language

如何使用与您编写该编译器的语言相同的语言编写编译器?那不是递归的吗?

编辑: 这可能会被删除,但除此之外......:

如何引导:

为什么引导:

【问题讨论】:

标签: compiler-construction recursion bootstrapping


【解决方案1】:

通常,编译器的第一个版本是用不同的语言编写的,然后每个后续版本都是用该语言编写的,并与旧版本一起编译。一旦你编译了版本x 和版本x-1,你可以使用新构建的版本x 重新编译自己,利用该版本引入的任何新优化; GCC 就是这样发布的

【讨论】:

  • +1 我用 JAVA 构建了一个简单的 Lisp 解释器。
  • 那么...为什么不能只使用编译器的第一个版本?为什么需要双级编译器?
  • @froadie 你的意思是为什么不用版本 1 编译每个版本?通常,新版本的编译器会比以前的版本生成更好的机器代码,因此使用最新版本构建将使编译器本身尽可能快/高效。此外,如果语言本身正在发生变化,并且您想在编译器的源代码中使用这些新功能,则需要使用更新的版本进行构建
  • @MichaelMrozek 太酷了,你是说所有语言都源自汇编?
  • @froadie 看到这个q bootstrapping-a-compiler-why?
【解决方案2】:

是的。您通常需要从另一种语言编译或解释的语言的引导版本。

为了让你多想想,几年前我读了一篇作为研究生项目编写的 Pascal 编译器的历史。它是用 Pascal 编写的,并使用系统内置的 Pascal 编译器进行编译。最终,它足以替换系统内置的 Pascal 编译器。不幸的是,他们在代码生成中发现了一个错误,但是代码生成器的修复触发了编译器中的错误,生成了一个错误的编译器。要修复它,需要从已安装的编译器手动修补二进制文件,然后将补丁应用到源以替换自身。

【讨论】:

  • 我发现这个问题想知道在这种错误情况下会做什么。我没有想到手动修补。好笑的故事。哈哈
【解决方案3】:

这只是第一个版本的问题。一旦我有编译器的 V1.0 工作,我可以用我的语言编写 V2.0 并使用 V1.0 编译器来编译它。然后我可以写V3.0,用V2.0编译,用V3.0编译V4.0等等。

【讨论】:

  • 您的意思是 V0.1 吗?第一个版本将缺少重要功能,不符合 1.0 的要求
【解决方案4】:

编译器的第一遍通常是用其他东西编写的,直到语言的格式足够好,可以编译它自己的编译器,然后你就可以进入 x 是用 x 编写的。

【讨论】:

    【解决方案5】:

    在一开始,该语言真正的第一个编译器当然不是用该语言编写的。第二个可以用那种语言写。此外,给定一种语言规范,您可以在引导编译器中实现基本核心,然后使用“引导”编译器理解的子集以该语言编写完全兼容的编译器。第二代编译器也可以忘记“引导”编译器。

    【讨论】:

      【解决方案6】:

      在某些时候,您需要一个用不同语言编写的编译器(或解释器)。但它不需要高效,并且可以用一种易于解析和原型设计的语言来完成(LISP 很流行)。一旦你用它编译了“自编译器”,你可以丢弃它并使用结果。

      【讨论】:

      • 不一定。第一个“编译器”也可以是人类,在这种情况下,您根本不需要使用其他语言的引导编译器。这就是 Niklaus Wirth 的大多数语言的第一个编译器的编写方式:他基本上将它们分配给他的学生 :-)
      猜你喜欢
      • 2011-05-15
      • 2015-02-15
      • 2011-07-16
      • 2014-02-11
      • 1970-01-01
      • 2011-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多