编译原理部分学习
欢迎建议与讨论。
文章目录
前言
这是我在b站听哈工大老师讲的编译原理,只听了前四章,主要内容是词法分析,语法分析的经典算法 。
我的目标是能生成自己想要的AST树以用于研究,没有继续往后看。 完整课件在b站这个视频下边的评论里
一、第一章 概述
1 编译概述
1 高级语言到低级语言是编译。高级语言就是源语言。
2 源程序 经过预处理,到编译器。链接器就是把用到的程序链接起来放在一起,比如把其他文件中的程序放在需要的地方。
3 编译系统结构
3-1 英语就是源语言,汉语就是目标语言。我们分析源语言,获得句子的语义,这一过程就是语义分析。英语一般找动词,动词很重要。
汉语和英语之间有一个中间表示,中间表示很重要,独立于具体的语言,不论汉语法语还是汉语日语,同一个中间表示就可以。
3-2 可重定位:起始位置+相对地址=绝对地址。
3-3 划分句子成分,比如介词短语一般做状语或者补语。动词做谓语动词。这个划分句子成分,关键识别出句子中的各种短语,这过程叫做语法分析(Syntax Analysis)
3-4 识别各种短语,根据词性。一个代词本身可以是一个名词短语。因为识别短语,所以要识别每个单词的词性,这一过程就是词法分析。
3-5 很明显,先分析词法,后语法,后语义分析。
3-6 词法分析:对词。通过词法分析获得单词的词性。
语法分析:识别短语,获得句子结构。
语义分析:根据句子结构,分析短语在句子中充当什么成分,从而确定各个名词和核心谓语动词之间的关系。
最后给出中间表示程序。
3-7 编译器结构
2 词法分析概述
1 词法分析、扫描
确定单词类型,将识别出的单词换成词法单元(token)形式。
token<种别码,属性值>
2 单词类型
关键字 if 一词一码、
标识符 变量名a 多词一码、
常量 整型等 一型一码、
运算符 + 一词一码、界限符 { 一次一码
3 token
3 语法分析概述
1 语法分析器(parser)从词法分析器输出的token序列中识别各类短语,并构造语法分析数(parse tree)
2 赋值语句的分析树
3 标识符就是各种变量。
4
4 语义概述
1 主要任务:
1 收集标识符的属性信息:种属
2 语义检查:变量或过程未经声明就使用等
5 中间代码生成和编译器后端
1 中间表示形式:三地址码和语法结构树。三地址码由类似于汇编语言的指令序列组成,每个指令最多有三个操作数。
op是操作的意思。操作符就是核心动词。
2 中间代码生成的例子
3 目标代码生成:以源程序的中间表示形式作为输入,并把它映射到目标语言。目标代码生成的一个重要任务是为程序中使用的变量合理分配寄存器。
4 代码优化:运行快,占用空间少。
二、第二章 语言及其文法
1 基本概念
1 字母表上的运算。字母表上的乘积,字母表的n次幂,长度为n的符号串构成的集合。
字母表的正闭包:长度为正数的字符串构成的集合
字母表的克林闭包:任意符号串构成的集合
2 串 :是字母表中符号的一个有穷序列。串的长度 |s|就是字符串的长度。
串上的运算 连接:x=dog,y=house,xy=doghouse.
幂运算:s=ba ,s^2=baba
2 文法的定义
1 自然语言的例子:
2 文法的形式化定义:
3
E表示的是 表达式,
3 符号的约定:
3 语言的定义
1 推导 归约
2 经过0步推导就是没有推导,就是它本身。
3
推导是产生式的右替换左部。归约是产生式的左替换右。我喜欢用换成来说,即统统换成右边的;归约就是统统换成左边的。
4 偏定词串是该语言的句子:
5 句型和句子
句子是不包含非终结符的的句型。
6 语言的形式化定义:无穷语言的有穷表示形式。
4 文法的分类
1 0型文法
无限制文法,
2 1 型文法
3 2 型文法
4 3 型文法
左线性文法是左边为非终结符,右线性文法是右边为非终结符。
5 四种文法的关系:是逐级约束的。上下文约束的是会有左右东西限制。
5 cfg分析树
1 上下文无关文法的分析树。
2 分析树是用来描述句子结构的。
2-1 短语
2-2 二义性文法:有两个意思,计算机不喜欢这样的。
引入消灭歧义规则:每个else和最近的尚未匹配的if匹配。
三、第三章 词法分析
1 正则表达式
1 语言是一个集合。
RE是正则表达式。
2 正则表达式的定义
3 c语言无符号整数的RE
4 可以用RE定义的语言就是正则语言
2 正则定义
1 正则定义
2
3 有穷自动机
1 FA的表示
状态0遇到符号A的时候会变到状态1
2 FA定义接收的语言
3 接收的语言是啥呢?
4 最长字串匹配原则。
4 有穷自动机分类
1 有穷自动即分类
2
3 一个DFA
S:0,1,2,3
第二个:a,b
第三个:
4 非确定的有穷自动机
5
NFA比DFA直观。好像DFA的每个状态都会有指向的状态。而NFA没有。
6
不需要接收字符从a到b,但是收到的符号(有向边)就变化了。代表了若干个0连接若干个1连接若干个2.
7 带有和不带有空边的NFA的等价性。
8 DFA的算法实现:
接收状态集F。
5 从正则表达式到有穷自动机
1 从RE不容易到DFA,但是可以先到NFA。
2 根据RE构造NFA
3 例子
6 从NFA到DFA的转换
1 这一个感觉全是根据转换表来处理。
dfa:根据状态表,从大a开始,通过a进入大ab集合。黄字,dfa的每个状态都是一个由nfa中的状态构成的集合,即nfa状态集合的一个子集。那么大ab遇到a时,状态合集时大ab和空集的集合。遇到b时,形成大ab集合的并集即大bc和空集的并集。
2 带空边的nfa
3 子集构造法
7 识别标识符的dfa
1
本身通过正则表达式dfa和nfa一样
2 无符号数
3 识别各种进制的东西:
我们把状态一的token表示出来,(种别码,属性值)。
把树合成为森林。
4 识别注释的dfa
5 识别token的dfa
关键字也是字符串,识别出来后,在关键字表中查看,发现存在就把他置为关键字。
四、第四章 语法分析
1 自顶向下分析概述
1 分析词串。根据给定的文法,识别句子中的短语,并构造分析树。
2 自顶向下的分析,根节点就是句子的开始符号,叶节点就是单词。
3 回答以上两个问题
4
5 匹配完一个后箭头向右移动
恰好自左至右的完成目标完成了整个树,没有的就是空串。
6 计算机采用递归下降分析。
需要回溯的分析器称为不确定的分析器。可以不回溯的分析器称为预测分析。
2 文法转换
1 自顶向下不一定都适合。
2 消除直接左递归。就是把左递归变成了右递归。
3 LL1文法
1
2不需要回溯,预测分析。ll1文法。
预测分析法的工作过程:
从文法开始的符号除法,在每一步推导过程中根据当前句型的左非终结符A和当前输入符号a,选择正确的A产生式。为保证分析的确定性,选出的候选式必须是唯一的。
s_文法:
当前非终结符后边能跟啥。
产生式的可选集:输入符号的集合。遇到这些输入符号的时候就可以选择这些产生式。比如下图,只有用到a这个终结符时,才能用这个产生式。如果右边时空集,需要输入为follow集才能用这个产生式。
串首终结符:
以上一个为例子,如果没有空集,first集合就是bd,如果有了空集,first集合就是bdac吧。
计算first集合和follow集合:
4 first集和follow集
1 例题
先选能直接看的见的,就是以终结符打头的。就是2,4,5,。然后再看非终结符的。
2 follow集合的计算
这里根据的就是E本身就是一个句型,就是句型的最右符号。
3 计算select集
这就是预测分析表,防止了晦朔。
相同左部的select集合不相交。
当E碰到(和id时候,选用产生式1;
5 LL1文法的分析方法
1 从左到右扫描, 最左推导。
2 递归预测分析法。
3
写出产生式右部为空的,select集。
getnext是词法分析的东西,选一个token进来,对他进行语法分析。
以下是扩展解释:
非递归的预测分析
总结
1 完整课件在b站这个视频的评论里
2 词法分析可以用正则语言实现。语法分析需要递归下降算法。