文档章节

编译器与解释器

wiitht
 wiitht
发布于 2017/06/11 20:56
字数 1446
阅读 3
收藏 0

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

编译器这样处理代码: 对代码进行词法分析,语法分析,语义制导,生成中间代码,中间代码优化,生成目标代码,目标代码优化.(目标代码可以是汇编代码,也可以是机器代码,这取决于编译器的实现,比如编译器中集成了汇编器) 代码的优化是反复进行的,穿插于整个过程中. 整个代码文件被编译成目标代码之后, 链接器程序将目标文件与相应的函数库链接,这样 原来的文本代码就成为了一个可执行程序,可以独立运行.

而解释器是这样处理: 解释器同样要对代码进行词法分析,语法分析,语义制导, 文本代码中某一段符合一定的语法规则,就会执行语法文件中定义好的动作.(想想,如果是编译器,与语法规则相对应的动作应该是构造中间代码).我们定义的动作可以是构造一棵语法树.比如遇到 a+b 匹配语法规则 expr '+' expr 对应的执行函数是{new treenode("+",$1,$3)} 当所有的文本代码都遍历完之后,就可以建立一棵完整的语法树,接下来,解释器程序可以遍历这棵语法树来实现想要完成的功能.比如说 我们要输出 文本文件代码表示的模型. 解释器就可以直接把这棵语法树输出给用户. 解释器也可以输出目标代码(比如汇编代码),只需把与语法规则相对应的动作改为输出函数,输出的汇编指令需要自己手写,这样产生的代码质量,完全取决于编写者的水平.一般没有编译器做的那么好. 如果再使用汇编器编译执行产生的汇编代码,解释器就变成了编译器. 解释器慢的原因之一是 同样的代码,下次执行,还是要从头来解释一遍,重新构造语法树.无法脱离解释器. 而编译器对文本文件代码编译一次,生成的程序可以独立运行,不再需要编译器.再执行一次,直接运行可执行程序.

 

  学过C/C++语言的同学都知道,写完的程序都要经过编译的过程,这其中就涉及到对编译器的理解,也许对于非计算机专业的人来说,没必要把其中的详细编译步骤了解清楚,但知其所以然似乎更好。

        Windows下比较主流的编译过程一般集成在集成开发环境VS中,在Linux下一般使用GNU(当然比较牛的人似乎都是用那种命令行的形式编译的,可惜我不是)。在VS中程序的执行过程包括:预处理(preprocessor)—编译(compiler)—汇编(assembler)—链接(linker)—加载(loader)。

         预处理的作用将分散在多个文件中的代码合并起来,#include语句就有此作用,在预处理中有可能用到宏(macros)。#include加入的头文件不能包含有定义语句,由于C++中变量和函数只能定义一次,而头文件是被加入到其他原文件中的,所以其中不能含有定义语句,否则会有重定义(redefinition)的错误,当然也有例外,类,const对象,inline函数可以定义在头文件中。

         编译的过程就是将源程序翻译成目标程序:源程序—编译器—目标程序,编译器还有报告源程序错误的作用。在生成了目标程序后,由我们的输入就可以生成相应的输出:输入—目标程序—输出,这也是诸多函数的调用形式。

        汇编就是将编译步骤生成的代码(在C/C++中.o格式文件),其一般是汇编语言代码,转化为计算机能够处理的机器代码,这个过程和上一步骤似乎很类似。

        链接是将分散在不同源文件中的代码组合起来,生成一个可以处理的大文件,例如,在VS中的多个源文件,通过单独编译后,可以链接成一个文件,然后通过加载器将其加载到计算机内存中,得到可执行文件(C/C++中的.exe文件)

        解释器是另外种形式的语言处理器,它相当于不生成上面的目标程序,直接将输入“放到”源程序中,然后经过解释器,就得到了输出。通常情况下,编译过程比解释过程更快,但解释器能够有更好的错误诊断,因为解释器是逐句进行解释的。学习过Python语言的同学都知道,Python是一种解释性语言,它的运行过程就用到了解释器。

        编译器和解释器可以结合起来进行处理,Java语言处理器就是其中的代表,其过程是源程序经过翻译器处理后得到中间程序,也被称作字节码(bytecode),然后和输入共同加入到虚拟机(virtual machine)的前端,得到输出,其前一部分用到编译器,后一部分用到解释器,这样做的好处是一个机器解释的代码可以应用在另外的机器上,甚至可以延伸到网络上。

本文转载自:

wiitht
粉丝 3
博文 158
码字总数 113941
作品 0
深圳
架构师
私信 提问
自己手动编写一个简单的解释器 Part 1

“如果你不了解编译器是如何工作的,那么你就不了解计算机是如何工作的。如果你无法确保100%掌握编译器的工作原理,那么你就是不了解其工作原理” — Steve Yegge 好了,思考一下这个问题。无...

Aaron74
2015/07/01
14.5K
23
浅谈解释器与JIT编译器的功能

  早在Java1.0版本的时候,Sun公司发布了一款名为Sun Classic VM的Java虚拟机,它同时也是世界上第一款商用Java虚拟机,在当时这款虚拟机内部只提供解释器,用今天的眼光来看待必然是效率低...

胡萝卜思ss
2018/01/15
0
0
笨办法学 Python · 续 练习 35:解释器

练习 35:解释器 原文:Exercise 35: Interpreters 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 解析中的最后一个练习应该既具有挑战性又有趣。你终于可以看到,你的微型 Python 脚...

apachecn_飞龙
2017/08/13
0
0
谈笑间解答--编译器和解释器

菜鸟经常将编译器和解释器弄混淆,无奈之下,于是向高手请教。 高手说: 菜鸟说:“我还是不明白,能给个形象的比喻么?” 高手说:“给你讲个故事。” 菜鸟说:  高手说: 总之,解析器和编...

hblxp321
2017/02/08
0
0
凭啥Java的运行环境称虚拟机,Python的只能称解释器

看到Stackoverflow上有个问题在讨论Java和Python的对比,其中就有人问答为啥Java的运行环境被称之为JVM,而Python的只能叫做Interpreter。 这个问题估计想过的人不多,先找维基百科看一下虚拟...

AlexMahoneFBI
2015/03/07
324
0

没有更多内容

加载失败,请刷新页面

加载更多

【JavaScript】callee 与 caller

callee callee是函数参数arguments对象的一个属性,它指向参数arguments对象所在的函数自身。 function foo (x) {console.log(arguments.callee);return x;}foo(); 从控制台中可以看...

小草先森
30分钟前
2
0
全面剖析 Knative Eventing 0.6 版本新特性

摘要: Knative Eventing 0.6 版本已经于5月15号正式发布。相比于0.5版本,此次发布包含了一些重要特性及更新。针对这些新特性以及更新,我们如何快速、精准的定位主要技术点。本篇文章针对这...

阿里云云栖社区
32分钟前
9
0
ffmpeg常用命令

1.合并两个或多个视频文件 将a.flv b.flv合并为c.flv 编辑文件flvs.txt file 'a.flv'file 'b.flv' #ffmpeg -f concat -i flvs.txt -c copy c.flv...

硅谷课堂
33分钟前
1
0
MySQL面试题--常见的四种隔离级别

什么是事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个...

寰宇01
33分钟前
2
0
Docker 安装 reids

0、mac上安装docker brew cask install docker 1、查询reidis docker search redis 2、拉取redis最新版本(也可以拉取指定版本,如:docker pull redis:4.0) docker pull redis 3、查看镜像 ...

moon888
41分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部