【编译原理】编译的过程

计算机科学 同时被 2 个专栏收录
3 篇文章 0 订阅
1 篇文章 0 订阅

被隐藏的过程

  1. 预处理(Prepressing)- 展开宏定义(处理#define,#include),删除注释,添加行号和文件名标识。生成.i 预处理文件
  2. 编译(Compilation)- 词法分析、语法分析、语义分析、优化。预处理+编译用ccl完成。生成.s 汇编代码文件
  3. 汇编(Assembly)- 把汇编代码转成机器可执行的指令,不需要做指令优化。用汇编器as 完成。生成.o 目标文件(object file)
  4. 链接(Linking)- 用链接器ld完成。

编译器做了什么

通常,编译过程分为6步:扫描、语法分析、语义分析、源代码优化、代码生成、目标代码优化。

1 词法分析(src -> Tokens, Scannar:lex)

  • 源代码进入扫描器,用有限状态机 把源代码的字符分割成TokenToken 一般包括关键字、标识符、字面量、特殊符号。
  • 同时,扫描器也会完成其他工作,例如将标识符放到符号表,将数字、字符串常量放到文字表等。
  • lex,可以根据用户描述好的词法规则,来进行词法扫描的,词法扫描器。

2 语法分析(Tokens -> ST, Parser :yacc)

  • 对Tokens进行语法分析,产生语法树(Syntax Tree)。ST以表达式为节点,叶子节点是数字字面值或标识符。
  • 采用的是上下文无关语法(Context-free Grammar)。
  • yacc,可以根据用户给定的语法规则,对输入的Token序列进行解析,并构建语法树的,语法分析器。

3 语义分析(ST -> commented ST, Semantic Analyzer)

  • 完成静态语义分析(编译时确定的语义是静态的,运行时确定的是动态的,编译器只能完成静态语义分析)。静态语义分析一般包括声明和类型的匹配、类型转换等。
    • 例如,在语法分析得到的ST中,可能出现两个指针做乘法;在经过语义分析后,判定这是不合法的。
    • 动态语义是运行时出现的语义问题,例如将0作为除数。这是不能被编译器检查到的。
  • 经过语义分析后,ST的所有节点被标识了类型,对于隐式转换的,会插入相应转换节点。语义分析器还会对符号表中的符号类型也做更新。

4 中间语言生成(commented ST -> IR, Source Code Optimizer)

  • 代码优化器将语法树转换成中间代码,也称中间表达式(IR)。IR是语法树的顺序表示,通常为三地址码,或P-代码。
    • 三地址码:x = y op z
    • 为什么要转成IR呢?因为直接在语法树上做优化比较困难。
  • 非常接近目标代码,但是IR与目标机器和运行时环境无关(而目标代码依赖于目标机器)
    • 与目标代码和运行时环境无关,是因为IR不包含数据的大小、变量的地址和寄存器的名字(会用t1/t2/t3这种临时变量表示)。
  • 根据IR,编译器分为前端和后端。前端负责产生IR,后端负责将IR转换成目标机器码。
    • 对于跨平台的编译器,可以使用同一个前端和针对不同机器平台的不同后端。

5 目标代码生成(IR -> Target Code,code generator)

  • 代码生成器将IR转换成目标机器码(例如,x86汇编语言)
  • 这个过程依赖于机器。
    • 因为不同机器有不同的word size/寄存器名称/整数数据类型/浮点数数据类型等。

6 目标代码优化(Target Code -> Final Target Code, target code optimizer)

  • 目标代码优化器对上述目标代码进行优化
  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值