19

调用用 C 编写的 C 编译器或用 PHP metacircular 编写的 PHP 解释器是否合法?这个定义是否只对特定类型的语言有效,比如 Lisp?简而言之,一个解释器需要满足哪些条件才能被称为 Metacircular?

4

4 回答 4

27

A metacircular interpreter is an interpreter written in a (possibly more basic) implementation of the same language. This is usually done to experiment with adding new features to a language, or creating a different dialect.

The reason this process is associated with Lisp is because of the highly lucid paper "The Art of the Interpreter", which shows several metacircular interpreters based on Scheme. (The paper is the kernel for the book SICP, and its fourth chapter works through others that create e.g. a lazily-evaluated Scheme.)

This is also vastly easier to do in a "homoiconic" language (a language whose code can be manipulated as data at runtime), such as Lisp, Prolog, and Forth.

As to your direct question - the C compiler wouldn't be an interpreter at all. A compiler written in its own language is 'self-hosting', which is a similar property, but more related to bootstrapping. A PHP interpreter in PHP probably wouldn't count, since you would likely be re-implementing a nontrivial amount of the language in the process. The major benefit of a conventional metacircular interpreter is that doing so isn't necessary - you can plug in the existing parser, garbage collection (if any), etc., and just write a top-level evaluator with different semantics. In Scheme or Prolog, it's often less than a page of code.

于 2009-09-26T12:40:11.267 回答
7

以下是metacircular维基百科页面的定义:

元循环评估器是自解释器的一种特殊情况,其中父解释器的现有设施直接应用于正在解释的源代码,而无需任何额外的实现。

所以在这两种情况下答案是否定的:

  • AC 编译器不是解释器(评估器)。它将程序从一种形式转换为另一种形式而不执行它。
  • 用 PHP 编写的(假设的)PHP 解释器是自解释器,但不一定是元循环的。
于 2009-09-26T11:58:10.867 回答
4

为了补充上述答案:http ://www.c2.com/cgi/wiki?MetaCircularEvaluator

用 Lisp 编写的 Lisp 通过调用“eval”来实现“eval”。但是在许多其他语言中没有“eval”(如果有,它具有不同的语义),因此必须编写一个全新的语言系统,一个为“eval”提供详细算法的语言系统——这是在元循环情况下不是必需的。这就是 MetaCircularEvaluators 的魔力:它们反映了它们可能使用的语言的潜在魔力。

于 2009-09-26T13:20:55.913 回答
-1

据我了解,元循环解释器是可以解释自身的解释器。

编译器只翻译代码,不执行它。

任何图灵完备的语言都能够在数学上模拟任何逻辑计算,因此这里有一个使用Python的示例。除了使用 CPython 将此代码转换为 CPU 指令并执行它,您还可以使用PyPy。后者是自举的,因此满足某些人用来定义元循环解释器的任意标准。

"""
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)

用 C 编写的 AC 编译器不是 MetaCircularEvaluator,因为编译器必须为每个构造指定极其详细和精确的语义。编译器是用目标语言编写的这一事实根本没有帮助;相同的算法可以翻译成 Pascal 或 Java 或 Ada 或 Cobol,它仍然是一个非常好的 C 编译器。

相比之下,Lisp 的 MetaCircularInterpreter 无法翻译成非 Lisp 语言。没错, 不能——至少,不能以任何简单的一对一方式。用 Lisp 编写的 Lisp 通过调用“eval”来实现“eval”。但是在许多其他语言中没有“eval”(如果有,它具有不同的语义),因此必须编写一个全新的语言系统,一个为“eval”提供详细算法的语言系统——这是在元循环情况下不是必需的。

就是MetaCircularEvaluators 的魔力:它们反映了它们可能使用的语言的潜在魔力。

于 2013-08-14T18:26:40.807 回答