【CS106】编译原理笔记5 —— 编译器编译过程

笔者:YY同学

生命不息,代码不止。好玩的项目尽在GitHub



学习自然语言处理(NLP)的同学们都有一个梦想,那么就是自己写一个编译器。但是编译器可不是说写就能写的,它需要经历很多复杂的步骤,只有做好每一个步骤,我们的编译器才能发挥出它的最强性能!

Step 1:Scanner(扫描仪)

Scanner 的作用是把用户的源代码进行分割,切割成不同的词快( Token ),例如 int a = 0; 这句话中,就可以切割出 5 个 Token,即 Type关键字INT变量a赋值号数字0分号

需要检查的错误:

  1. 你的语言中未定义的字符在非注释中出现,例如 @a = 4;
  2. 关键字的拼写错误,例如 mian

输入:以用户编写的源代码
输出:如果没有语法错误则输出一个完整的 Token 的链表,如果有错误则需要将所有错误扫描一遍并报错(第几行、错误位置、错误类型等)


Step 2:Parser(语法解析器)

在这里插入图片描述

Parser 的作用是根据 Scanner 处理完毕的 Token 链表建立一棵语法树( Syntax Tree ),是编译器的核心,核心算法为迭代递归,Parser 设有不同类型的树(表达式树、if 树、while 树等等),每棵树的子节点可以是单独的语句也可以是另一棵树的根节点。这样由下往上,每棵树处理对应的一类语句,将 Token List 变成树状结构。主要根据上下文无关语法,一般将左侧的表达式作为根节点,根据右侧表达式的种类个数生成对应数量的子节点。例如在 python 的 while 语句中,

while condition:
      block

主体部分由 while关键字条件block 三部分组成(忽略 冒号indent),因此这三个部分为 while树 的子节点(while树自己是根节点)。

需要检查的错误:

  1. 括号匹配问题
  2. 数学表达式语法结构问题(例如不可能出现3*+5)
  3. if 和 while 的语法结构问题(例如没有冒号的情况)
  4. 首行缩进问题(indent 和 dedent)

输入:Scanner 处理产生的 Token 的链表
输出:一棵大的语法树。


Step 3:Semantic Analyzer(词法分析器)

词法分析器(简称 SA)在 Parser 的基础上进行进一步的错误勘探。Parser 是自下而上扫描找出结构上的错误,而 SA 更多则是自上而下扫描找出逻辑内容上的错误,例如类型匹配的错误。此外,SA 还需要一个 Symbol Table(数据结构为 Hash Table 和 Bucket List)来记录所有出现过的变量名称以及它们的值,需要一个 Line List 来记录这些变量的使用情况以及栈指针来记录函数返回值的位置。

需要检查的错误:

  1. 类型是否匹配(例如字符串+数字)
  2. 没有 return

输入:Parser 产生的语法树
输出:逻辑检验后的带注释的树( Annotated Tree )


Step 4:Source Code Optimizer(源代码优化器)

这一部分是在 SA 的基础上,将一部分的结果用同等效果的优化结果代替,以加快编译速度。例如:a=5+6*2 的结果会被优化为 a=17

输入: Annotated Tree
输出:优化后的中间代码( Intermediate Code )


Step 5:Code Generator(代码生成器)

这一部分需要用到 C语言转汇编语言( Assembly Code )。

输入:Optimized Intermediate Code
输出:目标代码( Target Code )


Step 6:Target Code Optimizer(目标代码优化器)

最后一步属于底层优化,主要是从指令集逻辑上来加快编译的速度,一般通过指令换序、指令合并来进行加速,打过 ACM 的同学可能知道 gcc 编译选项里有 O2 这个参数,事实上就是第二档的目标代码优化。

输入:Target Code
输出:Target Code(二进制文件Binary Code)


Step 7:Execute Target Code

最后只需要执行最终的目标代码(只含二进制数 0 和 1),就可以顺利跑出我们的程序啦~

至此,一个编译器就这样诞生了,让我们一起祝福它生日快乐~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值