一、理论
- 前端:分析部分,包括词法和语法分析,符号表建立,语义分析,中间代码生成,错误处理
- 后端:综合部分,包括与机器有关的代码优化,目标代码生成,符号表操作,错误处理
- 编译有 5 个阶段,分别是:词法分析,语法分析,语义分析和中间代码生成,代码优化,生成目标程序。有两个事件贯穿其中,即符号表管理和错误处理。也就组成了 7 个逻辑部分。
- 字母表和符号串
- 符号:可以理解为一个个的字母,比如说 $a, b, c, \phi$
- 字母表:是符号的集合,比如说 $\sum = {a,b,\phi}$
- 符号串:是符号的序列:比如说 $abababa$
- 空符号串:无任何符号的符号串,即 $\epsilon$
- 符号串集合:由符号串构成的集合
- 语言:一种特殊的符号串集合
- 文法就是语法,规定了语言的结构。
- 左递归文法只是无法采用自顶向下的分析方法,并不是一无是处
运行时存储组织与管理要回答的问题是
- 数据结构在内存里是如何表示的
函数在内存中是如何表示的
- 需要记住调用前的状态,以便在调用结束后返回。
- 需要提供一种办法,在调用函数和被调函数之间传递参数,返回值
- 满足 Scope 的要求,能够找到所有的数据结构
他们在内存中如何放置,如何管理(这里面有个专题是垃圾回收机制)
- 感觉这里很有意思,操作系统将内存封装成了一个数组,编译器决定了这个数组的使用方式。
- 存储管理主要有两个方面:
- 静态存储管理,对应的就是实验中对于
.data
的处理 - 动态存储管理,这部分在编译实验中被拆成了两个部分,一个部分在 llvm 翻译的时候完成,比如说栈式符号表之类的东西就出现在此处,一部分在 mips 翻译的时候完成,比如说函数运行栈的结构。这就导致似乎没法建立一个统一的体系,只能说和理论在表面上看有些出入。
- 静态存储管理,对应的就是实验中对于
- 非分程序的结构语言:每个可独立进行编译的程序单元时一个不包含有子模块的单一模块。如 FORTRAN 语言。另外常说的 Module 这个概念,也可能是来自这个语言
- IR(Intermediate representation):不同层次的 IR 代表了不同层次的抽象(类型、操作)通过分层抽象,实现最大限度的重用。
- 错误分类:
- 语法错误:不符合词法和语法规则的错误。
- 语义错误:
- 程序不合语义规则。比如说未定义,就使用。
- 超越具体计算机系统的限制,比如说栈溢出,类型溢出等。
二、压缩文法
需要压缩文法包括两种:
- 有害规则,就是 $U::=U$ 这种,这种十分显然,所以就不说了。
- 多余规则,针对语法规则的左部(左部是一个符号),又分为
- 不可达符号:就是这个左部没法由识别符号推出,那么就是不可达的。这种非常好识别,只需要进行一个符号的 BFS 即可。
- 不活动符号,就是形如 $A ::= Aa $ 这样的规则,会导致一直循环,没完没了。