5

一段时间以来,我一直在使用 Ruby 进行编程,只使用 Ruby 的标准 MRI 实现,但我一直对其他我听到的很多实现感到好奇。

前几天我在阅读关于 Rubinius 的文章,这是一个用 Ruby 编写的 Ruby 解释器。我尝试在不同的地方查找它,但我很难弄清楚这样的东西到底是如何工作的。我在编译器或语言编写方面从来没有太多经验,但我真的很想弄清楚。

一种语言如何准确地被自己解释?编译中是否有一个基本步骤我不明白这在哪里有意义?有人可以像我是个白痴一样向我解释这一点(因为无论如何这不会太离谱)

4

5 回答 5

8

它比你想象的要简单。

Rubinius 不是 100% 用 Ruby 编写的,只是大部分情况下。

来自http://rubini.us/

C 和 Java 等流行语言的一个重要方面是程序员可用的大部分功能都是用语言本身编写的。Rubinius 的目标是将 Ruby 添加到该列表中。Rubyists 可以更轻松地为该语言添加功能、修复错误并了解该语言的工作原理。Rubinius 尽可能使用 Ruby 编写。在不可能的地方(还),它是 C++。

于 2010-05-30T06:08:14.107 回答
4

您正在寻找的概念是编译器引导

基本上,引导意味着用语言x为语言x编写编译器(或解释器)。这可以通过手工编写较低级别的基本编译器(即用汇编编写 C 编译器)或使用不同的高级语言来完成。

在wikipedia上阅读有关引导的更多信息。强烈推荐 Greg 关于元循环评估器的回答,包括 SICP 中的相关章节。

于 2010-05-30T12:50:37.263 回答
2

在 Rubinius 的情况下,VM 是用 C++ 编写的,并处理所有低级(操作系统相关)的东西和基本操作。VM 有自己的字节码格式(就像 JVM 也有自己的一样),当 Rubinius 启动时,它会启动执行字节码的 VM。然而,与 C (MRI) 或 Java (JRuby) 相比,Rubinius 的大部分标准库(它是 Ruby 语言的一部分)都是用 Ruby 实现的。此外,Rubinius 字节码编译器也是用 Ruby 编写的。所以是的,在早期的某个时候,他们不得不使用标准的 Ruby 解释器 (MRI) 来引导 Rubinius。但这不应该是这种情况了(尽管我不确定你是否仍然需要它,因为它的构建系统使用 rake)。

于 2010-05-30T12:39:39.017 回答
1

假设你正在使用的语言是某种语言,比如 Lisp,尽管这并不重要。(可以是 C++、Java、Ruby 等等。)

那么你有一个 Lisp 的实现。将此实现称为 Imp(只是 IMPlementation 的一些虚构名称)。由于 Imp 本身就是一个程序,因此您的计算机可以运行它。现在你为用 Lisp 编写的 Lisp 编写你自己的实现,你称之为 Circ。Circ 只是一个从 Lisp 代码编译(或解释)的程序。您的代码是这样编写的,因此它会读入一个文件,对其进行解析(将其处理为有意义的数据),然后对数据进行一些处理。这是什么东西?在 Circ 的情况下,它执行数据。

但它是如何做到的呢?

好吧,假设对于一个简单的情况,Circ 读取并解析的代码很简单,比如做一些数学运算并输出结果。Circ 将代码处理成易于使用的数据(对于像 Lisp 这样的语言来说,它很容易开始,但这已经超出了重点)并存储它。在 Lisp 中你可以编写代码来处理数字,所以为 Circ 编写的代码也可以这样做,因为它是用 Lisp 编写的。因此,处理后的数据被插入到一些附加处理代码中......瞧!你有数字结果!然后你的 Circ 程序输出结果。

同样的事情也可以用比简单数学更复杂的事情来完成。事实上,您可以编译/解释该语言的其他方面。编写足够多的这些“其他方面”并将它们粘合在一起,您将获得一个用 Lisp 编写的 Lisp 编译器。

由于编译器是 Imp 编译的,所以它可以在你的机器上运行,并且 presto!你完成了。

于 2010-05-30T06:27:25.820 回答
0

这种技术通常被称为元循环评估器,几十年前在 Lisp 的上下文中首次引入。

可以在计算机程序的结构和解释第 4 章中找到对该技术的一个很好的描述。

于 2010-05-30T06:21:18.607 回答