学习笔记——解释器

      解释器(英语:Interpreter),又译为直译器,是一种电脑程序,能够把高级编程语言一行一行直接转译运行。解释器不会一次把整个程序转译出来,只像一位"中间人",每次运行程序时都要先转成另一种语言再作运行,因此解释器的程序运行速度比较缓慢。它每转译一行程序叙述就立刻运行,然后再转译下一行,再运行,如此不停地进行下去。

      解释器针对不同的硬件平台实现了一个虚拟机,可以仿真硬件的执行过程和一些关键应用,来弥合程序语义与硬件语义之间的差异。

 

解释器的组成

       一个解释器通常包括完成解释工作的解释引擎,一个包含将被解释的代码的存储区,一个记录解释引擎当前工作状态的数据结构,以及一个记录源代码被解释执行的数据结构。

      

      基本构件:

      解释器引擎

      被解释源代码

      存储区

      解释器引擎的当前的内部控制状态的表示

      程序当前执行状态的表示

      连接件:

      对存储区的数据访问

 

Small BASIC解释器

      包括两个主要的子系统:一个是表达式解析器,负责处理数字表达式;另一个是解释器,负责程序的实际执行。

      包含在同一个解释器类中,该类名为SBasic。

      两者用同一个类的好处:实现时的效率会更高。

      因为表达式解析器和解释器的代码是密不可分的。例如,两个子系统都操作保存着程序代码的同一个字符数组。如果将它们分别安排在两个类中,将会增加可观的额外开销,并导致性能上的损失和功能上的重复。程序解释的任务繁重,而解析表达式只是其中的一部分。

 

解释器的三种策略:

      1.传统解释器(ASP /excel/JavaScript/MATLAB/etc)

      直接运行高级编程语言 (如 Shell 自带的解释器)

     /* shell

      在计算机科学中,Shell俗称壳(用来区别于核),是指“提供使用者使用界面”的软件(命令解析器)。它类似于DOS下的command.com。它接收用户命令,然后调用相应的应用程序。同时它又是一种程序设计语言。作为命令语言,它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。*/

      

      2.字节码解释器(例如:Java/python)

      在该类解释器下,源代码首先被“编译”为高度压缩和优化的字节码,但并不是真正的机器目标代码,因而与硬件平台无关;编译后得到的字节码然后被解释器加以解释;

      /*字节码

      字节码(Byte-code)是一种包含执行程序、由一序列 op 代码/数据对组成的二进制文件字节码是一种中间码,它比机器码更抽象。它经常被看作是包含一个执行程序的二进制文件,更像一个对象模型。字节码被这样叫是因为通常每个 opcode 是一字节长,但是指令码的长度是变化的。每个指令有从 0到255(或十六进制的: 00 到FF)的一字节操作码,被参数例如寄存器或内存地址跟随。*/

      

      JAVA

      Java的源程序不是直接交给解释器解释,而是先经过一个编译过程,把Java源程序翻译成一种特定的二进制字节码文件,再把这个字节码文件交给Java解释器来解释执行。

      3.实时编译

      以解释器包含的编译器对高级语言编译,并指示处理器运行编译后的程序 (例如:JIT)

      实时编译JIT中,字节码在运行时被编译为本机的目标代码。第一步是编译得到字节码,字节码被配置到目标系统中,当字节码被执行时,运行环境下的编译器将其翻译为本地机器码。JIT模糊了解释器、字节码解释器和编译器之间的边界与区分。

      

 

       JIT编译部分:当某个函数要被执行时或被频繁执行的代码段

 

直译与编译的比较:

      1.在解释器上运行程序比直接运行编译过的代码来得慢,是因为每次解释执行时候,都需要分析程序的结构,而编译代码则直接执行而无需重复编译。解释器对内存的分配是在解释时才进行的;而编译器则是在编译时进行,因此运行时直接将程序代码装入内存并执行即可。

      2.在程序开发的雏型化阶段和只是撰写试验性的代码时尤其来得重要,因为这个"编辑-直译-除错"的循环通常比"编辑-编译-运行-除错"的循环来得省时许多。

      3.可携性佳,直译式程序相较于编译式程序有较佳的可携性,可以容易的在不同软硬件平台上运行。而编译式程序经过编译后的程序则只限定于运行在开发环境平台。

      4.在使用解释器来达到较快的开发速度和使用编译器来达到较快的运行进度之间是有许多妥协的。

      有些系统(例如有一些LISP)允许直译和编译的代码互相调用并共享变量。

      许多解释器并不像其名称所说的那样运行原始代码,反而是把原始代码转换成更压缩的内部格式。例如,用Emacs Lisp所撰写的源代码会被编译成一种高度压缩且优化的另一种Lisp源代码格式,这就是一种字节码(bytecode),而它并不是机器码(因此不会被绑死在特定的硬件上)。这个"编译过的"码之后会被字节码直译器(使用C写成的)转译。解释器也可以使用如同编译器一般的文字分析器(lexical analyzer)和 语法分析器(parser)然后再转译产生出来的抽象语法树(abstract syntax tree)。

 

参考来源:

http://xue163.com/2089/1/20890552.html

http://baike.so.com/doc/5904938-6117840.html

http://www.doc88.com/p-333761462276.html

posted @ 2016-03-20 11:53  铃铛小妹  阅读(1724)  评论(0编辑  收藏  举报