Arya

第一章 绪论 note
[+] 食指划伤真的使我绝望[+] 日不落教练今天放了日不落(哈哈哈哈第一章 绪论 note第一课 什么是编译计算...
扫描右侧二维码阅读全文
22
2019/01

第一章 绪论 note

[+] 食指划伤真的使我绝望
[+] 日不落教练今天放了日不落(哈哈哈哈

第一章 绪论 note

第一课 什么是编译

计算机程序设计语言分为三个层次:机器语言,汇编语言,高级语言

汇编:将汇编语言翻译成机器语言的过程
编译:利用编译器将高级语言(源语言)翻译成汇编语言(目标语言)或者直接翻译成机器语言(目标语言)的过程
Image1-1.png

那么在编译中,编译器是怎么发挥作用的呢很重要的作用
编译器在语言处理系统中的位置可以用这种方法表示(本来画的流程图,结果没显示出来,伤心

Image1-2.png

预处理器:把存储在不同文件中的源程序聚合在一起;把被称为宏的缩写语句转换为原始语句
可重定位(Relocatable):在内存中存放的起始位置L不是固定的,并不是在内存中的绝对地址(起始位置+相对地址=绝对地址)
加载器:修改可重定位地址;将修改后的指令和数据放到内存中适当的位置
链接器:将多个可重定位的机器代码文件(包括将库文件连接到一起;解决外部内存地址问题)
外部内存地址:一个文件中的代码可能会引用另一个文件中的数据对象或地址,而这些数据对象或地址相对于引用文件来说就是外部内存地址

第二课 编译系统的结构

编译的本质是一个翻译的过程,编译器的输入是高级语言程序(如:C语言程序),编译器的输入是汇编语言程序或者是机器语言程序

这里举一个例子:
In the room,he broke a window with a hanmmer.
现在我们要将这一句话翻译成中文,那么这里的英语就是源语言,汉语就是目标语言

翻译的过程大致可以分为两步:1、语义分析(Semantic Analysis)分析源语言获得句子的语义。2、生成目标语言

细分则可分为很多阶段,首先进行词法分析,获得每个词的词性;接下来进行语法分析,获得整个句子的结构;最后进行语义分析,获得每个短语在句子中充当的成分。这里用一张图来表示
Image2-1.png

中间表示形式独立于具体的语言,起到了一个桥梁的作用

我们这里所说的不同阶段,只是编译器的逻辑组织方式,在实际过程中,多个阶段可以被放在一起,如:语义分析的结果通常可以表示成直接代码的形式,因此语义分析器与中间代码生成器执行的阶段往往是放在一起实现的;也可以在执行语法分析的同时结合句子的语义进行语义分析,这一技术也叫语法制导翻译(Syntax Directed Translation)

词法分析

主要任务:从左向右逐行扫描源程序的字符,识别出各个单词,确定单词的类型,将识别出的单词转换成统一的机内表示——词法单元(token)形式
token :<种别码,属性值>

单词类型种别种别码
1关键字program、if、else、then、……一词一码
2标识符变量名、数组名、记录名、过程名、……多词一码
3常量整型、浮点型、字符型、布尔型、……一型一码
4运算符算数(+ - */ ++ --)
关系(> < ++ != >= <=)
逻辑(& |~)
一词一码或一型一码
5界限符; () = {} …一词一码

下面是一个例子
Image3-1.png

SLP表示(SRP表示)IDN(Identity)表示标志符NE(Not Equal)表示!=LP表示{,RP表示}CONST表示常量,INC表示++

语法分析(parsing)

语法分析器(parser)主要任务:从词法分析器输出的token序列中识别出各类短语,并构造语法分析树(parse tree)

赋值语句的分析树
position=initial+rate*60;
Image4-1.png

可以看出:
一个标识符或者是一个常数本身可以构成一个表达式,
一个表达式与一个表达式相结合可以构成一个更大的表达式
标识符、表达式与分号再以诶则可以构成一个赋值语句

变量声明语句
文法:由一系列规则构成

<D>-><T><IDS>;
<T>->int|real|char|bool
<IDS>->id|<IDS>,id

DDeclaration的首字母,表示声明语句
TType的首字母,表示类型
IDSIdentity Sequence的首字母,表示标识符序列

此处输入

int a,b,c;

则分析树如下
Image4-2.png

语义分析

主要任务:1)收集标识符的属性信息,2)语义检查

标识符的属性信息

  • 种属(Kind)
    简单变量、复合变量(数组、记录、……)、过程、……
  • 类型(Type)
    整型、实型、字符型、布尔型、指针型
  • 存储位置、长度
  • 作用域
  • 参数和返回值信息

下面为举的一个例子
Image5-1.png

语义阶段所收集的所有属性信息都被存放在一个符号表
符号表是用于存放标识符的属性信息的数据,符号表中还会存在字符串表,用来存放程序中用到的标识符和字符常数
符号表的name字段则被分为两个部分,一部分用来存放标识符在字符串表中的起始位置,领一部分用来存放标识符的长度
Image5-2.png

语义检查常见错误

  • 变量或过程未经声明就直接使用
  • 变量或过程名重复使用
  • 运算分量类型不匹配
  • 操作符操作数之间的类型不匹配
    1)数组下标不是整数

2)对非数组变量使用数组访问操作符
3)对非过程名使用过程调用操作符
4)过程调用的参数类型或数目不匹配
5)函数返回类型有误

中间代码生成和编译器后端

常用的中间代码表示形式

  1. 三地址码(Three-address Code)
  2. 语法结构树/语法树(Syntax Trees)

三地址码由类似于汇编语言的指令序列组成,每个指令最多有三个操作数(operand)

常用的三地址指令

序号指令类型指令形式
1赋值指令x = y op z
x=op y
2复制指令x = y
3条件跳转if x relop y goto n
4非条件跳转goto n
5参数传递param x
6过程调用call p,n
7过程返回return x
8数组引用x = y[i]
9数组赋值x[i] = y
10地址及指针操作x &= y
x=* y
*x=y

其中call p,np为过程名字,n为过程的参数个数;x = y[i]y为数组的名字,x表示数组的基地址,i表示数组的偏移地址

且地址可以具有如下形式之一:

  1. 源程序中的名字(name)
  2. 常量(constant)
  3. 编译器生成的临时变量

三地址指令的表示

  • 四元式(Quadruples)
    (op,y,z,x)
  • 三元式
  • 间接三元式(Indirect triples)

Image6-1.png

一个三地址指令序列唯一确定了运算完成的顺序

中间代码生成的例子
Image6-2.png

右侧为该程序对应的中间代码,冒号前面的数字表示指令的编号,此处从100~112,jjump的首字母

(j<,a,b,102)#若a<b,则跳转到102号指令,否则按顺序执行101号指令

目标代码生成:以源程序的中间表示形式作为输入,并把它映射到目标语言,中一个任务是为程序中使用的变量合理分配寄存器

代码优化:为改进代码所进行的等价程序变换,使其运行得更快一些,占用空间更少一些,或者二者兼顾

Last modification:January 28th, 2019 at 11:52 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment