前言
最近在了解
vue.js
。观察到它能够在代码编辑过后,不用重新运行,便可以直接更新(后来了解到这个现象的原因:优秀的开发者朋友们编写了检测文件改动的工具,当检测到有文件完成改动并保存时,则自动响应编译动作。这和编译本身无关
)。于是产生了重新 了解计算机程序从编辑到机器执行工作的原理的兴趣。计算机编写的程序,都要通过编译、链接,最后生成机器的可执行文件,在机器上运行。编译的过程,是由编译器工具链去执行的。
我们作为编写代码的手艺人,
不能一直停留在平台语言功能SDK API 上的学习
。学习功能的API(比如学习一个LBS功能
) 固然能帮助我们去编写一个应用程序相关的功能点。
但要想了解计算机的工作原理,我们就必须去认识计算机编译相关的知识。其中,学习编译配置相关的知识,也有助于我们了解计算机程序的工作过程 和其底层原理实现,加深我们对整个程序的认识,帮助我们编写的高质量代码。所以我们不妨
从计算机编译原理这门课复习一下相关的知识点
!!!
概述
本文仅从全局视野的角度去关注计算机编译原理,而不对整个编译过程展开许多细节的讨论。可以相当于一个完整计算机编译原理的概述。
为了帮助我们能够较好理解,概述中会蜻蜓点水般点到为止地提及一些核心概念和核心理论,但不会去对理论的程序过程细节讨论
本文的篇幅包括以下几个章节:
一、编译型语言与解释型语言
二、编译程序
三、编译型语言的编译器和编译过程与解释性语言的解释过程
四、总结
推荐阅读
相关阅读
一、编译型语言与解释型语言
1.计算机程序工作的基本过程
- 1.在日常开发过程中,程序员编写的程序一般采用高级语言编写,然后存放在硬盘
- 2.当我们在IDE中 运行 编写好的程序 ,程序就会通过编译,生成二进制可执行文件 装载到内存
- 3.二进制程序在内存中运行,一般都有基于该类型高级语言编写的执行环境,如Java的JVM、OC/Swift的runtime、Node.js的Node、运行在Chrome中的H5其运行环境Chrome的V8引擎、运行在Safari中的H5其运行环境Safari的JavaScriptCore......
- 4.二进制程序在内存中运行过程中,其计算和控制一般由CPU处理,若有关于图形界面处理的逻辑,还会牵扯到GPU
- 5.二进制程序可以通过CPU控制计算机的硬件器件:显示器、音响、键盘、话筒、蓝牙等....
从前面的介绍我们可以知道,编写的应用级程序的计算机语言一般是高级语言,编写完毕之后,有一些语言是需要通过运行IDE,进行编译、链接、然后生成对应平台的可执行目标程序,最终运行在模拟器或者某个终端设备中去的。这种需要通过编译器
加工的语言称之为编译型语言
。
还有一些高级语言编写完毕之后,不需要通过编译器加工,但是需要通过解释器程序来解释,然后生成机器码
运行在目标终端。这种语言叫做解释型语言
。
我们简单小结一下:
1.2 编译型语言
- 程序运行前,必须先通过
编译器
生成机器码
,机器码直接通过CPU
执行,运行时不需要重新翻译; - 程序执行效率高,但依赖编译器,调试周期长、跨平台性差些;
- 代表语言:
C
、C++
、OC
等;
1.3 解释型语言
-
程序运行前,不需要进行编译,而是以文本方式存储程序代码,运行时需要解释器解释后再运行;
-
程序执行效率低下,但是程序具有动态性,运行后也可以随时增加和更新代码来改变程序逻辑;
-
代表语言:
Javascript
、Python
等;
二、编译程序
我们通常所说的程序编译就是程序编译的过程,那么什么是编译程序
呢?
从编译原理
一书中,我们可以认识到这是指导我们了解 如何将高级语言程序
变换成低级语言程序
的方法 。在书本中我们可以摘抄几个要点:
- 编译程序又称编译器:
- 高级语言的源程序->低级语言的目标程序
- 使编程者不必考虑与机器有关的细节
- 低级语言:
- 特定的计算机系统所固有的语言
- 即:机器语言、汇编语言
- 特点:执行效率高、编制效率低
- 编译程序分成若干遍:
- 占内存少,程序结构更加清晰,程序效率低,耗时长
- 编译程序一遍:
- 占内存多,程序逻辑不清,程序需效率高,耗时短
- 编译程序 关注的点:
- 源程序
- 目标语言
- 编译程序的编译方法及其过程
三、编译器的编译过程与解释过程
从上一Part我们可以了解到,编译器其实就是编译程序。我们可以进一步认识一下编译器:
3.1 编译器
概念:把一种编程语言(原始语言
)转换为另一种编程语言(目标语言)的程序;
大多数编译器都分前端
和后端
两部分:
- 前端:负责
词法分析
、语法分析
、生成中间代码
; - 后端:以
中间代码
作为输入,进行与架构无关的代码优化,接着针对不同架构生成不同的机器码;
补充:
- 前后端以
中间代码
作为媒介,使得前后端可以独立的变化,互不影响; - 这样的好处在于:新增一门语言只需要修改前端,而新增一种
CPU
架构只需要修改后端即可;
3.2 编译过程和编译程序的结构
结构图:
概念解释:
- 编译器前端
-
词法分析
- 从左到右读入源程序的每个字符,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词
-
语法分析
- 在词法分析的基础上将单词序列分解成各类语法短语
- 根据语法规则判断
-
语义分析
- 任务:审查源程序有无语义错误,为代码生成阶段收集类型信息。
- 语义:是程序设计语言中按语法规则构成的各个语法成分的意义。
- 静态语义:编译时刻即可确定的语法成分含义。
- 动态语义:运行时刻才能确定的语法成分含义。
-
中间代码生成
- 任务:在语法和语义分析之后,将源程序变成一种“内部表示形式”
-
- 编译器后端
- 代码优化
- 任务:对中间代码进行变换或改造,使之更为高效(时间、空间)
- 目标代码生成
- 任务:把中间代码变换成特定机器上的绝对指令代码或可重定位的机器指令代码或汇编指令代码
- 代码优化
3.3 解释性语言的解释过程
和编译型语言的工作方式不同,解释性语言也有其自身的皆是过程:
-
接受高级语言程序,并立即运行这个源程序。
- 工作模式是一个个获取、分析并执行源程序语句
-
解释程序与编译程序的比较
-
编译与解释的根本区别:是否生成目标代码
-
解释程序
-
优点:
- 可移植性较好。
-
缺点:
-
速度慢
-
空间开销大
-
-
-
四、总结
我们从前面篇幅中大概了解了:
-
程序语言一般分为高级语言和低级语言两大类。其中高级语言与人类自然语言比较接近,低级语言又称为面向机器的语言
-
面向机器的语言是指各种计算机系统都通用的语言,其特点是程序执行效率高,编写效率低,可读性差
-
编译程序是将高级语言程序翻译成汇编语言程序或机器语言程序;汇编程序是将汇编语言程序翻译成机器语言程序
-
编译程序的工作过程可以划分为 词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成 等六个阶段,同时还伴有表格管理 和出错处理
-
编译程序可以发现源程序的全部 语法 错误和部分 语义 错误
-
要在某台机器上为某种语言构造一个编译程序(编译器),必须掌握的内容有:源语言,目标语言,编译方法
-
一个编译程序,不仅包含词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成,还应包括表格处理和出错处理。其中中间代码生成和代码优化不是每个编译程序都必需的。词法分析器用于识别单词。语法分析器可以发现源程序中的语法错误
-
程序语言的语言处理程序是一种系统软件。解释程序 和 编译程序都是程序语言的处理程序,两者的主要区别在于是否生成目标代码 。
-
编译器必须完成的工作有
- 词法分析
- 语法分析
- 语义分析
- 目标代码生成
-
编译时,语法分析器的任务包括
- 分析单词串是如何构成语句和说明的
- 分析语句和说明是如何构成程序的
- 分析程序的结构
-
解释程序
- 与编译程序相比,解释程序通常缺少目标代码生成,代码优化
- 同时,解释程序比较简单,可以移植性好,执行速度慢,它处理语言时采用的方法是将源程序逐句转化成中间代码,解释执行
-
本篇文章没有进一步对编译过程的细节进行关注,因为日常工作中会关注这个过程比较多的,一般都是面向操作系统开发的朋友。