一个用C编写的C编译器或用PHP编写的PHP解释器是否可被称为“元环”的合法?这个定义仅适用于特定类型的语言,比如Lisp吗?简而言之,一个被称为元环的解释器应满足什么条件?
一个用C编写的C编译器或用PHP编写的PHP解释器是否可被称为“元环”的合法?这个定义仅适用于特定类型的语言,比如Lisp吗?简而言之,一个被称为元环的解释器应满足什么条件?
元循环解释器是一种用同一语言的(可能更基础的)实现编写的解释器。通常这样做是为了尝试向语言中添加新功能或创建不同的方言。
之所以将这个过程与Lisp联系在一起,是因为这篇高度清晰的论文《解释器的艺术》展示了几个基于Scheme的元循环解释器。(该论文是书籍SICP的核心,其第四章介绍了其他创造惰性计算Scheme的元循环解释器.)
这在“同像”语言(一种代码可以在运行时作为数据进行操作的语言)中,例如Lisp、Prolog和Forth中要容易得多。
至于您直接的问题——C编译器根本不是解释器。用自己的语言编写的编译器是“自举”的,这是类似的属性,但更相关于引导程序。用PHP编写的PHP解释器可能不符合条件,因为在此过程中你可能需要重新实现大量的语言功能。传统元循环解释器的主要优点是没有必要——您可以插入现有的解析器、垃圾回收等,并只编写具有不同语义的顶层求值器。在Scheme或Prolog中,这通常只需要不到一页的代码。
以下内容摘自维基百科关于元循环页面:
元循环求值器是自解释器的特例,其中父解释器的现有功能直接应用于被解释的源代码,无需额外的实现。
因此,在这两种情况下答案都是否定的:
据我所知,元循环解释器是一种可以解释自身的解释器。
编译器只翻译代码,不执行它。
任何图灵完备语言在数学上都能模拟任何逻辑计算,因此这里有一个使用Python的例子。你可以使用PyPy而不是使用CPython将此代码翻译为CPU指令并执行它。后者是自举的, 因此满足了一些人用来定义元循环解释器的任意标准。
"""
Metacircular Python interpreter with macro feature.
By Cees Timmerman, 14aug13.
"""
import re
def meta_python_exec(code):
# Optional meta feature.
re_macros = re.compile("^#define (\S+) ([^\r\n]+)", re.MULTILINE)
macros = re_macros.findall(code)
code = re_macros.sub("", code)
for m in macros:
code = code.replace(m[0], m[1])
# Run the code.
exec(code)
if __name__ == "__main__":
#code = open("metacircular_overflow.py", "r").read() # Causes a stack overflow in Python 3.2.3, but simply raises "RuntimeError: maximum recursion depth exceeded while calling a Python object" in Python 2.7.3.
code = "#define 1 2\r\nprint(1 + 1)"
meta_python_exec(code)
exec
和相关函数虽然是元级别的行为,但并不构成元循环解释器。在没有任何元级别设施的语言中,您可以制作元循环解释器。关于“元循环”的事情是:用语言A编写的语言A的解释器。例如,Pascal用Pascal编写,Basic用Basic编写,Smalltalk用Smalltalk编写。使用exec
只是将其传递给主机Python,并不构成Python的新实现。pypy是一个元循环Python,您应该看一下! - Tobiaseval
与第二个eval
不同时。被调用的eval
不应与Python的exec
混淆;eval
是由元循环解释器实现的,而不是主机语言的解释器。 - Tobias