程序设计语言
- 机器语言
- 汇编语言:多种汇编指令集与语法…
- 有多种 CPU 架构, 如 x86, arm, mips …
- 不同的架构对应的不同的汇编指令集, x86 汇编, arm 汇编, mips 汇编
- 不同的汇编指令集有不同的汇编语法, x86 汇编有 Intel 风格的 与 ATT 风格的, arm 汇编有自己语法, mips 也有自己的语法
- 不同语法的汇编需要由不同的汇编器转换为机器能识别的机器指令
- 中间语言的抽象程度与复杂程度介于高级语言和机器语言之间, 高级语言直接翻译为机器语言难度较大…
- 高级语言
翻译
是指能把某种语言的源程序,在不改变语义的条件下,转换成另一种语言程序一目标语言程序。编译程序就是一种翻译程序。
实现过程:编译/解释
- 编译:由高级语言转为低级语言
- 解释:接受某高级语言的一个语句输入,进行解释并控制计算机执行,马上得到这句的执行结果(不产生目标程序),然后再接受下一句
- Strength: 直观易懂,结构简单,易于实现人机对话
- Weakness: 效率低
编译
两阶段过程:编译 + 运行, source -> exe
三阶段过程:编译 + 汇编 + 运行, source -> asm -> exe
不同的高级语言经过编译后最终得到的目标代码可能为 exe 也可能为 obj 文件(也是 01 代码组成的文件), 如果是 obj 文件还需要进行链接(link), 才能正常使用
编译程序分类
运行编译程序的机器称为宿主机, 运行目标语言程序的机器称为目标机
- 诊断编译程序, Diagnostic Compiler, 辅助开发和调试, 发现错误
- 优化编译程序, Optimizing Compiler, 侧重于提高目标代码的效率
- 交叉编译程序, Cross Compiler, 编译程序产生不同于其宿主机的机器代码称为交叉编译程序
- 可变目标编译程序, Retargetable Compiler, 针对目标机器平台生成目标代码
编译程序流程
- 词法分析:识别出一个个单词(token, 高级语言中有实在意义的最小语法单位), 各个单词按照类别分类讨论, 转换成统一的规格, 供语法分析使用
- 语法分析:根据语言的语法规则(文法), 将单词符号组成各类的语法单位(短语、子句、过程、程序)
- 中间代码生成
- 优化:
- 目标代码生成:
词法分析
Target: 输入源程序,对构成源程序的字符串进行扫描和分解,识别出单词符号
语法分析
Target: 在词法分析的基础上,根据语法规则把单词符号串分解成各类语法单位(语法范畴)
推导与规约:derive 将规则展开 与 reduce 将短语规约为规则
最右推导, 最左规约:只推导最右侧的符号 + 逆向规约过程
最左推导, 最右规约:只推导最左侧的符号 + 逆向规约过程
语法树:
语义分析和中间代码生成
Target: 语义检查 + 中间代码翻译, 对各类语法单位按语言的语义进行初步翻译
四元式中间代码
优化
Target: 对前面产生的中间代码进行加工变换,以期在最后阶段能产生更为高效的目标代码
常见的优化有:
- 公共子表达式的提取
- 合并已知量
- 删除无用语句
- 循环优化
目标代码生成
Target: 把经过优化的中间代码转化成特定机器上的低级语言代码
目标代码有多种形式:
- 绝对指令代码:可立即执行的目标代码
- 汇编指令代码:汇编语言程序,需要通过汇编程序汇编后才能运行
- 可重定位指令代码:先将各目标模块链接起来,确定变量、常数在主存中的位置,装入主存后才能成为可以运行的绝对指令代码; 支持模块化的网络开发
Tips: 不同机器的绝对指令代码是不同的, 如果要适配不同的机器生成绝对指令代码就需要多种编译程序, 效率较低; 因此选择将编译程序生成一种中间代码的形式(汇编指令代码,与硬件无关)后续适配的任务交给汇编或链接完成
表格与表格管理
表格, 用来记录源程序的各种信息以及编译过程中的各种状况, 主要用于词法分析、语法分析、中间代码生成
常见的表格有:
- 符号表
- 常数表:登记各类常量值,不同类型的常量由不同类型的常量表进行维护
- 标号表:登记标号的定义与引用(少用了)
- 分程序入口表
- 中间代码表:四元式,三元组等
符号表
用来登记原程序中的常量名、变量名、数组名、过程名等,记录它们的性质、定义和引用情况
出错处理
如果源程序有错误,编译程序应设法发现错误,并报告给用户
错误类型:
- 语法错误:在词法分析和语法分析阶段检测出来
- 语义错误:一般在语义分析阶段检测
编译程序生成
普通使用高级语言编写编译程序,也可能编译程序核心部分常用汇编语言编写其它部分用高级语言编写
编译工具:
- LEX, 词法分析工具
- YACC, 自动产生 LALR 分析表