个人笔记——编译原理(1)

目录

什么是编译

编译系统的结构

词法分析概述

语法分析概述

语义分析概述

收集标识符的属性信息

语义检查

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

三地址码

常见的三地址指令

目标代码生成

​编辑

代码优化


什么是编译

编译:将高级语言翻译成汇编语言或机器语言的过程

源程序可能是在不同的模块,且存放到不同的文件中

预处理器:把存储在不同文件中的源程序聚合在一起,把被称为宏的编写语句转换为原始语句

在源程序通过编译器和汇编器的处理生成了可重定位的机器代码

可重定位(Rclocatable)在内存中存放的起始位置L不是固定的(相对地址)

        起始位置 + 相对地址 = 绝对地址

加载器:修改可重定位地址:将修改后的指令和数据放到内存中适当的位置。

大型程序经常分成多个部分进行编译,可重定位的机器代码可能要与其他可重定位目标程序(库文件)进行链接生成可支执行代码,这一工作是通过链接器进行完成的

链接器:

将多个可重定位的机器代码文件(包括库文件)连接在一起

结果外部内存地址问题

外部内存地址是指一个文件中的代码可能会引用另一处文件中的数据对象的过程,那么这个数据对象和过程的地址相对于这个文件来说就是外部地址。

编译系统的结构

编译器的本质是一个翻译的过程

通过词法分析分析出句子中单词的词性,或者说词类

然后进行语法分析,从而识别出句子中的各类短语,获得句子的结构

接下来进行语义分析,分析短语中在句子中充当什么成分从而确定各个名词成分的关系。

最后给出中间表现形式

编译器结构和上面英语例子相类似,都是经历这几个阶段。

这里指的阶段是编译器的逻辑组织方式,在实现过程中多个阶段可能会组合在一起

词法分析概述

词法分析主要是将扫描的字符识别成各个单词,确定了单词的类型将识别出的单词转化成统一的机内表示——词法单元(token)形式

token:<种别码,属性值>

每一个token对应一个单词

语法分析概述

语法分析器的主要任务是从词法分析器输出的token序列中识别出各类短语,并构造语法分析树。

语法分析树描述了句子的语法结构。

例子:赋值语句的分析树

例子2:变量声明语句的分析树

<D>:表示声明语句

<T>:表示类型 int | real | char | bool

<IDS>:表示标识符序列

(课堂小问题:如何根据语法规则为输入句子构造分析树?后面课程解答)

语义分析概述

语义分析的主要任务:

收集标识符的属性信息

        1.种属(Kind)

                简单变量、复合变量(数组、记录......)、过程......

        2.类型(Type)

                整型、实型、字符型、布尔型、指针型.....

        3.存储位置、长度

         这个代码片段声明了一个实型数组x,所以x的相对地址就是0

         假设这个实型变量占8个字节,x中有8个元素,一个整型占4个字节所以i的相对地址就是64,j的相对地址就是68,以此类推。

        4.值

        5.作用域

        6.参数和返回值信息

        

存放的符号信息都存放到符号表中。 

每一个字段都表示一个属性。

符号表通常带有一个字符串表,用来存放程序中用到的标识符和字符常数

符号表一个用来存储字符的起始位置,另一个存放字符的长度。

符号表中为什么要设计字符串表这样一种数据结构?

                不同标识符的NAME字段长度往往不同,如果以变长存储,就会使得符号表的查询效率降低,增大符号表管理的难度; 而若是以定长存储,很显然必须为该字段按照最大长度分配空间,而造成空间的严重浪费。

语义检查

        如变量或过程未经过声明就使用

        便变量或过程名重复声明

        运算分量类型不匹配(比如一个数组名字和过程名字相加是没有意义的,数据类型转化等)

        操作符与操作数之间的类型不匹配

                数组下标不是整数

                对非数组变量使用数组访问操作符

                对非过程名使用过程调用操作符

                过程调用的参数类型与数目不匹配

                函数返回类型有误

        ......

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

源程序的中间表示可以有多种形式

语法结构树简称语法树,这里的语法树和前面讲的语法分析树不是一回事(第八章介绍)。

三地址码

常见的三地址指令

地址可以具有如形式之一

        程序中的名字。

        变量。

        编译器生成临时变量。

因为地址都存放在字符表中,所以通过名字就可以找到地址。

第一个指操作符,后面的指操作数。

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

例子:

对应的分析数

对应的中间代码 

最后面的是跳转指令,跳转到哪个地方

当a<b 则跳转到102号指令,如果a不小于b则继续执行101号指令

其他以此类推。

编译器如何根据分析树生成执行代码的呢?(视频第六讲才会讲,或者是第六个笔记)

目标代码生成

目标代码生成的一个重要任务是为程序中使用的变量合理分配寄存器

代码优化

(代码优化详细内容将在第八章或第九章介绍)

总结:这一课我们了解了基本的编译过程,通过这些编译过程我们能大概知道编译器是如何执行,有什么步骤执行,各个部分的简单概述。

学习链接:【编译原理】哈工大公开课(高清版)_哔哩哔哩_bilibili

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值