阅读所有已编译和解释的文章似乎编译意味着机器将直接运行编译的代码而解释,解释器将运行代码。但是,如果代码在机器上,那么解释器如何运行代码呢?它是否仍然必须将它的解释转换为机器代码并且仍然让机器运行它?在一天结束时,一切都必须最终成为机器代码,以便机器运行正确吗?似乎解释只是意味着它一次一行地运行语言,而编译意味着一次性通过它。在那之后,它几乎一样吗?
答案 0 :(得分:2)
不,它不需要将其转换为机器代码。说明只是向解释器本身提供指令,解释器然后自行执行。
考虑一种非常愚蠢的“语言”,其中包含以下说明:
添加[编号]
减去[数字]
除[数字]
乘以[数字]
我们可以实现这样的“解释器”(用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);
}
ExecuteStatements
方法将编译为机器代码。另外,我们有一个这样的文本文件:
加1 减去1 加10 乘以50 划分5
结果将是100.字符串实际上从未编译成任何东西 - 它们只是告诉解释器要采取什么操作。
显然,这种“语言”甚至不是模糊的图灵完整,但关键是我们在某种程度上不会将其“翻译”成机器代码 - “解释器”只是采取任何指定的行动。
我实际上曾作为测试自动化框架的一部分编写了一个解释器。当有人对API进行调用时,我们会拦截调用,使用反射来确定调用是什么以及参数是什么,并将反射元数据序列化为JSON。然后,我们对JSON进行了反序列化,并使用反射来调用之前使用相同参数运行的任何方法。引擎实际上并不需要机器代码 - 它只是使用反射来确定要执行的调用。
这是关键的洞察力:解释的代码本身实际上什么都不做 - 所有它正在做的是为解释器提供它需要采取的行动。解释器已经“知道”如何采用您在解释语言中执行的所有操作,因此不需要额外的机器代码。
作为一个类比,想想你正在解释为食谱的代码和作为厨师的翻译。配方指定了“添加1杯面粉和混合”等操作。厨师知道如何遵循他在食谱中找到的任何指示,并且他自己执行。严格来说,食谱实际上并没有做任何事情 - 它只是坐在那里供厨师阅读,以便厨师知道要采取什么行动。为了完成配方,没有必要让食谱真正 一个厨师 - 它只需要知道如何遵循其指示的人。
TL; DR 您无需将其“翻译”为机器代码 - 您只需要为解释器提供足够的信息即可了解要采取的操作。一个好的解释器已经“知道”如何采取语言可以实现的任何动作,因此不需要创建任何额外的机器代码。