有没有一种解释型语言可以动态修改解释器?

4
我一直在思考马克·吐温所写的这篇文章,他开始用英语写作,但在整个文本中改变了拼写规则,以至于最后得到的可能是伪德语。这使我想知道是否有某种已经建立的语言解释器,可以让人们访问解释器本身,以便可以随时更改语言的语法和结构。例如,通常if子句是一个关键字;是否有一种语言可以让您在运行过程中更改或重新定义它?想象一下从一个语言开始,在结束时使用另一种语言。显然,你可以编写解释器并运行它,也许没有具体的区别在于这样做和修改解释器之间。我不确定这一点。也许对于任何给定的解释器,你可以动态地进行的修改是有限制的?除了这些更开放的问题,我只想知道是否有已知的解释器可以允许这样做?或者,也许这种能力只是程度上的区别,我的问题提出得不好。
3个回答

6

当然有一些语言可以在语言语法层面上实现自修改行为。Lisp程序可以包含宏,其中包括动态创建新控制结构的能力,以至于依赖广泛宏编程的两个Lisp程序看起来几乎像是用两种不同的语言编写的。类似的,Forth提供了约十二个基本操作的核心集合,需要使用该领域的语言(通常是某种必须精确且可编程的现实交互,例如工业机器人)构建程序。Forth程序员创建一个理解特定问题领域的语言的解释器,然后在该语言中编写更高级别的程序。

通常,这里的共同观点是将代码和数据视为等同的语言或系统,并且给用户修改它们的同等权利。例如,每个Lisp程序都是一个Lisp数据结构。这与Java等语言形成对比,在Java中,对程序代码和操作的数据进行了尖锐区分。

相关主题是自修改低级代码,这是汇编程序员在具有复杂指令集的小型计算机时代的一种相当常见的技术,它在早期的8位和16位微型计算机世界中也有所涉及。在这种编程惯用语中,为了提高速度或节省内存,程序将以“意识到”编译或解释指令存储在内存中的位置的方式编写,并可以逐字节地就地更改实际的机器级指令以影响其行为。


2

Forth是我能想到的最明显的东西。它是串联和基于堆栈的,其基本单元是一个单词。因此,您编写一系列单词,它们按照编写顺序执行,并且堆栈被明确操纵以影响参数传递、结果等。因此,一个简单的Forth程序可能如下所示:

6 3 + .

以下是翻译的结果:

这句话包含了数字6、3、加号和点号。两个数字将它们的值推入堆栈,加号符号将从堆栈中弹出最后两个项并将它们相加,然后将结果推入堆栈。句点输出堆栈顶部的任何内容。

Forth 的一个基本特点是你可以定义自己的单词。由于所有单词都是运行时的一等成员,实际上你构建了一个应用程序特定的语法。定义了相关的单词之后,你可能会得到像下面的代码:

red circle draw

那将画一个红色的圆。

Forth在遇到每个单词序列时进行解释。然而,它区分编译时和普通单词。编译时单词执行的操作包括将一系列单词编译并存储为新单词。因此,这相当于在经典过程式语言中定义子程序。它们也是实现控制结构的手段。但是,您也可以定义自己的编译时单词。

因此,Forth程序通常定义其整个语法,包括相关的控制单词。

您可以在这里阅读基本介绍。


Factor是另一种具有可塑语法的连接语言。它的语义更像Lisp而不是Forth。 - Jon Purdy

2
Prolog是一种同像语言,允许以多种方式拒绝元解释器(MIs)。在Prolog中,元解释器——解释解释器——是一种常见且有用的本地构造。

请参阅this page 以了解此论点的介绍。一个有趣且实用的技术是部分执行

使用部分求值技术可以编译掉使用MIs实现这些东西所产生的开销。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接