解释器如何转换for循环?

时间:2017-07-31 06:18:16

标签: compilation compiler-construction interpreter

据我所知,解释器会逐行将源代码转换为机器代码,并在遇到错误时停止。

我想知道,当你给它做循环时,解释器会做什么。

E.g。我有以下(MATLAB)代码:

for i = 1:10000

pi*pi

end

它是否真的贯穿并逐行转换for循环10000次?

编译器的机器代码更短,只包含一组语句,其中包含一个有效10000次迭代的控制语句。

对不起,如果这没有意义,我对编程的基础知识和精神都不是很了解,但我想快速理解。

1 个答案:

答案 0 :(得分:3)

  

据我所知,解释器会逐行将源代码转换为机器代码,并在遇到错误时停止。

这是错误的。有许多不同类型的解释器,但很少有人逐行执行代码,而那些(主要是shell)执行的代码根本不会生成机器代码。

通常,有四种或多或少的常见方法可以解释代码:

  • 语句执行

    这可能是你逐行的意思,除了通常用分号作为换行符的替代品。正如我所说,这几乎只是由贝壳完成的。

    这是如何工作的,一次解析一个语句。这就是解析器在语句完成之前读取令牌。对于直到达到语句终止符的简单陈述,例如行尾或分号。对于其他语句(例如if语句,for循环或while循环),直到找到相应的终止符(endif,fi等)。无论哪种方式,解析器都会返回某种语句的表示形式(通常是某种类型的AST),然后执行。任何时候都不会生成机器代码。

    这种方法具有不寻常的属性,即文件末尾的语法错误不会阻止文件的开始执行。但是,所有内容仍然只被解析一次,即使条件为假,仍然会解析if语句等的主体(因此if false内的语法错误仍然会中止脚本)。

  • AST行走解释

    这里立即解析整个文件,并从中生成AST。然后解释器简单地遍历AST以执行程序。原则上这与上面相同,只是首先解析整个程序。

  • 字节码解释

    同样解析整个文件,但解析器不是AST类型结构,而是生成一些字节码格式。然后,逐个指令执行该字节码。

  • JIT编译

    这是实际生成机器代码的唯一变体。这有两种变体:

    • 在调用之前为所有功能生成机器代码。这可能意味着在整个文件被加载或翻译之前立即翻译它们。生成代码后,执行它。
    • 首先解释字节码,然后在执行多次后单独JIT编译特定的函数或代码路径。这允许我们根据在解释期间收集的使用数据进行某些优化。这也意味着我们不会为不被称为很多的功能支付编译费用。一些实现(特别是一些JavaScript引擎)也重新编译已经JITed的代码,以根据新收集的使用数据进行优化。

总而言之:逐行执行代码(或者更确切地说是语句)的实现与生成机器代码的实现之间的重叠应该非常接近于零。那些逐个语句的实现仍然只解析代码一次。

相关问题