一、编译器的实现步骤

1、词法分析,将原文件划分为单独的单词或关键字。

2、语法分析,利用上下文无关文法分析程序的短语结构。

3、语义分析,根据短语建立抽象语法树,确定短语含义、变量关联声明、检查表达式类型。

4、翻译,根据抽象语法树翻译成中间表示树不依赖任何特定的程序语言和目标机器结构。

5、指令选择,根据目标机器的指令体系,对中间表示树的节点进行划分。

6、控制流分析。

7、数据流分析。

8、寄存器分配。

9、代码生成。

在上编译原理课程的时候,我们完成了一个基于miniJava的编译器和垃圾回收器

代码:https://github.com/xuhaoavl/tiger

二、词法分析器

1、词法记号,编程语言语法单元的一系列字符,词法记号一般分为有限的几种。

例如:ID(字符串)、NUM(整数)、REAL(实数)、IF(if)、VOID(void)、COMMA(逗号)。。。。

2、正则表达式,一般用正则表达式匹配字符窜的方式检查字符串类型。

符号(a,v,h,b等),或(a|b)、并(a·b)、空(ε)、重复(克林闭包,所有可能的字符串)

有一些可能会产生模糊性,例如if8是字符串还是if和8,对此有以下两种解决方法

a、最长匹配,选择可以匹配正则表达式的最长输入字符串。

b、优先匹配,选择最先与之匹配的正则表达式,这时候正则表达式的顺序很重要。

3、有限自动机DFA,不存在两个从统一状态出发且标记完全相同的边,不存在空串。

一般使用DFA来实现词法分析。

4、非确定有限自动机NFA,可能存在多条从一个状态出发且标记一样的边,也可能有空边。

一般使用正则表达式表示一个语言的词法,然后将其转换为NFA(正则表达式转NFA比较容易),最后再将NFA转DFA,并用代码实现。

三、语法分析

1、上下文无关文法

使用上下文无关文法描述词法结构。

推导形式有最左推导和最右推导,可以使用一颗分析树表示推导的过程,每一步推导都对分析树中的某一个节点进行一步拓展。

二义性文法是指能够产生两颗不同的分析树。,可以通过改写文法消除二义性。

2、预测分析的过程

递归下降,每个递归下降分析器对应一个非终结符号的推导。

但是在推导的过程中有可能会产生冲突,即在某一步有多个候选式。

这时候可以通过计算当前非终结符的first集和follow集来解决冲突。

LL(k):从左到右分析,最左推导,k个lookahead符号。

LR(k):从左到右分析,最右推导,k个lookahead符号。

消除左递归,根据first集和follow集,左递归会导致多重定义入口。

消除左因子,用一个新的非终结符替代。

四、抽象语法

1、在一个递归下降分析器中,语义动作是分析函数返回的值。

2、抽象语法树,其实也就是前面所说的分析树

在Java中其实也就是一颗对象树,main函数所在的类也就是树根,树上有表达式对象,语句对象等。

如图所示,在语法分析的过程中,已经构建出了一颗抽象语法树。

3、抽象语法树的遍历

从根步遍历语法分析树的时候并不知道每个子节点的类型,可以通过instanceof解决,但是更好的一个解决方法是使用访问者模式。

意图:主要将数据结构与数据操作分离。

主要解决:稳定的数据结构和易变的操作耦合问题。

五、语义分析

把变量的定义与使用联系到一起,检查表达式的类型。通过符号表进行。

1、符号表,将标识符与其类型和位置进行映射。实际中可能含有很多个符号表,每一个类、每一个方法都有一个符号表,第一次遇到该变量的时候会将其加入到符号表中,作用域结束后将其删除。

符号表主要用于检查变量的使用和定义、检查表达式类型。

六、翻译成中间表示

虽然可以直接翻译成机器码,但是这将阻碍可移植性并且无助于进行模块化设计。

中间表示是一种抽象的机器语言,无需过多考虑机器特性就可以对目标机进行表达。但是,它同样独立于源语言。编译器的前端进行词法分析、语法分析、语义分析并负责生成中间表示,后端负责对中间表示进行优化,同时翻译成机器语言。

1、使用中间树表示中间表示

递归遍历前面生成的抽象语法树将其转换成中间树。中间树与抽象语法树的区别是抽象语法树和源语言相关,而中间树则与源语言无关,与机器也无关,是一种中间表示形式,例如三地址指令、四地址指令等。

中间树要尽量能够满足不同语言的要求,又不能与机器底层有太多关系。

七、指令选择

中间表示树的每一个树节点仅能表示一种操作:从内存中读,从内存中写,加,减等。找到一些恰当的指令去构造一颗中间表示树是指令选择阶段要完成的工作。

将机器指令表示成中间树的片段,称为树模式。这样指令选择的任务就是构造一颗包含最小树模式集所组成的树。

八、活性分析

编译器需要分析中间表示程序来确定哪些临时变量同时被使用,如果一个变量中保存的值会被使用,则变量是活跃的。如果两个临时变量不是同时使用,则他们可以共用寄存器。通过活性分析可以确定出一个最少使用的寄存器数,最大化寄存器的使用。

控制流图:每一条语句都是一个执行块,按照程序执行的顺序可以画出程序的控制流。

通过控制流分析出每个变量的活性,再通过活性画出干扰图。

干扰图可以是一个邻接矩阵或则一个无向图,哪些点之间有边表示那些变量之间不能分配给同一个寄存器。

九、寄存器分配

寄存器分配其实是一个着色问题,使用k(k个寄存器)种颜色给干扰图着色。

十、垃圾收集

标记清扫、复制、标记整理、分代收集。

十一、数据流分析

数据流分析主要是收集程序运行时可能发生的信息,并针对该信息进行一些优化:

1、寄存器分配,同一个寄存器保存两个不重叠的临时变量。

2、消除共用子表达式,如果一个表达式被多次计算,消除其中一个计算。

3、消除死代码

4、合并常量,如果一个表达式的操作数是常量,那么在编译时执行该计算。

除此之外,还有其他的一些优化策略,如循环优化、静态单赋值、流水线和调度策略。

还有一些利用计算机cache的优化,如指令cache对齐,预取指令循环交换,分块等。

一个简单编译器的实现过程相关推荐

  1. 使用TensorFlow 来实现一个简单的验证码识别过程

    本文我们来用 TensorFlow 来实现一个深度学习模型,用来实现验证码识别的过程,这里识别的验证码是图形验证码,首先我们会用标注好的数据来训练一个模型,然后再用模型来实现这个验证码的识别. 1.验 ...

  2. 制作演示的福音,推荐屏幕录制软件:Adobe Captivate 2,特意使用这个录制一个简单的录制使用过程,让大家有直观印象...

    我相信,大家都碰到过这样的情况,就是介绍一个软件或者指导一个电脑操作的时候,千言万语也说不明白. 初级工具是截屏,晋级工具当然是录像了. 录像工具我以前用过很多,不是很理想,有些使用复杂;有些生成的文 ...

  3. 一个简单的宏病毒制作过程

    为了说明简单,笔者为教大家做一个简单的宏病毒,以此来了解宏病毒的作用机制,请大家不要模仿这个来搞"小动作"啊,不然,警察叔叔要请你喝茶我就没办法了^_^.首先启动Word2000/ ...

  4. 使用 LLVM 实现一个简单编译器

    作者:tomoyazhang,腾讯 PCG 后台开发工程师 1. 目标 这个系列来自 LLVM 的Kaleidoscope 教程,增加了我对代码的注释以及一些理解,修改了部分代码.现在开始我们要使用 ...

  5. Qt实现一个简单的编译器(软件生成器)

    Qt实现一个简单的编译器(软件生成器) 本文章只记录如何用Qt实现一个简单编译器,即点击本软件中的按钮便可在另一目录中生成一个新的软件(与本软件不冲突). 文章目录 Qt实现一个简单的编译器(软件生成 ...

  6. 从Mysql源代码角度分析一句简单sql的查询过程

    1. 前言 使用mysql这么多年,以前一直只懂写sql,却不其中运行原理,直至最近抽时间看了一下mysql源代码, 对其事务运行原理及sql解析优化有一些更深入的理解. 本篇是讲述sql解析的开篇之 ...

  7. 实现一个简单的编译器

    简单的说 编译器 就是语言翻译器,它一般将高级语言翻译成更低级的语言,如 GCC 可将 C/C++ 语言翻译成可执行机器语言,Java 编译器可以将 Java 源代码翻译成 Java 虚拟机可以执行的 ...

  8. java实现编译器_实现一个简单的编译器

    简单的说 编译器 就是语言翻译器,它一般将高级语言翻译成更低级的语言,如 GCC 可将 C/C++ 语言翻译成可执行机器语言,Java 编译器可以将 Java 源代码翻译成 Java 虚拟机可以执行的 ...

  9. 一步一步解读神经网络编译器TVM(一)——一个简单的例子

    @TOC 前言 这是一个TVM教程系列,计划从TVM的使用说明,再到TVM的内部源码?为大家大致解析一下TVM的基本工作原理.因为TVM的中文资料比较少,也希望贡献一下自己的力量,如有描述方面的错误, ...

最新文章

  1. 中文停用词文档_使用Python中的NLTK和spaCy删除停用词与文本标准化
  2. 如何在windows下安装cygwin
  3. 数据挖掘十大算法--K-均值聚类算法
  4. 【转】 使用 AppFuse 快速构建 J2EE 应用
  5. java 字符串去掉换行_java第一个程序quot;helloworldquot;
  6. boost::owner_less相关的测试程序
  7. java后台http请求完成之后怎么setcookie_关于HTTP的那些事和cookie
  8. Codeforces Round #669 (Div. 2)
  9. csv转json文件
  10. [C++基础]037_编写不可被继承的类
  11. 《Ray Tracing in One Weekend》——Chapter 12: What's next?
  12. Git教程 git pull 和 git clone的区别
  13. H5动画实现简单的转盘抽奖。
  14. 普乐郡——回乐县(城市记忆7)
  15. 八种语言最新毕业文献参考
  16. 浅谈大小端(Endian)与位域
  17. Laya shader opengles 2.0 第一章-飘扬的旗帜 gitee代码
  18. 递归回溯法求数独全部解
  19. 如何快速无损地把flv格式文件转换为mp4格式(可在iPhone上播放)
  20. 用于软件测试的最佳免费自动化工具

热门文章

  1. 中鑫吉鼎|家庭理财规划具体有哪些步骤
  2. 怎样把视频里的音乐提取出来?
  3. 气象-数据同化学习(OBSPROC)(2)
  4. Mediacodec 华为P9 绿屏
  5. iis发布mvc 遇到的HTTP错误 403.14-Forbidden Web 服务器被配置为不列出此目录的内容.
  6. 侏罗纪2来袭,看3D电影和探险3D恐龙世界,你选哪个?
  7. 廖雪峰老师git学习笔记(2)
  8. ULN2003步进电机 5V/12V步进电机 28BYJ-48步进电机 13003驱动板开发者文档
  9. 拼多多店铺排名这样来做
  10. 华硕z790让独显和集显同时工作