当前课程知识点:编译原理 > 第3章 词法分析 > 3.1 词法分析概述 > 词法分析概述
同学们大家好
大家都知道
人们理解一篇文章
或者是一个程序
是在单词的级别上来思考的
同样 编译程序也是在单词的级别上
来分析和翻译源程序的
词法分析作为编译过程的第一步
是我们编译的基础
词法分析器的只要任务是
从左至右逐个字符地
对源程序进行扫描
产生一个个的单词符号
其核心是找到单词之间的分隔符
把作为字符串的源程序
改造成为单词的符号串
词法分析器在扫描源程序时
会滤掉对源程序当中无用的成分
比如注释、空格、回车等等
处理和平台有关的输入
比如根据文件结束符的
不同表示来处理相关的输入
根据单词定义来识别单词记号
并交给语法分析器
整个过程呢
都会和符号表管理器
和出错处理器打交道
进行相关的处理
词法分析程序就是从输入字符串中
识别一个个的
具有独立意义的单词符号
单词符号是一个程序语言的
基本语法符号
称作 token(记号)
它是具有独立意义的最小语法单位
把字符组成记号
与我们在一个英语句子当中
将字母构成单词
并且确定单词的含义
非常的相似
这个任务非常像拼写
程序语言的单词符号
一般来说分为五种
关键字
关键字就是由程序语言定义的具有
固定意义的标识符
我们也叫它保留字或者是基本字
比如C语言当中的if
else do while
C++当中的class int switch break
这些都是保留字
它们通常不作为一般的标识符
接下来是标识符
标识符就是来表示各种名字的
比如变量名 常量名 数组名
函数名和子过程名
还有常数
程序中会出现各种类型的常数
常量的类型呢
一般来说有整型
实型 布尔型和字符型
比如125、0.718
布尔常量TRUE
字符串“Hello” 等等
还有在表达式当中
连接运算对象的符号
这些都是运算符
比如+、-、*、/
还有关系运算符< 等等
还有程序当中的定界符
比如像是逗号 分号 括号
还有注释符号等等
但是只把切分好的单词符号
本身输出是不够的
一个输出单词符号
至少应该有两方面的信息
其一是本单词符号的种别
另外还需要单词符号它的属性值
单词符号种别
是我们在进行语法分析的时候
需要的信息
通常用整数来编码
一个语言的单词符号如何去分种
分成多少种
怎样去编码
这是一件非常技术性的问题
它主要取决于处理上方便
比如我们可以把标识符
一般归为一种
常数则按照类型去分种
关键字可以把它视为一种
也可以一个关键字一种
采用一字一种的分法
实际上处理起来是非常方便的
运算符可以采用一符一种的分法
但也可以把具有一定共性的
运算符视为一种
至于界符的话
一般来说是一符一种的分法
还有就是单词自身的值
单词符号的属性值
是我们在编译的其它阶段
譬如说在语义处理的时候需要的信息
属性值
是指单词符号它的特性或者是特征
可以是单词符号
在符号表当中的入口地址
或者是数值它的二进制等等
如果是一符一种的分法
词法分析器只需要给出
种别的编码就可以了
不需要去给出它的属性值
如果一个种别含有多个单词符号
那么对于它的每个单词符号
除了给出种别编码之外
还应该给出符号它的属性值
以便把同一类的单词区别开来
标识符的属性值是自身的符号串
也可以是在符号表当中的入口地址
常数自身的值
是常数的二进制数值
接下来让我们来看一下这个程序段
if (a>1) b = 100;
假设我们按照关键字
运算符和界符
都是一符一种的这种方法
那么标识符自身的值就是字符串
常数就是二进制的值
接下来我们就可以把
刚才的这个程序段
变成这样的字符序列
在这个字符序列当中大家可以看到
关键字 if
左括号 ( 大于号 > 右括号 )
赋值号 = 分号
都是一符一种
那么标识符它的类别是10
值分别是a和b
常数的类别号是11
值分别是1和100
也可以有另一种表示方法
就是关键字 运算符和界符
都是一符一种
标识符自身的值
是我们符号表当中的入口地址
常数是二进制值
那么对于这样的一个程序段我们来看一下
while ( i >= j ) i--
我们得到了这样一个
符号表序列当中我们发现
while 左括号 大于等于 右括号和分号
都是一符一种
标识符i和j的种类是id
值分别是指向i
指向j的符号表当中的表项指针
词法分析器有两种处理结构
一种是将词法分析器程序作为主程序
把词法分析与语法分析分开
另外一种方法
是将词法分析程序
作为语法分析器的调用子程序
那么一般来说
我们把词法分析器
安排为一个独立的阶段
因为这样可以让整个编译程序
结构更加的简单 清晰和条理化
而且词法分析比语法分析
要简单得多
我们也可以用更加有效的特殊的方法
和工具来进行处理
把词法分析器安排为独立的一遍
让它把整个源程序
翻译成一连串的单词符号
也就是二元式的序列
存放于文件当中
等到语法分析程序进入工作的时候
就可以从这个文件
去输入这些单词符号然后进行语法
句子的结构分析
把语法分析器安排为一个子程序
每当语法分析器
需要一个这样的单词符号时
就去调用这个子程序
每一次的调用
词法分析器就从我的输入串当中
识别一个单词符号
然后交给语法分析器
我们来看一下
这是我们词法分析器的整个工作过程
词法分析器工作的第一步
是输入源程序文件到输入缓冲区
首先它要做预处理
预处理的工作主要是将输入的源程序当中的
多余空白符 跳格符 回车符 换行符
等等编辑性的字符
以及注释的部分剔除掉
并且把这个结果呢
存入到扫描缓冲区当中去
那么方便我们扫描器
去对单词符号进行识别
为了保证单词符号不被
扫描缓冲区边界打断
扫描缓冲区一般设计为
如下的一分为二的区域
每次输入更新其中一半的空间内容
使得词法分析器
即便在最坏的情况之下
识别单词符号的长度
是扫描缓冲区的长度一半
也不至于丢失单词的剩余部分
因此双缓冲区也称为配对缓冲区
我们还需要注意一点
源程序当中的单词符号
在构成上没有特殊的结尾
字母单词符号与字母单词之间
在不引起可读性理解错误的时候
可以不用空格作为间隔
因此 有的时候当单词符号它的所有字符
都已经处理之后
特别是当有的单词符号
是另一个单词符号的前缀的时候
词法分析器是不能确定
当前的单词识别是否已经结束了
比如说在C++ 语言当中的单词符号>
它也是大于等于的前缀
也就是说即便读取了大于号
也并不能够确保
是否已经读取了一个完整的单词
需要在超前搜索
若干个字符之后才能够确定
返回识别的这个单词
如果说我这个时候多读进了一些字符的话
那么需要回退的处理
同学们
这节课主要向大家介绍了词法分析器
在整个编译系统当中的位置
以及词法编辑器主要的任务
还有词法编辑器
它的结构和我们的设计策略
这节课就讲到这里
谢谢大家
-1.1 什么是编译原理
--什么是编译原理
--什么是编译程序
--讨论:翻译程序、汇编程序、编译程序、解释程序的区别和联系。
--练习1
-1.2 编译的基本过程
--编译的基本过程
--编译的基本过程
--练习2
-1.3 编译程序的组织
--编译程序的组织
--编译程序的组织
--练习3
-编译原理概述
-2.1 文法与语言
--文法与语言
--文法与语言
-2.2 文法和语言的形式定义
--练习1
-2.3 文法的类型
--文法的类型
--文法的类型
--练习2
-2.4 上下文无关文法及语法树
--练习3
-2.5 上下文无关文法的句型分析
--练习4
-编译理论基础作业
-3.1 词法分析概述
--词法分析概述
--词法分析概述
--练习1
-3.2 正规文法和状态转换图
--练习2
-3.3 有限状态自动机
--有限状态自动机
--有限状态自动机
--练习3
-3.4 NFA与DFA的等价性
--练习4
-3.5 正规表达式与正规集
--练习5
-3.6 正规文法与正规式
--正规文法与正规式
--正规文法与正规式
--练习6
-3.7 正规式与FA
--正规式与FA
--正规式与FA
--练习7
-词法分析作业
-4.1 自顶向下语法分析及其面临的问题
--练习1
-4.2 文法的等价转化
--文法的等价转化
--文法的等价转化
--练习2
-4.3 LL(1)文法与递归下降分析法
--练习3
-4.4 构建FIRST集合FOLLOW集合
--练习4
-4.5 LL(1)分析器工作原理
-- LL(1)分析器工作原理
-4.6 LL(1)分析表构造算法
--练习5
-5.1 自底向上的语法分析及优先分析
--练习1
-5.2 LR分析器
--LR分析器
--LR分析器
--练习2
-5.3 活前缀和LR(0)项目
-- 活前缀和LR(0)项目
--练习3
-5.4 构造识别活前缀的FA
--练习4
-5.5 LR(0)分析表构造算法
--练习5
-5.6 SLR(1)分析法
--练习6
-5.7 LR(1)分析法与LALR分析法
--练习7
-6.1 语义分析和语法制导翻译概述
--练习1
-6.2 常见中间语言简介
--常见中间语言简介
--常见中间语言简介
--练习2
-6.3 简单算术表达式和赋值语句翻译
--练习3
-6.4 布尔表达式和复制语句翻译
-6.5 拉链和回填
--拉链与回填
--拉链与回填
--练习4
-6.6 程序控制语句翻译
--程序控制语句翻译
--程序控制语句翻译
--练习5
-6.7 for循环语句的翻译
-6.8 GOTO语句和情况语句的翻译
--练习6
-6.9 含数组元素的算术表达式的翻译
--练习7
-6.10 数组元素赋值语句的翻译
--练习8
-7.1 符号表概述
--符号表概述
--符号表概述
--练习1
-7.2 符号表的建立
--符号表的建立
-- 符号表的建立
--练习2
-8.1 运行时存储空间组织概述
-8.2 运行时分配策略
--运行时分配策略
--运行时分配策略
--练习
-9.1 线性窥孔优化
--线性窥孔优化
--线性窥孔优化
-9.2 基本块及其优化方法
-9.3 循环概念
--循环概念
--循环概念
-9.4 循环优化
--循环优化
--循环优化
-代码优化作业