引导编译器:为什么?

时间:2009-09-29 16:53:25

标签: compiler-construction theory bootstrapping

我理解一种语言如何自我引导,但我无法找到关于为什么你应该考虑引导的很多参考。

直观的答案是,您正在编写的语言提供了编译器“基本”语言中没有的实用程序,语言的功能相对非常适合编译器。

例如,引导C ++编译器是有意义的 - 在正确使用OOP时,维护编译器可能要容易得多,而不是使用普通的C.

另一方面,MATLAB确实使矩阵数学比普通的C容易得多,但我在MATLAB中编写MATLAB编译器/解释器看不出任何明显的好处 - 看起来它会变得更少可维护。类似的视图可以应用于R编程语言。或者一个非常极端的例子是bootstrapping Whitespace,它是用Haskell编写的 - 绝对是一个巨大的超级空白空间集。

引导的唯一原因是利用新语言的功能吗?我知道还有“因为我们可以”的理由,但这不是我想要的:)

11 个答案:

答案 0 :(得分:30)

有一种叫做“吃自己的狗食”的原则。通过使用工具,您可以证明该工具的实用性。

人们经常会问,“如果语言X的编译器不是用X语言编写的,我为什么要冒险使用它呢?”

这当然仅适用于适合编译器编写领域的语言。

答案 1 :(得分:13)

引导语言实现有两个主要优点:首先,正如您所建议的那样,在实现中利用所述语言的高级功能。但是,一个不太明显但同样重要的优点是,它允许您自定义和扩展语言,而不会陷入用C语言编写的较低层(或Java,或者新语言运行时下面的任何内容)。

元编程可能对大多数日常任务没有用,但有时它可以为您节省大量的重复或样板代码。能够在高级语言中连接到编译器和核心运行时,可以使高级元编程任务变得更加容易。

答案 2 :(得分:10)

Ken Thompson的Reflections on Trusting Trust解释了引导的最佳原因之一。从本质上讲,您的编译器会在引导链中为每个版本的编译器学习新的东西,您将永远不必再教它。

在他提到的情况下,您编写的第一个编译器(C1)必须明确告知如何处理反斜杠转义。但是,第二个编译器(C2)是使用C1编译的,因此本机处理反斜杠转义处理。

他演讲的基石是你可以教一个编译器为程序添加一个后门程序的可能性,并且使用被攻陷的编译器编译的未来编译器也将被赋予这种能力,并且它永远不会出现在源<!/ em>的

基本上,您的程序可以在每个编译周期学习新功能, 不必在以后的编译周期中重新实现或重新编译 ,因为编译器已经知道所有这些

花一点时间意识到这些后果。

[edit]:这是构建编译器的非常糟糕的方法,但很酷的因素是通过屋顶。我想知道它是否可以通过正确的框架进行管理?

答案 3 :(得分:9)

可以将“玩具”语言与“真实”语言区分开来。如果语言不够丰富,无法实现,那它仍然是一个玩具。但考虑到今天用C语言实现的流行语言数量,这可能是一个过去时代的态度。

答案 4 :(得分:7)

一个优点是,开发编译器的开发人员只需要知道正在编译的语言。否则,开发人员需要知道正在编译的语言以及编译器编写的语言。

答案 5 :(得分:4)

编译器解决各种各样的重要问题,包括字符串操作,处理大型数据结构以及与操作系统连接。如果您的语言旨在处理这些事情,那么用您的语言编写编译器就可以演示这些功能。此外,它会产生指数效应,因为当您的语言包含更多功能时,您可以在编译器中使用更多功能。如果您实现任何可以简化编译器编写的独特功能,那么您可以使用这些新工具来实现更多功能。

但是,如果您的语言不是为了处理与编译相同的问题,那么引导只会诱使您使用与编译相关但与目标问题无关的功能来混淆您的语言。使用Matlab或SQL进行自编译会很荒谬; Matlab没有理由包含强字符串操作函数,SQL没有理由支持代码生成。由此产生的语言将是不必要和混乱的。

值得注意的是,解释型语言的问题略有不同,应予以相应处理。

答案 6 :(得分:3)

低级语言经常被引导,因为为了将代码放在新系统上,你需要一个低级编译器。获取C编译器,现在您可以使用大量代码。使用自举编译器可以简化这一过程,只需要存在自己的代码即可编译和改进自己的代码。

还有其他方法可以实现这一点,比如制作交叉编译器,在大多数系统上,你不需要在普通使用中在设备上编译静态语言(事实上,像Windows这样的系统没有编译器)

编译器经常引导的另一个原因是它们不必担心编译它们的编译器中的错误。确保您的编译器可以自己编译,并限制在使用其他编译器编译时可能出现的错误组合。

我认为引导高级语言主要是为了展示一个人毛茸茸的编程技巧。

答案 7 :(得分:2)

您没有为DSL编译编译器。您不在SQL中编写SQL查询编译器。 MATLAB可能看起来像一种通用语言,但实际上它不是 - 它是一种专为数值计算而设计的语言。

答案 8 :(得分:2)

Bootstrapping还有另一个优点:如果您的语言很好,您可以通过在&lt; insert language here&gt;中编写编译器来节省时间。例如,C#编译器是用C ++编写的,但现在它们用C#重写它,这允许它们(除其他外)使用CLR中的线程框架而不是在C ++中自己编译(并且跟随Mono家伙的领导,营销明智,Mono处于更好的位置,能够说我们的C#编译器实际上是用C#编写的。

答案 9 :(得分:2)

作为一个具体的例子,在version 1.5(2015年8月发布)中,Go转变为完全引导语言 [1] [2] 。他们列出了以下原因:

  • Go比C更容易编写(正确)。
  • Go比C更容易调试(即使没有调试器)。
  • 围棋是你唯一需要知道的语言;鼓励捐款。
  • Go具有更好的模块化,工具,测试,分析......
  • Go使并行执行变得微不足道。

其中,唯一适用于所有语言的是,您只需要知道一种语言就可以为编译器做出贡献。其他论点可以概括为&#34;我们的新语言比旧语言更好&#34;。哪个应该是真的,为什么还要写一种新语言?

答案 10 :(得分:1)

理论上,您可能有几个原因需要这样做:

  1. 您的编译器会产生更多 优化代码比其他编译器 在bootstrap平台上。
  2. 您的编译器生成更正确的 代码比其他编译器上的 引导平台。
  3. 你是个自负的混蛋 确信上述之一是 即使不是,也是如此。
  4. 没有可用的编译器 你的平台(这是GCC的 原始逻辑,因为很多 平台没有C编译器 回到白天)。
  5. 你想证明你的编译器 可以处理它(毕竟,这对编译器来说实际上是一个非常好的测试)。