编译原理
↓源程序 对应的自然语言
出错处理
|
表格管理(数据结构)
|
1.词法分析器 识别单词
↓单词符号 ↓
2.语法分析器 分析句法
↓语法单位 ↓
3.语义分析和中间代码分析器 初步翻译
↓中间代码 ↓
4.代码优化器 译文润色
↓中间代码 ↓
5.目标代码生成器 正式翻译
↓目标代码
基本概念:
- 预备
- 字符(字母)
- 字母表
- 字符串(句子、行)、空串、由空字符组成的串
- 字符串长度
- 串的连接运算
- 字符串的前缀、真前缀、后缀、真后缀
- 字符串的公共前缀、最大公共前缀、公共后缀、最大公共后缀
- 子串、公共子串、最大公共子串
- 两个字母表的乘积运算
- 字母表的幂运算
- 字母表的闭包运算(*、+)
- 语言
- 文法
- 定义
- 类型
- 0型 ——短语文法
称 G=(VT,VN,S,P )是一个0型文法,如果它的每个产生式 α→β是这样的结构,α∈(VN∪VT)* 且至少有一个非终结符,而β∈(VN∪VT)*
-
-
- 1型 ——上下文有关文法
-
G的任何产生式 α→β 均满足:|α| <|β|(其中 |α| 和 |β| 分别为 α 和 β 的长度;仅 S→ε 除外)
-
-
- 2型 ——上下文无关文法
-
G的任何产生式为:A→β,A∈VN ,β∈(VN∪VT)*
-
-
- 3型 ——右线性文法,另一种形式称为左线性文法。
-
——等价于正规式,也称为正规文法
G的任何产生式为:A→aB或A→a,其中a∈VT,A、B∈VN(右)
G的任何产生式为:A→Ba或A→a,其中a∈VT,A、B∈VN(左)
- 文法和语言的形式化定义
- 如何描述一种语言?
- 如果语言是有穷的(只包含有穷多个句子),可以将句子逐一列出来表示
- 如果语言是无穷的,找出语言的有穷表示
- 语言的有穷表示有两个途径:
- 生成方式(文法):
- 如何描述一种语言?
语言中每个句子可以用严格定义的规则来构造
-
-
- 识别方式(自动机)
-
用一个过程,当输入的一任意串属于语言时,该过程经有限次计算后就会停止并回答 “是”,若不属于,要么能停止并回答 “不是”,要么永远继续下去
- 上下文无关文法及其语法树
- 句型的语法分析树的构造
- 规范推导——最右推导
- 规范句型
- 上下文无关文法的语法树
- 二义文法
- 定义
- 解决方案
- BNF:
- 句型分析
- 语法树构造过程
- 自上而下的语法分析
- 自下而上的语法分析——规约
- 句型分析的有关问题
- 短语、直接短语和句柄
- 语法树与短语的关系:
语法树子树的末端结点符号串即使语法树所描述的句型的短语;
简单字数(只有父子两代)的末端节点符号串即使直接短语;
做做简单子树的末端节点符号串即是句柄;
- 正规文法:
- 正规式:
- 正规集
- 有穷自动机
- 确定有穷自动机:DFA(deterministic finite automaton)
- 非确定有穷自动机:NFA(nondeterministic finite automaton)
- 状态转换图:
- 最左推导:
- 左递归
- 中间代码:
- 逆波兰式:
- DAG:无循环有向图
- 属性文法:在上下文无关文法的基础上,为每个文法符号(终结符或终结符)配备若干相关的 “值”(称为属性)——属性翻译文法
- 抽象语法树:
- 三地址代码:
由下面一般形式的语句构成的序列:
x := y op z
其中: x、y、z 为名字、常数、或编译时产生的临时变量;
op代表运算符号。
每个语句的右边只能有一个运算符
例:x+y*z
T1 = y * z
T2 = x + T1 其中T1 T2 为临时变量
- 三元式
- 间接三元式
- 四元式
1.词法分析:
- 输入源程序,对字符串扫描分解、识别出单词(或单词符号、简称符号)——实际上是根据不同单词的构词规则,识别单词及其类型。
- 任务:输入源程序,对字符串扫描分解、识别出单词(或单词符号、或简称符号)。 如:基本字(for、while)、标识符、常熟、算符、界符(标点符号、左右括号等)。
例: for(i= 1; i<=100; i++)
基本字(关键字):for
运算符:=、<=、++
间隔符: ; ();
标识符:i
整常数:1、100
- 注意:
- 单词是语言的基本组成部分,是人们理解和编写程序的基本要素
- 识别和理解这些要素无疑是翻译的基础。如何讲英文翻译成中文是一样的,如果对英语单词不理解,则谈不上正确的翻译
- 理解:
- 一种高级语言的单词(关键字、标识符、运算符等)是如何规定的—————依循原则:语言的词法规则(或构词规则)
- 因为所进行的词法分析是利用程序自动完成的,那么,对于词法规则必须有形式化的描述,才可能设计出词法分析程序,所以必须有词法描述工具————描述工具:正规式和有限自动机
- 词法分析器的设计思想:
- 预处理——对文本文件进行 “规范化”,单词之间只用一个空格或分隔符间开或删除注释等有关的处理
- 针对一些特殊的单词识别,采用一种 “超前搜索技术”。在处理时,必须向前多读一个字符,以确定是 > 还是 >=
- 在进行单词识别时所需存放数据的数据结构
- 通常,一次读取文本中的一行信息(以回车换行为标记),用于存放这行符号的存储单元,称为 输入缓冲区(字符串变量)
- 进行预处理,实现符号串的规范化,并存放到另一个存储单元中(称为扫描缓冲区)
- 从扫描缓冲区,依次读字符实现不同类型单词的识别,并存放单词
- 词法分析器的出路步骤:
- 词法分析器设计方法:
- 采用状态转换图描述构词法,并实现识别。——手工实际词法分析程序
- 采用正规表达式描述词法,然后将正规表达式转换为自动机(利用正规式和自动机的等价性),最后实现单词识别——自动设计词法分析程序
- 技术:
- 概况:
文法
↓
正规式——单词的形式化描述工具
↓
自动机——单词的形式化识别系统 确定有穷自动机DFA
↓
非确定有穷自动机NFA
-
- 正规文法——程序设计语言的单词都能用正规文法描述
- 正规式——用于描述正规文法的所有句子
- 正规式的运算律
- 正规式的等价
- 正规式和正规文法的转换
- 正规式和正规文法之间的等价转换
- 转换规则 文法产生式 正规式
- 规则① A->xB B->y A=xy
- 规则② A->xA | y A=x* y
- 规则③ A->x A->y A->x | y
- 转换规则 文法产生式 正规式
- 正规是与正规集之间的等价转换
- 正规式和正规文法之间的等价转换
- 有限自动机
- 有限自动机理论:
- 自动机的图形描述——状态转换图
- 利用构词法生成状态转换图
- DFA
- DFA是一个五元式:
- DFA的矩阵表示
- DFA识别的语言
- DFA与正规集的等价性
- NFA
- NFA是一个五元式:
- NFA的矩阵表示
- NFA的状态转换图
- NFA接受的语言
- 存在的缺点
- DFA与NFA的等价转换
- 不具有 ε动作的 FA——子集构造法
- 具有 ε动作的FA
- 正规式与有限自动机的等价性
- 确定有限自动机的化简
- 正规文法与有限自动机的等价行(自学)
2.语法分析:
- 在词法分析的基础上,根据语言的语法规则,把单词符号串分解成各类语法单元(语法范畴)
- 任务:在词法分析的基础上,根据语言的语法规则,把单词符号串分解成各类语法单元(语法范畴)
如:短语、子句、句子(语句)、程序段、函数、程序等。通过语法分析,确定整个输入串是否构成语法上正确的 “程序“。
- 注意:识别源程序中,每个语句或语句块是否复合该语言所规定的语法原则?
- 一种语言规定了什么语法规则————依循原则:语言的语法规则
- 如何判定一个语句是否正确————描述方法:上下文无关文法
- 语法分析器的基本思想:
- 本质:
语法分析器的工作本质上就是按文法的产生式,识别输入符号串是否为一个 句子,并建立一颗与输入串相匹配的语法分析树
-
- ①信息输入:
语法分析器按文法的产生式识别输入串是否成为一个句子,其中输入串是指由单词符号(文法的终结符组成)组成的有限序列
-
- 正确语句的识别
对于一个文法,给定一串(终结)符号,如何判断他是不是该文法的一个句子?
实际上判断:能否从文法的开始符号推导出这个输入串。或者,就是要建立一颗与输入串相匹配的语法分析树
-
- 识别方法:
自顶向下
自底向上
- 技术:
- 概况:
不确定的
自顶向下分析法 递归下降分析法
确定的
预测分析法LL(1)
语法分析的方法: 简单优先分析法
优先分析法
算符优先分析法
自低向上分析法 LR(0)分析法
SLR(1)分析法
LR分析法 LR(1)分析法
LALR(1)分析法
-
- 采用上下文无关文法。将上下文无关文法作为语法分析的基础
- 自顶向下分析法
- 判定一个句子是否符合语法规则处理要点
- 由根向下构造语法树
- 构造最左推导
- 推导出的终结符是否与与当前输入符匹配
- 自上而下分析法面临的问题
- 推导过程出现大量回溯现象
- 推导过程出现死循环
- 难以知道输入串中
- 解决——>修改文法
- 消除左递归
- 消除回溯,提取左因子
- 确定的自顶向下分析条件
- 首字符集(FIRST)
- 后继符号集(FOLLOW)
- 条件①:文法不含左递归
- 条件②:对于文法中的每个非终结符A的各个产生式的候选首字符集两两不相交。
- 条件③:
- 判定一个句子是否符合语法规则处理要点
- LL(1)文法:
- 判断
- 分析过程
- 提供的设计程序的方法:
- 设计-递归下降分析程序实现语法分析
- 设计-预测分析程序实现语法分析
- 自下而上分析法
- 基本思想
- 基本问题
- 分析法包括两种方法:
- 优先分析法
- 简单优先分析法
- 算符优先分析法
- LR分析法
- LR(0)分析法
- SLR(1)分析法
- LR(1)分析法
- LALR(1)分析法
- 优先分析法
- 算符优先分析法
- LR分析表
- LR方法的基本思想
- LR(0)分析法
- SLR(1)
3.语义分析与中间代码生成:
- 对语法分析所识别的各类语法范畴,分析其含义,并进行初步翻译(产生中间代码)
- 任务:对语法分析所识别的各类语法范畴,分析其含义,并进行初步翻译(产生中间代码)
- Def:将一个符合语法规则的语句,等价转换另一个语言描述语句。
- 注意:实际上就是翻译,你需要知道该语句所要表达的意义(语义)
- 工作:
- 静态语义检查:变量是否定义,类型是否正确等———依循原则:语言的语义规则
- 若语义正确,则进行中间代码翻译————描述方法:属性文法
- 技术: ①类型检查
- 概况: (静态语义审查) ②控制流检查
静态语义分析 ③一致性检查
④上下文相关性检查
语义分析的工作 ⑤名字的作用域检查
动态语义处理
语义的形式化描述——属性文法
-
- 语义分析: 过程
依赖图 树遍历的属性计算方法
属性的计算顺序
语法制导 属性的计算过程 L-属性文法可用于一边扫
翻译: 及其实现 一边扫描的 描的自上而下分析
翻译模式 处理方法 S-属性文法适合于一边扫
自顶向下翻译 描的自下而上分析
-
-
- 属性文法
- 中间代码
- 作用
- 编译方法:语法制导翻译
- 形式:
- 逆波兰式——后缀式
- 图表示法——DAG和抽象语法树
- 三地址代码——四元式,三元式,间接三元式
- 逆波兰式——后缀式
- 基于语法制导的翻译
- 数值表达式的中间代码描述
- 简单赋值表达式的中间代码描述
- 逻辑表达式的中间代码描述
- 控制表达式中布尔表达式的翻译
- While循环的中间代码描述
- For循环的中间代码描述
- 数组元素的赋值过程的中间代码的描述
-
———————————————————————————————————————
4.优化:
- 对中间代码加工变换,以期产生更为高效(时间和空间)的目标代码,公共子表达式的提取、循环优化、删除无用代码等。
- 任务:对中间代码加工变换,以期产生更为高效(时间、空间)的目标代码
- 采用方法:公共子表达式的提取、循环优化、删除无用代码
- 依循原则:程序的等价变换规则
- 技术:
5.目标代码生成:
- 把中间代码(或优化后)变换成特定机器上的低级语言代码
- 任务:把中间代码(或优化后)变换成特定机器上的低级语言代码
- 生成过程非常复杂:
- 最后的翻译,有赖于硬件系统结构和机器指令含义,设计硬件功能部件的应用,机器指令的选择,各种类型变量的空间分配,以及寄存器和后院寄存器的调度等。
- 如何产生足以发挥硬件效率的目标代码是一件非常不容易的事情
- 目标代码形式:
- 绝对指令代码 → 可立即执行
- 可定位指令代码 有→ 借助连接装配程序把各目标模块连接在一起,确定程序变量(或常熟)在主存中的位置,装入内存中指定的起始地址,使之成为绝对指令代码(大多数编译程序采用)
- 汇编指令代码 → 汇编器汇编之后执行
- 技术:
表格与表格管理:
- 设计编译程序,需要存放有关信息的数据结构,主要采用线性数据结构——表格及表格管理
- 一系列的表格,用以登记源程序的各类信息和编译各个阶段的进展情况。合理设计表格是编译程序构造的一个重要问题
- 其中最重要的是 符号表:登记源程序中出现的每个名字及其各个属性。
- 当扫描器是被一个名字(标识符)后,就把该名字填入到符号表中。但此时不能完全确定该名字的属性,其各种属性要在后续的各个阶段才能填入。因此编译各阶段都涉及到构造、查找或更新有关表格。
出错处理:
- 不仅能对书写正确的源程序进行编译,而且应能对出现的错误进行处理,若源程序有错,应设法发现错误,并把有关信息报告给用户
- 专门由一组程序完成,出错处理程序。
- 绝大多数的错误可在编译的前三个阶段检测出来:
- 语法错:不符合词法规则(“非法字符“)、或不符合语法规定(”括号不匹配“、”缺少;“等。
- 语义错:不符合语义规则,语义分析时检测出来(静态语义)。有事要到运行时才能检测出来(动态语义)。如:说明错误、作用域错误、类型不一致错误等。