解释器如何运行代码?

sta*_*lei 5 programming-languages interpreted-language compilation

阅读所有编译与解释的文章,似乎编译意味着机器将直接运行编译的代码,而解释则意味着机器将运行代码。但是,如果代码在机器上,解释器如何运行代码呢?它最终是否仍然必须将其解释的内容转换为机器代码并仍然让机器运行它?归根结底,一切都必须成为机器代码才能让机器正确运行?似乎解释只是意味着它一次一行地运行该语言,而编译意味着一次运行所有内容。之后,就几乎一样了,对吗?

EJo*_*ica 7

相关:用解释语言编写的程序如果从未翻译成机器语言,如何执行?

不,它不需要将其转换为机器代码。这些指令仅向解释器本身提供指令,然后解释器自行执行这些指令。

考虑一种非常愚蠢的“语言”,它由以下指令组成:

加 [数字]
减 [数字]
除 [数字]
乘 [数字]

我们可以实现一个像这样的“解释器”(用 C# 编写):

public static void ExecuteStatements(List<string> instructions)
    {
        int result = 0;
        foreach (string instruction in instructions)
        {
            string[] action = instruction.Split(' ');

            int number = int.Parse(action[1]);

            switch (action[0].Trim().ToLower())
            {
                case "add":
                    result += number;
                    break;
                case "subtract":
                    result -= number;
                    break;
                case "divide":
                    result /= number;
                    break;
                case "multiply":
                    result *= number;
                    break;
            }
        }

        Console.WriteLine("Result: " + result);
    }
Run Code Online (Sandbox Code Playgroud)

ExecuteStatements方法将被编译为机器代码。另外,我们有一个如下的文本文件:

加1
减1
加10
乘50
除5

结果将是 100。这些字符串实际上从未被编译成任何东西——它们只是告诉解释器要采取什么操作。

显然,这种“语言”甚至还没有接近图灵完备,但关键是我们在任何时候都不会以某种方式将其“翻译”成机器代码——“解释器”只是采取指定的任何操作。

实际上,我曾经编写过一个解释器作为测试自动化框架的一部分。当有人对 API 进行调用时,我们会拦截该调用,使用反射来确定调用是什么以及参数是什么,并将反射元数据序列化为 JSON。随后,我们反序列化了 JSON,并使用反射来调用之前使用相同参数运行过的任何方法。引擎使用 JSON,而不是机器代码,并使用它来确定它应该执行什么调用;它从来没有创建或需要任何机器代码。关键的是,假设已经给定了有效的脚本,引擎“知道”如何自行执行所有指定的操作,因此它永远不需要将任何指令“卸载”到机器本身。

这是关键的见解:解释后的代码本身实际上什么也没做——它所做的只是向解释器提供它需要采取的操作。解释器已经“知道”如何执行您可以在解释语言中执行的所有操作,因此不需要额外的机器代码。

打个比方,将您正在解释的代码想象成菜谱,将解释器想象成厨师。该食谱指定了诸如“添加 1 杯面粉并混合”之类的操作。厨师知道如何遵循他在菜谱中找到的任何指示,并亲自执行。严格来说,菜谱实际上并没有做任何事情——它只是放在那里供厨师阅读,以便厨师知道要采取什么行动。为了完成菜谱,菜谱实际上不需要厨师——它只需要知道如何遵循菜谱指示的人。

TL;DR您不需要将其“翻译”为机器代码 - 您只需要有足够的信息让您的解释器知道要采取什么操作。一个好的解释器已经“知道”如何采取该语言可以实现的任何操作,因此不需要创建任何额外的机器代码。