可能的重复:
在“自身”中实现编译器
引导语言
您如何使用与您编写该编译器的语言相同的语言编写编译器?那不是递归的吗?
编辑:这可能会被删除,但否则......:
如何引导:
为什么要引导:
通常,编译器的第一个版本是用不同的语言编写的,然后每个后续版本都用该语言编写并与旧版本一起编译。x
使用 version编译版本后x-1
,您可以使用新构建的版本x
重新编译自身,利用该版本引入的任何新优化;GCC 以这种方式发布
这是。您通常需要从另一种语言编译或解释的语言的引导版本。
为了让你多想一想,几年前我读了一篇作为研究生项目编写的 Pascal 编译器的历史。它是用 Pascal 编写的,并使用系统内置的 Pascal 编译器进行编译。最终,它足以替换系统内置的 Pascal 编译器。不幸的是,他们在代码生成中发现了一个错误,但是代码生成器的修复触发了编译器中的错误,生成了一个错误的编译器。要修复它,需要从已安装的编译器手动修补二进制文件,然后将修补程序应用于源以替换自身。
这只是有史以来第一个版本的问题。一旦我有编译器的 V1.0 工作,我可以用我的语言编写 V2.0 并使用 V1.0 编译器来编译它。然后我可以编写 V3.0 并使用 V2.0 编译它,使用 V3.0 编译 V4.0 等等。
编译器的第一遍通常是用其他东西编写的,直到语言的格式足够好,能够编译它自己的编译器,然后你就可以进入 x 是用 x 编写的。
一开始,该语言真正的第一个编译器当然不是用该语言编写的。第二个可以用那种语言写。此外,给定一种语言规范,您可以在引导编译器中实现基本核心,然后使用“引导”编译器理解的子集以该语言编写完全兼容的编译器。第二代编译器也可以忘记“引导”编译器。
在某些时候,您需要一个用不同语言编写的编译器(或解释器)。但它不需要高效,并且可以用一种易于解析和原型设计的语言来完成(LISP 很流行)。一旦你用它来编译“自编译器”,你可以丢弃它并使用结果。