我听说过引导一种语言的想法,就是为这种语言编写一个编译器/解释器.我想知道如何实现这一点,并且看了一下,看到有人说它只能通过其中任何一个来完成
用不同的语言编写初始编译器.
在Assembly中手动编写初始编译器,这似乎是第一个特例
对我来说,这些似乎都不是真正引导语言,因为它们都需要外部支持.有没有办法用自己的语言编写编译器?
有没有办法用自己的语言编写编译器?
你必须有一些现有的语言来编写你的新编译器.如果你正在编写一个新的,比如说C++编译器,你只需要用C++编写它,然后用现有的编译器编译它.另一方面,如果您正在为新语言创建编译器,我们称之为Yazzleof,您需要先用另一种语言编写新的编译器.通常,这将是另一种编程语言,但它不一定是.它可以是装配,也可以是机器代码.
如果你是要引导用于Yazzleof一个编译器,你一般不会写最初的全语言的编译器.相反,你会为Yazzle-lite编写一个编译器,这是Yazzleof的最小可能子集(至少是一个非常小的子集).然后在Yazzle-lite中,您将编写完整语言的编译器.(显然这可以迭代而不是一次跳转.)因为Yazzle-lite是Yazzleof的正确子集,所以现在你有一个可以编译自己的编译器.
关于从最低级别(在现代机器上基本上是一个十六进制编辑器)引导编译器有一个非常好的写法,标题为从无到有引导简单编译器.可以在https://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html找到它.
你读过的解释是正确的.在编译器中对此进行了讨论:原理,技术和工具(龙书):
在语言Y中为语言X编写编译器C1
使用编译器C1为语言X中的语言X编写编译器C2
现在C2是一个完全自托管的环境.
关于这一点的一个非常有趣的讨论是在Unix共同创作者Ken Thompson的图灵奖演讲中.
他开始时:
我要描述的是编译器用他们自己的语言编写时出现的许多"鸡和蛋"问题之一.在这方面,我将使用C编译器中的一个特定示例.
并继续展示他是如何编写一个Unix C编译器的版本,它总是允许他在没有密码的情况下登录,因为C编译器会识别登录程序并添加特殊代码.
第二种模式针对C编译器.替换代码是Stage I自我复制程序,它将两个特洛伊木马插入编译器.这需要一个学习阶段,如第二阶段的例子.首先,我们使用普通的C编译器编译修改后的源代码,以生成错误的二进制文件.我们将这个二进制文件作为官方C安装.我们现在可以从编译器源中删除错误,新的二进制文件将在编译时重新插入错误.当然,login命令将保持错误状态,并且在任何地方都没有跟踪源.
我听说过的方法是用另一种语言编写一个极其有限的编译器,然后使用它编译一个用新语言编写的更复杂的版本.然后可以使用第二个版本编译自己和下一个版本.每次编译时都会使用最后一个版本.
这是bootstrapping的定义:
一个简单的系统激活一个更复杂的系统,为同一目的服务的过程.
编辑:关于编译器引导的维基百科文章比我更好地涵盖了这个概念.