简短的答案是:您猜对了,总是需要另一个用X编写的解释器,或者是从Y到已经具有解释器的某种其他语言的编译器。解释器执行,编译器只能从一种语言翻译成另一种语言,在系统中的某个时候,必须有一个解释器…即使是CPU。
不管您用语言Y编写了多少新的解释器,您始终将必须使用用X编写的第一个解释器来解释后续的解释器。仅仅由于口译员的性质,这似乎是一个问题。
正确。您可以做的是将编译器从Y编写为X(或您拥有解释器的另一种语言),甚至可以在Y中进行编译。然后你可以运行你的Ÿ编译器写在Ÿ在Ÿ解释写在X(或在ÿ解释写在Ÿ在运行Ÿ解释写在X,或在ÿ写在解释Ÿ在运行Ÿ解释写在Ÿ在运行ÿ用X编写的解释器,或…ad infinitum)将用Y编写的Y解释器编译为X,以便您可以在X解释器上执行它。这样,您就摆脱了用X编写的Y解释器,但是现在您需要X解释器(但是我们知道我们已经有了一个,因为否则我们将无法运行用Y编写的X解释器),并且您必须先编写一个Y到X的编译器。
但是,另一方面,Wikipedia上有关口译员的文章实际上讨论的是自托管口译员。这是一个相关的小摘录:
自解释器是用一种可以解释自身的编程语言编写的编程语言解释器;一个例子是用BASIC编写的BASIC解释器。自解释器与自托管编译器有关。
如果不存在用于要解释的语言的编译器,则创建自解释器需要使用宿主语言(可以是另一种编程语言或汇编程序)来实现该语言。通过拥有这样的第一个解释器,系统将被引导,并且可以使用语言本身开发新版本的解释器
不过,对于我来说仍然不清楚如何完成此操作。看来,无论如何,您总是被迫使用以宿主语言编写的解释器的第一个版本。
正确。请注意,Wikipedia文章明确指出您需要语言的第二种实现,但并没有说您可以摆脱第一种实现。
现在,上面提到的文章链接到另一篇文章,其中Wikipedia提供了一些假定的自我托管解释器的示例。经过仔细检查,似乎许多这些自托管解释器(尤其是一些较常见的解释器,例如PyPy或Rubinius)的主要“解释”部分实际上是用其他语言编写的,例如C ++或C。
同样,正确。这些确实是不好的例子。以Rubinius为例。是的,Rubinius的Ruby部分是自托管的,但这确实是编译器,而不是解释器:它可以将Ruby源代码编译为Rubinius字节码。解释器部分OTOH并不是自托管的:它解释Rubinius字节码,但是它是用C ++编写的。因此,将Rubinius称为“自托管解释器”是错误的:自托管部分不是解释器,而解释器部分也不是自托管。
PyPy与之类似,但更不正确:它最初不是用Python编写的,而是用另一种语言的RPython编写的。它在语法上类似于Python,在语义上是“扩展子集”,但实际上是一种与Java处于相同抽象级别的静态类型语言,其实现是具有多个后端的编译器,可将RPython编译为C源代码ECMAScript。源代码,CIL字节代码,JVM字节代码或Python源代码。
那我上面描述的可能吗?自宿主解释器可以独立于其原始宿主吗?如果是这样,将如何精确地做到这一点?
不,不是靠自己。您要么需要保留原始解释器,要么编写一个编译器并编译您的自解释器。
这里是一些元圆形的虚拟机,如克莱因(写在自我)和玛克辛(用Java编写的)。但是请注意,这里的“元圆”定义是不同的:这些VM并不是用它们执行的语言编写的:Klein执行Self字节代码,但以Self编写,Maxine执行JVM字节代码,但以Java编写。但是,VM的Self / Java源代码实际上会被编译为Self / JVM字节码,然后由VM执行,因此,在执行VM时,它是使用其执行的语言。ew
还要注意,这与诸如SqueakVM和Jikes RVM之类的 VM不同。Jikes用Java编写,SqueakVM用Slang(Smalltalk的静态类型化语法和语义子集,与高级汇编程序大致处于同一抽象级别)编写,并且两者都在运行之前被静态编译为本机代码。他们不会在自己内心奔跑。但是,您可以在自己之上(或在另一个Smalltalk VM / JVM 之上)运行它们。但是,从这个意义上讲,这不是“元圆形”。
Maxine和Klein,OTOH 做在自己内心奔跑;他们使用自己的实现来执行自己的字节码。这是真正的弯腰!它提供了一些很酷的优化机会,例如,由于VM与用户程序一起执行自身,因此它可以内联从用户程序到VM的调用,反之亦然,例如可以将对垃圾回收器或内存分配器的调用内联到用户中代码,并且用户代码中的反射性回调可以内联到VM中。此外,现代VM会执行所有聪明的优化技巧,它们会监视执行程序并根据实际工作量和数据对其进行优化,因此VM可以在执行用户程序时将这些相同的技巧应用于自身,而用户程序正在执行特定的工作负载。换言之,虚拟机高度专业化的本身是特定的程序运行的是特定的工作负载。
但是,请注意,我绕过上面的“解释器”一词的使用,而总是使用“执行”吗?嗯,这些VM不是围绕解释器构建的,而是围绕(JIT)编译器构建的。有加入玛克辛后来的解释,但你总是需要编译器:你必须运行VM 一次上(在玛克辛的情况下,如Oracle的HotSpot)另一个虚拟机之上,以便VM可以(JIT)编译本身。对于Maxine,它将JIT编译自己的启动阶段,然后将编译后的本机代码序列化为引导VM映像,并在前面放置一个非常简单的bootloader(VM用C语言编写的唯一组件,尽管这只是为了方便起见)。 ,也可以在Java中使用)。现在,您可以使用Maxine自行执行。