第一章
编译器和解释器区别
参考这篇文章: lhttps://blog.csdn.net/qq_36627886/article/details/80402959
编译器(compiler):编译器是一种翻译程序,把源程序翻译为目标程序。编译在运行之前进行,【产物是另一份代码】。
解释器(interpreter):解释器也是一种翻译程序,它直接执行由编程语言或脚本语言编写的代码,并不会把源代码预编译成机器码。解释在运行时进行,【产物是执行结果】。
创建一个可执行目标程序流程
预处理器(preprocessor)
编译器(compiler)
汇编器(assembler)
链接器(linker)&加载器(loader)
编译流程
词法分析(lexical analysis或scanning)
- 任务:输入源程序,对构成源程序的字符串进行扫描和分解,识别单词符号
- 依循的原则:构词规则
- 描述工具:有限自动机
语法分析(syntax analysis或parsing)
- 任务:在词法分析的基础上,根据语法规则把单词符号分解成各类语法单位(语法范畴)
- 依循的原则:语法规则
- 描述工具:上下文无关文法
语义分析-中间代码产生阶段(semantic analysis)
- 任务:对各类语法中的语义进行初步翻译
- 依循的原则:语义规则
- 描述工具:属性文法
- 中间代码:三元式,四元式,树……
优化
- 任务:对前阶段产生的中间代码进行加工变换以期望在最后阶段产生更高效的代码
- 依循的原则:程序的等价原则
目标代码生成
- 任务:把中间代码变换成特定机器上的目标代码
- 依赖于硬件系统结构和机器指令的含义
- 目标代码三种格式
- 汇编指令代码:需要进行汇编
- 绝对指令代码:可直接执行
- 可重定位指令代码:需要链接
小的知识点
链接:相对地址(相对于本模块的地址 .obj)->绝对地址(.exe)
符号表管理:
出错处理:
遍(pass):遍和阶段不一样
- 一遍可以由若干段组成,常把联系紧密的阶段合成一遍来处理,词法+语法+中间,把词法分析和中间代码生产变为词法分析子程序或语义分析子程序,由语法分析来调用(语法分析起主导作用)。
- 一个阶段也可以分成若干遍完成,优化
前端:和源语言相关,和目标机器无关(注意这里不仅有前三个阶段lexical, syntax, semantic还有机器无关优化)
后端:和目标机器有关
思考,编译程序是什么程序,编译程序不是也要编译吗?
- 机器/汇编:不容易构建像编译程序逻辑这么复杂的程序。
- 高级语言:适合,但前提是要有高级语言的编译器。
- 移植方法:将L语言的编译程序P1从A机器移植到B机器,先用L语言自己写一个从L到B的编译程序P2(P2的A代码版本是交叉编译程序),在A机器上运行,得到P2的B代码版本,即B机器上可以执行的L语言编译程序。
- 自编译:L核心部分L1用汇编编译,然后核心部分L再自己构造更大部分L2的编译器,不再用汇编,这样慢慢自扩展。
- 编译程序自动产生(编译程序-编译程序):
- LEX:词法分析程序产生器
- YACC:语法分析程序产生器