特别声明:以下内容,源自 大学慕课 《编译原理》哈尔滨工业大学 陈鄞,文章经个人整理所得,仅供学习交流
先说几个必备的概念
机器语言是机器能直接识别的程序语言或指令代码,勿需经过翻译,每一操作码在计算机内部都有相应的电路来完成它,或指不经翻译即可为机器直接理解和接受的程序语言或指令代码。机器语言使用绝对地址和绝对操作码。不同的计算机都有各自的机器语言,即指令系统。从使用的角度看,机器语言是最低级的语言。 —— 百度百科
个人理解:
疑问:实际情况下,我们直接用二进制进行描述一些程序等是非常麻烦的,那为什么不直接转换成容易理解的十进制呢?然后运行的时候再转为二进制呢?而出现了八进制或者十六进制这样的概念
答案:首先直接使用二进制当然是比较麻烦的,枯燥,且很长很长,所以转换成一些更高的进制,就可以大幅度缩小长度,而十进制描述虽然符合人的行为习惯,容易被人接受,但是直接与计算机结构关联却有一些不太合适,而八进制或者十六进制分别是 2^3 以及 2^4 这一点使得,进制之间的转换会比较容易,同时8位二进制数为一个字节,而两位十六进制刚好可以表示一个字节,例如,F1 对应二进制为 11110001,同样可以看到,每一位十六进制数,也转换成了四位二进制数
汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。[1] —— 百度百科
简单概括:低级,不具有移植性,能直接访问计算机硬件,效率高,占用资源少,同时使用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。如上图的MOV X,2 同样代表赋值语句 X = 2
高级编程语言(High-level programming language)是高度封装了的编程语言,与低级语言相对。它是以人类的日常语言为基础的一种编程语言,使用一般人易于接受的文字来表示,有较高的可读性,以方便对电脑认知较浅的人亦可以大概明白其内容。 —— 维基百科
这没什么好说的,就日常编程所做的,x = 2
Em 铺垫好像是长了点哈
从上图可知,内容经过编译这个过程以后,从高级转换到低级的形式(从人乐意看的内容转换成机器乐意看的内容)
编译的定义:将高级语言(源语言)翻译成汇编语言或机器语言(目标语言)的过程
前面我们说了编译的一个基本概念,而为了建立可执行的目标程序,除了编译器外,我们还需要一些其他的程序进行配合,下图就是一个语言处理的基本过程,注意留意编译器所处的位置
简单介绍一下流程中的内容
与源语言相关,字符流——词法分析器——词法单元流——语法分析器——语法树——语义分析器——语法树——中间代码生成器
与目标语言相关,中间表示形式 ——机器无关代码优化器——中间表示形式——目标代码生成器——目标机器语言——机器相关代码优化器——目标机器语言
上述字体加粗的为后端部分
从左向右逐行扫描源程序的字符,识别出各个单词,确定单词的类型,将识别出的单词转换成统一的机内表示——此法单元(token)形式
token:<种别码,属性值>
单词类型 | 种别 | 种别码 | |
---|---|---|---|
1 | 关键字 | program、is、else、then、… | 一词一码 |
2 | 标识符 | 变量名、数组名、记录名、过程名、… | 多词一码 |
3 | 常量 | 整型、浮点型、字符型、布尔型、… | 一型一码 |
4 | 运算符 | 算数(+ - * 、 ++ --)关系(> < == != >= <=)逻辑(&|~) | 一词一码或一型一码 |
5 | 界限符 | ; () = {} … | 一词一码 |
种别码本身应该是一个整数,为了上例中为了直观,使用了宏定义的形式
语法分析器(parser)从词法分析器输出的token序列中识别出各类短语,并依据这些规则所体现出的语言构造的层次性,用各记号的第一元建成一种树形的中间表示
从下往上看,一个标识符 rete * 一个数字60 组成了一个新的表达式,而它又 + 另一个标识符 initial 组成了一个更大的表达式,接着通过 = 与标识符 postion 组成了最终的赋值语句
D:declaration(声明)
T:type(类型 )
IDS:identifiers sequence(标识符序列)
文法在图片中有提到,即 ① 声明 = 类型 + 标识符序列 + ; ② 类型 = int 或 real 或 char 或bool ③ 一个标识符 id 本身 可以构成一个标识符序列,一个标识符序列 + , + 标识符 id 可以构成一个更大的标识符序列
这样一看这个图就很直观了
简单变量、符合变量(数组、记录 …)、过程、…
整型、实型、字符型、布尔型、指针型、…
一个例子就明白了:
例如,创建一个实型数组x ,所以其相对地址为 0 ,其含有 8个元素,同时假设一个实型变量占用 8 个字节,这个数组占据了0-63的地址 ,所以下一个 整型变量 i 只能从 64 开始,而假设一个整型变量占用 4 个字节,j 就需要从64 + 4,68开始
参数个数、参数类型、参数传递方式、返回值类型
这些收集到的标记符属性信息,都会被存放到一个叫做符号表的数据结构中,其中有着例如 TYPE、KIND 等多种属性,同时符号表通常带有一个字符串表如下图
NAME = 标识符在字符串表中的起始位置 + 长度
中间代码生成:经过语法分析和语义分析后,许多编译器为源程序产生更低级的显示中间表示,可以理解为一种抽象的程序
三地址码 (Three-address Code) (在这里进行简单介绍)
语法结构树/语法树 (Syntax Trees)(后面详细讲,这里不涉及)
说明一下,右边,冒号左边的数字代表指令的编号,例子中从100取到112,j 代表 jump
如何看这个程序做了什么呢,例如第一行:100:(j<,a,b,102) 就是说,当 a < b 的时候 跳转到 102 指令,若不满足就继续执行 101 指令,找这种方式,对应着代码看,这个例子是非常直观的
代码优化
① 编译是对( ) 【正确答案:C】
② 用高级语言编写的程序经编译后产生的程序叫( ) 【正确答案:B】
③ ( )不是编译程序的组成部分 【正确答案:C】
④ 源程序是句子的集合,( )可以较好地反映句子的结构 【正确答案:B】
⑤ 编译程序是一种( ) 【正确答案:B】
⑥ 按逻辑上划分,编译程序第三步工作是( ) 【正确答案:A】
⑦ 编译程序中语法分析器接收以( )为单位的输入 【正确答案:A】
⑧ 编译过程中,语法分析器的任务就是( ) 【正确答案:B】
⑨ 语法分析时所依据的是( ) 【正确答案:A】
绪论部分的知识比较少,主要是对编译原理的基本知识进行了一定的总结概括,以及一些基本知识的入门,让我们对编译有一个初步的概念,更加详细的课程在后面的章节,后面再更新,最近在忙着写一些东西,可能更新文章会慢一些,希望大家见谅,再次感谢大家的支持,谢谢!!!