【问题标题】:Bootstrapping a compiler: why?引导编译器:为什么?
【发布时间】:2010-12-02 09:35:18
【问题描述】:

我了解一种语言如何自举,但我找不到太多关于为什么应该考虑自举的参考资料。

直观的答案是,您正在编写的语言提供了在编译器的“基础”语言中找不到的实用程序,并且该语言的功能相对适合编译器。

例如,引导 C++ 编译器是有意义的——当正确使用 OOP 时,与使用纯 C 相比,维护编译器可能更容易。

另一方面,MATLAB 确实使矩阵数学比普通 C 容易得多,但我看不到在 MATLAB 中编写 MATLAB 编译器/解释器有任何明显的好处——它似乎会变得 less 可维护。类似的观点可以应用于 R 编程语言。或者一个非常极端的例子是引导 Whitespace,它是用 Haskell 编写的——绝对是一个巨大的super空白集。

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

【问题讨论】:

  • 空白实际上是相当可维护的。你只需要使用语法高亮。 :)

标签: compiler-construction theory bootstrapping


【解决方案1】:

有一个原则叫做“吃你自己的狗粮”。通过使用工具,您可以展示该工具的实用性。

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

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

【讨论】:

  • 我认为我使用过的每一种好的语言都是结合使用它的程序设计和编写的。有时它是它自己的编译器,有时不是,但编译器是一个很好的第一个案例。除了立即有用之外,编译器还是一个非常复杂的程序(或者可以是),如果您可以编写自己的编译器,它可能会在早餐时解决更简单的问题!
【解决方案2】:

它可以被认为是区分“玩具”语言和“真实”语言的酒吧。如果语言不够丰富而无法实现自身,它仍然是一个玩具。但考虑到当今使用 C 实现的流行语言的数量,这可能是一个很大程度上已经过去的时代的态度。

【讨论】:

  • 我不同意“玩具”与“真实”的分类。语言是有目的的。有些是通用语言,如 C、VB 等,可用于发明自己。其他的,如 MATLAB,专门用于解决特定类别的问题。这不会使它们成为“玩具”语言,只是专门化的。
  • 一种语言甚至不需要图灵完备就可以自行引导,因此门槛非常低。
【解决方案3】:

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

【讨论】:

  • 虽然我不认为这没什么大不了的。通常,编译器编写者应该知道很多很多语言(或者实际上,任何计算机科学家)。
  • 您可能会感到惊讶。我会说几种语言,但是当我不得不尝试维护一个记录在我最熟悉的两种语言(英语和德语)中的系统时,我发现它至少比完全用英语维护一个系统要困难 10 倍。小的阻抗不匹配确实加起来了。
【解决方案4】:

自举语言实现有两个主要优点:首先,正如您所建议的,在实现中利用所述语言的高级特性。然而,一个不太明显但同样重要的优势是,它允许您自定义和扩展语言,而无需进入用 C(或 Java,或位于新语言运行时之下的任何东西)编写的较低层。

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

【讨论】:

    【解决方案5】:

    您不会为 DSL 引导编译器。您无需在 SQL 中编写 SQL 查询编译器。 MATLAB 可能看起来像一种通用语言,但实际上并非如此——它是一种专为数值计算而设计的语言。

    【讨论】:

      【解决方案6】:

      低级语言通常是自举的,因为为了将代码放到新系统上,您需要一个低级编译器。获取一个 C 编译器,现在您有大量代码可供使用。使用自举编译器可以更轻松地完成此操作,您只需要存在自己的代码即可编译和改进自己的代码。

      还有其他方法可以实现这一点,例如制作交叉编译器,在大多数系统上,您在日常使用中永远不需要能够在设备本身上编译静态语言(事实上,像 Windows 这样的系统没有编译器) .

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

      我认为引导高级语言主要是为了炫耀自己的编程技巧。

      【讨论】:

        【解决方案7】:

        Bootstrapping 还有另一个优点:如果你的语言很好,你可以用 编写编译器来节省时间,而不是用 C 编写。例如,C# 编译器是用 C++ 编写的,但现在它们是用 C# 重写它,这允许他们(除其他外)使用 CLR 中的线程框架,而不是在 C++ 中滚动他们自己的框架(并且在营销方面也遵循 Mono 人的领导,Mono 处于更好的位置可以说我们的 C# 编译器实际上是用 C# 编写的)。

        【讨论】:

          【解决方案8】:

          您可能想要这样做的原因有几个(理论上):

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

          【讨论】:

            【解决方案9】:

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

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

            还值得注意的是,解释型语言是一个稍微不同的问题,应该进行相应的处理。

            【讨论】:

              【解决方案10】:

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

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

              他演讲的基石是,你可以教编译器为程序添加后门,未来使用受感染的编译器编译的编译器也将被赋予这种能力,并且它永远不会出现在来源!

              本质上,您的程序可以在每个编译周期中学习新功能,不必在以后的编译周期中重新实现或重新编译,因为您的编译器已经了解它们.

              花一点时间了解后果。

              [编辑]:这是构建编译器的非常糟糕的方式,但最酷的因素是天翻地覆。我想知道它是否可以通过正确的框架进行管理?

              【讨论】:

                【解决方案11】:

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

                • Go 比 C 更容易(正确地)编写。
                • Go 比 C 更容易调试(即使没有调试器)。
                • Go 是您唯一需要了解的语言;鼓励贡献。
                • Go 具有更好的模块化、工具、测试、分析......
                • Go 让并行执行变得微不足道。

                其中,唯一适用于所有语言的是,您只需要了解一种语言即可为编译器做出贡献。其他论点可以概括为“我们的新语言比旧语言更好”。这应该是对的,否则你为什么要写一门新语言?

                【讨论】:

                  猜你喜欢
                  • 2014-09-13
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-11-19
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多