编译技术在我们日常的工作中可以说无处不在,React JSX语法的解析,Typescript转化为Javascript,XML、JSON的解析,Spring字节码生成技术,PHP的模板引擎,还有最近很火的文言文编程项目(wenyan-lang)……这些都和编译技术息息相关,既然编译技术有这么大作用,那么它到底是什么?首先我们给出一个整体的介绍,如下图所示:

从图中可以知道,编译技术总共分为6个过程,其中词法分析、语法分析、语义分析这三个过程统称为前端,生成中间码、优化、生成目标代码这三个过程叫做后端。有了一个整体的印象之后,就可以一步一步来解释每一个过程的作用。

写过程序的人都知道,程序语言一般包含一些特殊关键字:if、else、for、while、class、import……运算符:>、

接下来请回想一下自己在写代码的过程中是不是会写各种各样的语句,比如下面这样的if语句:

if(a>b) return a;

如果把a>b抽象成expr(表示任意表达式),把return a;抽象成statement(表示任意语句),那么上面的if语句就可以转化成如下形式:

if(expr) statement

这就是if语句的结构,同样很容易写出while语句的结构:

while(expr) statement

编译的第二个阶段就是要识别出程序代码中一个一个这样类似的结构,这个过程就叫做语法分析(Syntactic Analysis,or Parsing)。但是马上就会有一个疑问,我们到底把这些结构识别成什么了呢?还是回到刚才的例子,用如下图形表示if语句:

看到这里有没有很熟悉?这不就是数据结构中学习过的树结构嘛,是的,这就是一棵树,它叫做抽象语法树(Abstract Syntax Tree,AST),现在很容易就可以画出while语句的抽象语法树了:

同样地,还可以画出很多这样的图形,而我们的程序就是由这样一个一个的语句构成的,那么最终的程序就可以用如下图形表示出来:

这就是整个程序的语法树。你看语法树其实一点也不难理解,而整个语法分析的过程就是构建出这样一棵树。

有了语法树之后还要做什么呢?让我们再次回到刚才if语句的例子:

if(a>b) return a;

在if语句中使用了a、b两个变量,很多语言都要求在使用变量之前先申明,不然就是不合法的,编译器要能检测出这种错误。还有不同的语言有不同的作用域,比如Javascript有函数作用域,Java有类作用域,C语言有块作用域,编译器要能分析不同的作用域,以及每个变量所属的作用域等。在函数作为一等公民的语言中,还要实现闭包,比如如下Javascript代码:

function outer() {

var a = 0;

function inner() {

a = a + 1;

return a;

}

return inner;

}

var inner = outer();

console.log(inner()); // 1

console.log(inner()); // 2

按理说outer函数调用结束后,a应该被销毁了,但是在调用inner的时候还是可以引用到a,这就是我们常说的闭包,编译器要能识别出这样的a。还有比如很多静态类型的语言在编译的时候要做类型检查等等。给生成的语法树添加足够的信息,让它可以生成正确的目标代码,这个添加信息的过程就叫做语义分析(Semantic Analysis)。

理论上,拥有了足够信息的语法树之后已经可以生成目标代码了,这个过程可以用下面的图形表示:

再来看,如果引入中间码的过程会是怎么样:

对比两个图我们可以很容易看出,当引入中间码的时候,可以大大节省工作量,这就是引入中间码的其中一个原因。

我们都知道,衡量程序好坏的其中一个重要指标就是程序的性能,这就要求我们对生成的中间码进行优化,这个过程就是接下来的优化过程,可以用下面的图形表示:

经过优化器以后就可以生成最终的目标代码了,到此我们已经把编译的整个过程过了一遍。

总结:

词法分析:把源代码分割成一个一个的词法记号

语法分析:识别程序结构,生成语法树

语义分析:给语法树添加信息,用于生成正确的目标代码

生成中间码:节省工作量,解放生产力,增加灵活性

优化:让程序跑得更快

关注公众号获取第一手信息

下篇预告:《人人都可以学会编译原理-词法分析之四则运算》,在该篇中我们的主要目标是实现类似于下面的四则运算表达式的词法记号解析

​-3.14 + 3.14 \* 3.14 + (3.14 + 3.14) / 3.14 - 3.14

最终将它转化成如下形式

Minus -

NumberLiteral 3.14

Plus +

NumberLiteral 3.14

Star \*

NumberLiteral 3.14

Plus +

LeftParen (

NumberLiteral 3.14

Plus +

NumberLiteral 3.14

RightParen )

Slash /

NumberLiteral 3.14

Minus -

NumberLiteral 3.14

文言文编程可以编译成PHP吗,人人都可以学会编译原理-开篇相关推荐

  1. 人人都能学会的python编程教程(基础篇)完整版

    人人都能学会的python编程教程1:第一行代码 人人都能学会的python编程教程2:数据类型和变量 人人都能学会的python编程教程3:字符串和编码 人人都能学会的python编程教程4:关系运 ...

  2. 学计算机的会重装系统吗,人人都能学会重装系统,你还在抱着电脑去实体店重装系统吗?...

    人人都能学会重装系统,你还在抱着电脑去实体店重装系统吗? 简单快速重装系统 在这个互联网发达的时代,手机和电脑都是大多数人常用的工具. 在使用电脑的过程中,相信很多网友们都遇到过这种情况,电脑越用越卡 ...

  3. 带瀑布流的电钢琴_让人人都能学会弹钢琴——零基础入门的智能电钢琴 POP Piano...

    原标题:让人人都能学会弹钢琴--零基础入门的智能电钢琴 POP Piano 前言 其实你一直希望成为一个会弹琴的人,只是一直没有机会开始. 如果是20世纪是网络纪元,那么21世纪就是AI纪元.当人类创 ...

  4. python编译成exe有意义吗_python工程编译成EXE

    前言 python编译成EXE文件后,可以独立使用.亲测,一个复杂的python工程包含多个包多个模块,可以生成exe文件. 目的 windows下将整个python工程编译成单个EXE或者单个目录带 ...

  5. 人人都能学会的python编程教程1:第一行代码

    前言 众所周知,现在IT行业很火,行业薪酬也很高,国家在2017年也发布了人工智能教育的推广计划,人人会编程的时代将要到来.不会编程.不懂编程可能有些跟不上时代的节奏,普通人不懂技术也许会觉得这个很难 ...

  6. python编译成c代码_python如何调用c编译好可执行程序

    以下总结出几种在Python 中调用 C/C++ 代码的方法 -------------------------------------------------------------------- ...

  7. python是人都能学会_人人都能学会的python编程教程15:高级特性2

    生成器 如果你想要一百万个数,而这些数里只有一百个数是你经常要用的,剩下的都几乎不怎么会用到,那么如果直接把这一百万个数全部放在list中是不明智的因为这会浪费较多存储空间,生成器就是为了解决这个问题 ...

  8. java程序编译成exe文件_将java程序编译成独立运行的exe文件

    将java程序编译成独立运行的exe文件 众所周知java的程序可以"一次编译,到处运行",这个特性不错,但是实现这个特性的前提是当前的平台 必须有相应的jvm,而且如果当前平台的 ...

  9. 人人都能学会的SHELL编程

    目 录 1. Shell入门简介 1 2. Shell编程之变量详解 4 3. If条件语句学习 7 4. 使用if条件语句编写MySQL备份脚本 10 5. IF条件综合Shell实战脚本编写 11 ...

最新文章

  1. tomcat主目录(ROOT.xml)和虚拟目录
  2. TS流解析之PAT表格解析
  3. python计角_最小角python算法
  4. java xml 验证工具_验证xml格式
  5. tcpcopy使用方法
  6. C# 中的占位符本质
  7. oracle中imp命令具体解释
  8. Linux两台主机之间建立信任
  9. 实战HTML:根据参数构造动态设备监测列表
  10. 分模块开发创建service子模块——(八)
  11. 【笔记】scp如何复制文件到带空格路径的server目录
  12. 机器学习实战(一)xgboost实战
  13. 新版网易云课堂视频真实地址分析
  14. TestBed静态测试步骤
  15. 浅谈 渗透测试工程师(黑客) 技能
  16. 2.14 视图的分页预览以及分页符的使用 [原创Excel教程]
  17. Photoshop之快速蒙版Q
  18. oracle存储过程循环输入数据,oracle 存储过程循环插入数据
  19. 打开微信时站着的小人是谁?
  20. 双链路是什么意思_实时备份什么意思

热门文章

  1. Minio设置文件链接永久有效
  2. C#ABB机器人PC SDK通讯02
  3. 15位或18位身份证验证
  4. PW4053M原厂芯片5V升压12.6V1A,三节串联锂电池充电管理板
  5. Sorting(排序)
  6. 因为计算机中丢失dui,修复WmpDui.dll
  7. cytoscape安装java_Cytoscape软件学习(1):简介及安装
  8. [linux] zip
  9. 如何实现USB Type-c转HDMI2.0功能方案
  10. 光斑定位技术在空间激光通信中扮演着重要的角色。本文将详细介绍光斑定位的相关知识,并使用Matlab实现一些相关的算法。