解释器与编译器

时间:2022-12-25 17:07:58
          计算机不能直接认识并执行我们写的语句,它只能认识机器语言(是二进制的形式)。 编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快;
解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度是不如编译后的程序运行的快的.

1. 在具体计算机上实现一种语言,首先要确定的是表示该语言语义解释的虚拟计算机,一个关键的问题是程序执行时的基本表示是实际计算机上的机器语言还是虚拟机的机器语言。这个问题决定了语言的实现。根据这个问题的回答,可以将程序设计语言划分为两大类:编译型语言解释型语言

 

2. 编译型语言编写的源程序需要经过编译汇编链接才能输出目标代码,然后机器执行目标代码,得出运行结果,目标代码由机器指令组成,一般不能独立运行,因为源程序中可能使用了某些汇编程序不能解释引用的库函数,而库函数代码又不在源程序中,此时还需要链接程序完成外部引用和目标模块调用的链接任务,最后输出可执行代码C、C++、Fortran、Pascal、Ada都是编译实现的。

 

3. 解释型语言的实现中,翻译器并不产生目标机器代码,而是产生易于执行的中间代码,这种中间代码与机器代码是不同的,中间代码的解释是由软件支持的,不能直接使用硬件软件解释器通常会导致执行效率较低。用解释型语言编写的程序是由另一个可以理解中间代码的解释程序执行的。与编译程序不同的是,解释程序的任务是逐一将源程序的语句解释成可执行的机器指令,不需要将源程序翻译成目标代码后再执行。对于解释型Basic语言,需要一个专门的解释器解释执行 Basic程序,每条语言只有在执行才被翻译。这种解释型语言每执行一次就翻译一次,因而效率低下。(执行时逐一翻译成中间代码再解释成可执行的机器指令)一般地,动态语言都是解释型的,如Tcl、Perl、Ruby、VBScript、 JavaScript等。

 

4. Java很特殊,Java程序也需要编译,但是没有直接编译称为机器语言,而是编译称为字节码,然后在Java虚拟机用解释方式执行字节码。Python 的也采用了类似Java的编译模式,先将Python程序编译成Python字节码,然后由一个专门的Python字节码解释器负责解释执行字节码。

 (Java虚拟机对字节码的执行相当于模拟一个cpu,而ruby1.8--在虚拟机还未出现前--是通过解释成语法树执行。)

Java主要靠Java虚拟机(JVM)在目标码级实现平台无关性。JVM是一种抽象机器,它附着在具体操作系统之上,本身具有一套虚机器指令,并有自己的栈、寄存器组等。但JVM通常是在软件上而不是在硬件上实现。(目前,SUN系统公司已经设计实现了Java芯片,主要使用在网络计算机NC上。另外,Java芯片的出现也会使Java更容易嵌入到家用电器中。)JVM是Java平台无关的基础,在JVM上,有一个Java解释器用来解释Java编译器编译后的程序。Java编程人员在编写完软件后,通过Java编译器将Java源程序编译为JVM的字节代码。任何一台机器只要配备了Java解释器,就可以运行这个程序,而不管这种字节码是在何种平台上生成的(过程如图1所示)。另外,Java采用的是基于IEEE标准的数据类型。通过JVM保证数据类型的一致性,也确保了Java的平台无关性。

简单说,java的解释器只是一个基于虚拟机jvm平台的程序 ,解释器作用是把代码解释成虚拟机能够读懂的东西,然后由JVM来执行。虚拟机包括解释器的,运行的时候需要解释器去一点一点的去加载class文件最后由JRE支持。

java的工作机制

Java语言具有高安全性、高移植性等优点,这与它的工作机制有关。下面介绍Java的工作机制,这将更有助于理解Java语言的特点。   对于运行在Internet上的网络应用程序,需要有良好的可移植性。因为Internet是由各种各样不同类型的终端、服务器和计算机等硬件设备组成的,而且在这些设备上运行的软件系统也是多种多样的,所以Internet上的网络应用程序应该具有在各种不同的软硬件平台上均可正常工作的能力。以前的各种优秀语言都无法圆满解决这个问题,而Java的工作机制使得它具有了这样的能力。   Java 的工作机制是这样的:编程人员首先编写好源代码,然后经编译生成一种二进制的中间码,称为字节码(bytecode),最后再通过运行与操作系统平台环境相对应的、一种称为Java 解释器的运行机构来执行编译生成的字节码。虽然不同的平台环境需要有各自相应的解释器,但是任何一个平台上的解释器,对于一段Java程序的字节码来说却是相同的,因为它们对Java字节码呈现出完全相同的面貌。也就是说,Java的运行机制可以利用解释器来隐藏网络上平台环境的差异性。由此可见,Java 实现了二进制代码级的可移植性,在网络上实现了跨平台的特性。   Java的解释器又称为“Java虚拟机(JavaVirtual Machine,JVM)”,是驻留于计算机内存的虚拟计算机或逻辑计算机,实际上是一段负责解释执行Java字节码的程序。JVM能够从字节码流中读取指令并解释指令的含义,每条指令都含有一个特殊的操作码,JVM能够识别并执行它。从这个意义上说,Java可以被称为是一种“解释型”的高级语言。高级语言的解释器对程序边解释边执行,执行效率较低。因此,运行Java程序比运行C或C++等“编译型”语言程序速度要慢一些,这是Java语言的一个不足。随着硬件的发展,这个速度差别正变得越来越小,而网络的飞速发展,这种体系结构中立、平台无关的特性却显得越来越重要。

 

 

 

编译器和解释器

编译器和解释器都是可执行程序. 二者都需要输入.即文本代码文件.

编译器这样处理代码: 对代码进行词法分析,语法分析,语义制导,生成中间代码,中间代码优化,生成目标代码,目标代码优化.(目标代码可以是汇编代码,也可以是机器代码,这取决于编译器的实现,比如编译器中集成了汇编器)

代码的优化是反复进行的,穿插于整个过程中.

整个代码文件被编译成目标代码之后,

链接器程序将目标文件与相应的函数库链接,这样 原来的文本代码就成为了一个可执行程序,可以独立运行.

 

而解释器是这样处理:

解释器同样要对代码进行词法分析,语法分析,语义制导, 文本代码中某一段符合一定的语法规则,就会执行语法文件中定义好的动作.(想想,如果是编译器,与语法规则相对应的动作应该是构造中间代码).我们定义的动作可以是构造一棵语法树.比如遇到 a+b 匹配语法规则 expr '+' expr  对应的执行函数是{new treenode("+",$1,$3)}

当所有的文本代码都遍历完之后,就可以建立一棵完整的语法树,接下来,解释器程序可以遍历这棵语法树来实现想要完成的功能.比如说 我们要输出 文本文件代码表示的模型. 解释器就可以直接把这棵语法树输出给用户.

解释器也可以输出目标代码(比如汇编代码),只需把与语法规则相对应的动作改为输出函数,输出的汇编指令需要自己手写,这样产生的代码质量,完全取决于编写者的水平.一般没有编译器做的那么好.

如果再使用汇编器编译执行产生的汇编代码,解释器就变成了编译器.

 

解释器慢的原因之一是  同样的代码,下次执行,还是要从头来解释一遍,重新构造语法树.无法脱离解释器.

而编译器对文本文件代码编译一次,生成的程序可以独立运行,不再需要编译器.再执行一次,直接运行可执行程序.