一文带你快速了解编译原理

什么是程序的执行?

输入
程序
输出

程序可以看做一个函数,接受输入和返回输出?

什么是编译器?

源程序
编译器
目标程序

将源程序编译成 目标程序。
代表:

  • c/c++
  • go
  • rust

什么是解释器?

源程序
解释器
输入
输出

代表:

  • python
  • lua

混合编译器

源程序
第一次编译
中间代码
第二次编译
虚拟机
输入
输出
  • 中间代码更容易被翻译成目标程序、优化空间更大
  • 中间语言的存在更利于编译器的实现
  • 让虚拟机处理复杂的执行环境(跨平台)

代表:

  • java

即时编译器(Just-in-time compiler)

  • 一种提高效率的方法,中间代码不是直接执行,而是先被编译成机器码执行。
  • java

交叉编译

  • 在一个平台编译产生多个平台的可执行代码
编译平台Mac
Linux_ARM
Windows_x64
Linux_x64

不同方式优劣势

  • 解释执行有性能问题,但也异常灵活,例如支持eval函数,eval 本质上 就是c语言的函数指针,将cs:ip 指向文本,这样就能将一串文本 转换成 代码了。
  • 直接交叉编译技术难度是其次,跨平台问题会多;一次编译很多包也有分发问题----产品问题。
  • 虚拟化技术提供更好的体验,却没有 提供更好的性能(JIT完美解决这一点)。

编译阶段

词法分析
语法分析
编译平台Mac
Windows_x64
Linux_x64

词法分析(Parser):

将字符序列转换为单词(Token)序列的过程, 分词断句 + 判断词性的过程。

给定:

var a = 5 * 6.0 + 7;

token词性
var关键字
a变量
=运算符
5整型
*运算符
6.0浮点型
+运算符
7整形

语法分析(LEXical):

学过因为的都知道,单词不是随便都能组合的,按照"主谓宾" i eat a apple 我们可以把一句话,生成一个ast抽象语法树(Abstract Syntax Tree),用来辅助直接计算或者辅助编译器生成字节码的结构。
在这里插入图片描述

在这里插入图片描述

我们 对 这颗 AST树进行后序(左、右、上) 输出, 5、6.0 、* 、 7 、+ ,到了 这 我们 就可以很方便使用栈的数据结构模拟进行计算了。
在这里插入图片描述
语法 分析,可以从前往后 也可以从后往前,一般来说从前往后去解析语法比较方便,解析语法树 我们可以通过 一个表达式,

expr -> number op expr|number

上面的表达式 比较抽象, 举个例子

expr = 1 + 2 + 3 + 5 + 6

expr = 1 + expr1 = ↓
expr = 1 + 2 + expr2 =↓
expr = 1 + 2 + 3 + expr3 = ↓
expr = 1 + 2 + 3 + 5 + expr4

可以看到 expr3 = 5 + expr4 、此时 expr4 = 6 是一个number 那么,递归节结束。
上面,的例子 expr表达式 就是将 一个问题 像套娃、分形图 一样拆解成 一个数 操作符 和 另一个更小规模的expr表达式 ,这就是递归的思维 表达式的最后一层套娃是一个number。

运行时环境

  • 有的编译器将代码编译成机器码,按照操作系统约定编译成一个应用,运行称为操作系统的进程.
  • 有的编译器将代码编译成中间代码(字节码、三地址代码等),然后在操作系统中启动一个虚拟容器(进程)来执行他们。
  • JIT编译器一边执行中间代码,一边编译他们。

编译器分层

在这里插入图片描述

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值