编译程序(系统)和操作系统一起构建成立计算机中两大系统软件;一个是计算机资源的操纵者;另一个是计算机软件资源的开拓者。
1、我们为什么需要编译程序?
- 了解它是怎么将我们编写的源代码转换成可执行程序;
- 为什么它要这么设计;
- 为了提升自己 (如 了解底层机制,才能有更深入思考问题,以及深层次解决问题的能力,而不是只能盲目地搜索答案,从表面解决问题。而学习编译原理能让我们从前端的语法维度、代码优化的维度、与硬件结合的维度几个方面,加深对计算机技术的理解,提升自己的竞争力)。
2、什么是编译程序?
程序:按照我们编写的逻辑去执行相应的动作;
编译程序(compiler):是一种翻译程序,它特指把某中高级程序设计语言翻译成与之等价的具体计算机上的低级程序设计语言。
编译程序的执行过程包括两个阶段:编译阶段、运行阶段。
就好比我们写的java源程序,首先通过javac编译成.class字节码文件,之后再通过解释器java运行此字节码文件。
3、什么是解释程序?
解释程序(interpreter):也是一种翻译程序,它将源语言书写的源程序作为输入,解释一句后就提交计算机执行一句,并不形成目标程序。
两者的区别:
- 编译程序有目标程序;
- 解释程序无目标程序;
- 编译程序运行效率高;(我们直接运行目标程序就可以了,不需要完成翻译的过程)
- 解释程序便于人机对话;(不断获取外界数据,不断的执行)
4、编译程序的逻辑结构的6个阶段;
词法分析:识别出有意义的单词(保留字,标识符,常量,运算符,分隔符),返回单词的类别和单词的值,单词是组成语言程序的最小单位;
语法分析:在词法分析的基础上将单词序列分解成各类语法短语(如 程序、语句、表达式等)。这种语法短语也称为语法单位,可表示成语法树。
语义分析:审查源码程序有无语义错误,为代码生成阶段收集类型信息;(完整性,一致性)
中间代码生成:将源程序变成一种内部表示形式,这种内部表示形式叫做中间语言或中间代码;
代码优化:对前一阶段产生的中间代码进行变换或进行改造,目的使生成的目标代码更为高效,即省时间和空间;(优化作用,比如 语法合并之类的 java中的三元表达式可以节省if)
目标代码生成:这一阶段的任务是把中间代码变成特定机器上绝对指令代码或可重定位的指令代码或汇编指令代码;
前端(词法、语法、语义):将源语言翻译成一个中间代码的形式;
后端(中间代码生成,中间代码优化,目标代码生成):将中间代码的形式翻译成目标语言的形式。
5、编译程序与外文翻译的类别
I wish you success!
词法分析 :识别单词,确认词类;
语法分析:识别 短语和句型的语法属性;
语义分析:确认单词、短语和句型的语义特征;
中间代码生成和代码优化:修辞、文本编辑;
目标代码生成:生成译文;
6、遍
编译程序对源程序或等价程序从头到尾扫描的次数。
我通常将整个编译过程分为两遍:
-
第一遍:词法分析、语法分析、语义分析;
-
第二遍:中间代码生成、代码优化、目标代码输出;
如:使语法分析器处于核心的位置。当语法分析需要下一个单词时,就调用词法分析器,识别一个单词一旦识别出一个语法单位,就调用语义分析器,完成语义分析并产生中间代码。
7、编译过程的分析
如下c语言片段代码
int a,b;
...
b=a+2*5;
1、词法分析,识别源程序中的单词并分类;
(1) 关键字(keywords) -- int
(2) 标识符(identifier) -- a,b
(3) 常数(constant) -- 2,5
(4) 界符(p 这里有逗号、分号、赋值符号、加号、乘号) -- , ; = + *
2、语法分析:组词成句及语法错误检查;
b=a+2*5 的分析过程生成的结果是一棵语法树!
构造句子成功后进行语义分析;
3、语义分析:分析各种语法成分的语义特征;
-
构建标识符的语义辞典 -- 符号表
-
构建语句的语义树 -- 中间语言
如 b = a + 2 * 5
语义树形式:
四元式形式(中间代码生成):语法格式:(运算符,运算对象1,运算对象2,结果)
(1) ( * 2 5 t1 ) //第一条将2*5结果赋给t1 (2) ( + a t1 t2 ) //第二条将a+t1结果赋给t2 (3) ( = t2 _ b ) //第三条将t2的结果赋给b
4、代码优化:提高目标程序的质量;
如 b = a + 2 * 5
经常数合并,可分别获得优化后的中间代码;
优化前
中间代码:
(1) ( * 2 5 t1 )
(2) ( + a t1 t2 )
(3) ( = t2 _ b )
优化后
中间代码:
(1) ( + a 10 t2 )
(2) ( = t2 _ b )
5、目标代码生成;
-
最终,可生成目标代码(汇编指令);
中间代码:
(1) ( + a 10 t2 ) (2) ( = t2 _ b )
↓
目标代码:
① LD R,10 //将10这个常量加载到R当中,R为寄存器(指令有取、加、存), LD指取或加载的意思 ② ADD R,a //将a的值加到寄存器当中所存储的变量的值上面去,结果存在寄存器R当中 ③ ST R,b //将寄存器当中的值存到b所指定的内存当中