直观地说,Foo语言的编译器本身似乎不能用Foo来编写。更具体地说,Foo语言的第一个编译器不能用Foo编写,但任何后续的编译器都可以为Foo编写。

但这是真的吗?我隐约记得读过一种语言,它的第一个编译器是用“自身”编写的。这可能吗?如果可能,如何实现?


当前回答

是的,你可以用一种语言编写编译器。不,你不需要第一个编译器来引导该语言。

您需要引导的是该语言的实现。它可以是编译器,也可以是解释器。

历史上,语言通常被认为是解释语言或编译语言。解释器只为前者编写,编译器只为后者编写。所以通常,如果要为一种语言编写编译器,第一个编译器会用其他语言编写以引导它,然后,可选地,编译器会为主题语言重新编写。但是用另一种语言编写解释器也是一种选择。

这不仅仅是理论上的。我自己也在做这件事。我正在为自己开发的语言Salmon编写编译器。我首先用C创建了一个Salmon编译器,现在我正在用Salmon编写编译器,所以我可以让Salmon编译器工作,而不需要用任何其他语言为Salmon编写编译器。

其他回答

是的,你可以用一种语言编写编译器。不,你不需要第一个编译器来引导该语言。

您需要引导的是该语言的实现。它可以是编译器,也可以是解释器。

历史上,语言通常被认为是解释语言或编译语言。解释器只为前者编写,编译器只为后者编写。所以通常,如果要为一种语言编写编译器,第一个编译器会用其他语言编写以引导它,然后,可选地,编译器会为主题语言重新编写。但是用另一种语言编写解释器也是一种选择。

这不仅仅是理论上的。我自己也在做这件事。我正在为自己开发的语言Salmon编写编译器。我首先用C创建了一个Salmon编译器,现在我正在用Salmon编写编译器,所以我可以让Salmon编译器工作,而不需要用任何其他语言为Salmon编写编译器。

请注意,从技术上讲,您可以用一种仍然不存在的语言编写编译器。为了做到这一点,你创建了一个解释器,它是原始语言的一个下级,通常是缓慢和无用的,因为它在执行任何东西之前解释语言的每个语句。

如果你阅读它,它看起来确实完全像预期的语言,但它的执行要经过一些过程,将其转换为可执行的不止一个步骤。

这个编译器通常非常慢,因为它使用了一些适用于几乎所有现有语言的通用数学过程,但优点是下次除了在现有代码上使用生成的编译器外,什么也不用做。

当然这一次不需要解释。

这是一个dump(实际上很难搜索的话题):

闲聊 C

这也是PyPy和Rubinius的想法:

(我想这也适用于Forth,但我对Forth一无所知。)

一般来说,你需要先让编译器工作(如果是原始的),然后你才能开始考虑让它自托管。在某些语言中,这实际上被认为是一个重要的里程碑。

从我对“mono”的印象来看,他们很可能需要给反射添加一些东西来让它工作:mono团队一直指出,有些东西根本不可能用reflection . emit;当然,微软团队可能会证明他们错了。

这有一些真正的优点:对于初学者来说,这是一个相当好的单元测试!你只需要担心一种语言(也就是说,c#专家可能不太懂c++;但是现在你可以修复c#编译器)。但我想知道,这里是否存在某种职业自豪感:他们只是希望它能够自我托管。

不完全是编译器,但我最近一直在研究一个自托管系统;代码生成器用于生成代码生成器…所以如果模式改变了,我简单地运行它本身:新版本。如果有错误,我就返回到早期版本并重试。非常方便,也很容易维护。


更新1

我刚刚看了Anders在PDC的视频,(大约一个小时后)他给出了一些更合理的理由——都是关于编译器即服务的。只是为了记录。

也许你可以用BNF来描述BNF。