编译原理-概述
编译原理-概述
编译过程
编译程序能够把一个程序从源语言翻译成源程序
1. 词法分析
任务:输入源程序,对构成源程序的字符串进行扫描与分解,识别出单词符号
依循的规则:构词规则
描述工具:有限自动机
2. 语法分析
任务:在词法分析的基础上,根据语法规则把单词符号串分解成各类语法单位(语法范畴)
依循的规则:语法规则
描述工具:上下文无关文法
描述结构的分析树
3. 中间代码产生
任务:对各类语法单位按语言的语义进行初步翻译(静态语义检查)
依循的原则:语义规则
例:赋值语句语义:先计算赋值号右边的表达式的值,然后把这个值送到赋值号左边的变量的存储单元中
描述工具:属性文法
中间代码:三元式,四元式,树…
例: Z:=X+0.618*Y翻译成四元式为:
序号 OPR OPN1 OPN2 RESULT 注释(给人看的) (1) * 0.618 Y T1 T1:=0.618*Y (2) + X T1 T2 T2:=X+T1 (3) := T2 Z Z:=T2
4. 优化
任务:对前阶段产生的中间代码进行加工变换,以期在最后阶段产生更高效(程序在时间、空间方面)的目标代码
依循的规则:程序的等价变换规则(功能上完全等价)
5. 目标代码产生
任务:把中间代码变换成特定机器上的目标代码
依赖于:硬件系统结构和机器指令的含义
目标代码三种形式:
- 汇编指令代码:需要进行汇编(不能直接在机器上执行,需要汇编器)
- 绝对指令代码:可直接运行(指令地址部分是绝对地址,可以调到内存直接运行)
- 可重新定位指令代码:需要链接(代码中地址是相对地址,能从内存中的任何位置开始装载,绝对地址=相对地址+起始地址)利于模块化开发
编译程序结构
编译程序总框
符号表管理模块:主要完成编译过程中各种对象的信息的存储组织和修改,为各阶段的分析和转换提供依据,存储信息
出错处理模块:指出错误发生的代码位置,错误性质,甚至给出纠错建议
- 出错处理程序:发现源程序中的错误,把有关错误信息报告给用户
- 语法错误:源程序中不符合语法规则和词法规则的错误,如非法字符、括号不匹配、缺少;等
- 语义错误:源程序中不符合语义规则的错误,如说明错误、作用域错误、类型不一致等
遍
对源程序或源程序的中间表示从头到尾扫描一次
与阶段的区别:
- 一遍可以由若干段组成
- 一个阶段也可以分若干遍来完成
编译的前端和后端(分解和权衡)
与源语言、中间语言、目标语言的相关性的相关性有关
编译前端:与源语言有关,词法分析、语法分析、语义分析与中间代码产生,与机器无关的优化
编译后端:与目标机器有关,与目标机有关的优化,目标代码的产生
编译后端:程序逻辑结构清晰;优化更充分,有利于移植(保持一方不变,替换另一方)
编译程序生成
1. 以机器语言和汇编语言为工具
优点:可以针对具体机器,充分发挥计算机系统功能,生成的程序效率高
缺点:程序难读、难写、易出错、难维护、生产效率低
2. 高级语言书写
优点:易读、易写、易维护
S源程序–I实现语言–>T目标程序
- 利用已有的某种语言的编译程序实现另一语言的编译程序:
例:A机器上的L1语言编译程序实现A机器上的L2语言编译程序
已知L1语言–P1(A代码)–>A代码
可写L2语言–P2(L1语言)–>A代码
将P2(L1语言)输入P1
即生成L2语言–P2(A代码)–>A代码- 移植方法:把一种机器上的编译程序移植到另一种机器上
例:A机器上的L语言编译程序实现B机器上的L语言编译程序
已知L语言–P1(A代码)–>A代码
可写L语言–P2(L语言)–>B代码
将P2(L语言)输入P1
生成L语言–P2(A代码)–>B代码 //交叉编译
再将P2(L语言)输入P2(A代码)
即生成L语言–P2(B代码)–>B代码
3. 自编译方式
例:制作L语言的编译程序
L1–L1–>L1+L2–(L1+L2)–>L1+L2+L3–…-->L
4. 编译程序自动产生
- 编译程序-编译程序,编译程序产生器,编译程序书写系统
- LEX:词法分析程序产生器
- YACC:语法分析程序产生器