我听说过“自举语言”的概念,即使用该语言编写其自身的编译器/解释器。我想知道如何实现这一点,搜索了一下,看到有人说只能通过以下两种方式之一实现:
- 使用其他语言编写初始编译器。
- 手动使用汇编语言编写初始编译器,这似乎是第一种情况的特例。
对我来说,这两种方法都不像真正的“自举”,因为它们都需要外部支持。是否有一种方法可以真正地使用该语言编写编译器?
我听说过“自举语言”的概念,即使用该语言编写其自身的编译器/解释器。我想知道如何实现这一点,搜索了一下,看到有人说只能通过以下两种方式之一实现:
对我来说,这两种方法都不像真正的“自举”,因为它们都需要外部支持。是否有一种方法可以真正地使用该语言编写编译器?
您所读的解释是正确的。在 编译原理(龙书)中有这方面的讨论:
编辑:维基百科关于编译器引导的文章比我解释得更好。简单系统启动具有相同目的的更复杂系统的过程。
一个超级有趣的讨论在Unix的共同创始人Ken Thompson的Turing奖演讲中。
他开始说:
我即将描述的是编译器用其自身语言编写时出现的许多“鸡生蛋”问题之一。在这种情况下,我将使用C编译器的一个具体示例。
然后他展示了如何编写一个版本的Unix C编译器,该编译器总是允许他无需密码登录,因为C编译器会识别登录程序并添加特殊代码。
第二种模式针对C编译器。替换代码是一个自我复制的一阶段程序,将两个特洛伊木马插入编译器中。这需要像第二阶段示例中那样的学习阶段。首先,我们使用普通的C编译器编译修改后的源代码以生成有缺陷的二进制文件。我们将此二进制文件安装为官方C。现在,我们可以从编译器的源代码中删除错误,并且新的二进制文件将在每次编译时重新插入错误。当然,登录命令将保留错误,而在任何源代码中都没有痕迹。另一种选择是为您的语言创建一个字节码机器(如果它的特性不是非常不寻常,也可以使用现有的字节码机器),并编写一个编译器将源代码编译成字节码。编译器可以在字节码中实现,或者使用其他中间件(例如将AST作为XML输出的解析器工具包),然后使用XSLT(或其他基于模式匹配语言和基于树的表示)将XML编译为字节码。这并不能消除对另一种语言的依赖,但可以使更多的引导工作最终集成到系统中。