第一部分 --- 词法分析器的设计
1.在进行词法分析之前,源程序仅仅只是一串字符序列,没有什么别的含义
2.词法分析:对源程序字符串的字符一个个扫描,并根据工具生成一个个字符
生成了字符之后就是语法分析,将一个个字符组成句子
组成了句子之后就是语义分析,让原本只是形式结构的句子具有意义
词法分析器作为编译程序的一个结构,自然会有与编译程序其它的结构的交互,以及自己与外界的接口
1. - 表示这个单词符号没有自身的值,它仅由种别编码来表示
2. ‘m’ 表示m符号用它对应的ascii码值的二进制符号表示
1.但不一定作为单独的一遍扫描
2.我们用语法分析来推动词法分析,也就是说当我们在进行语法分析的时候需要单词了,我们就进行词法分析获取对应的单词并将单词返回给语法分析,就这样语法分析词法分析交替执行,最终对整个源程序分析完毕
1.在进行词法分析和语法分析的时候,都会和符号表打交道,将一些数据和信息记录在符号表中
第二部分 --- 词法分析器的结构![](https://img-blog.csdnimg.cn/f071d6f31187488392191f057cfad8fd.png)
1.在进行词法分析时,首先调用扫描器,接着扫描器调用预处理子程序,在预处理子程序中将源程序输入的输入缓冲区中,然后预处理子程序从输入缓冲区中读取源程序字符串并对源程序字符串进行预处理,处理完毕后将规范化的源程序字符串输入到扫描缓冲区中
接着扫描器结束预处理子程序的调用,并对扫描缓冲区中的源程序字符串进行读取单词的操作,读取后输出读取到的单词符号
1.在扫描缓冲区中我们有一个起点指示器指向单词的开头,还有一个搜索指示器指向单词的结尾
2.为了避免出现单词过长导致搜索指示器找不到单词的结尾,我们将扫描缓冲区分为两个半区来使用,同时规定每个单词的最大长度就是一个扫描缓冲区半区的长度(两个半区的长度一样)
第三部分 --- 超前搜索![](https://img-blog.csdnimg.cn/fe578f90fd2e4385ab646896a5be78c3.png)
1.有些时候,在扫描过程中有的字符(设为A)在被扫描后是无法确定其种类的,我们必须在扫描完这些字符A后继续往后面扫描,直到扫描到特定字符时,我们才能够判定这些字符A的种类
我们称这种扫描为超前搜索
1.所有的基本字都是保留字,我们会在保留字表中存储它们,当词法分析器扫描到它们的时候就会自动去保留字表中获取其种类和值
2.规定无法使用基本字作为标识符
第四部分 --- 状态转换图
1.从1结点经过弧a到2结点的意思就是:状态1在输入了字符a后转换为了状态2
2.状态转换图中的结点表示状态(有限个),弧表示输入。然后状态图中只有一个初态,以及至少有一个的终态(终态用双圆圈来表示)
3.状态转换图为有限方向图
1.关于状态转换图例子中的那个终态的右上角的 * 表示的意思是终态读入的字符不属于我们要读取的字符串,需要将这个字符退回
1.空白符其实指的就是空格
2.在字母那条路径上我们将识别出所有的标识符,此时每识别出一个标识符我们都需要加上一个额外的判断,来分辨这个标识符就是是普通的标识符还是关键字,即:将我们得到的标识符在保留字表中进行查找,如果在表中找到了,那么这个标识符就是关键字,如果找不到的话,这个标识符就是普通的标识符。
第五部分 --- 状态转换图的实现![](https://img-blog.csdnimg.cn/0d999a8b7c3b4848b359bff0afef0b26.png)
1.终态结点表示我们已经识别出了某个单词,此时我们要将这个单词返回(return),返回时要将识别出的单词的种别和单词自身的值一起返回。
1.回调就是回退的意思
2.标识符插入到符号表中,常数插入到常数表中
1.code变量中存储的是单词的种别编码,value变量中存储的是单词的值
2.如果单词是用户自己定义的标识符的话,则这个单词的种别编码为0,且这个标识符要插入到符号表中,返回时返回种别编码0以及单词自身的值
如果说种别编码不为0的话,则这个标识符为关键字,关键字都是有唯一的种别编码对应的,所以我们只需要返回关键字的种别编码,不需要返回关键字的值。
1.运算符也有唯一对应的种别编码,所以我们也只需要返回运算符的种别编码就行,不需要返回运算符的值
1.二维数组的第一个下标参数state表示的是当前的状态,然后第二个下标参数ch表示的是输入给当前状态state的字符,然后结合这两个下标在数组中找到的位置处存放的是现有状态在输入了ch后得到的新的状态newState