词法分析

词法分析总体概念

1、词法分析的任务
词法分析是编译的第一个阶段,其任务是:从左至右逐个字符地对源程序(用高级语言编写的)进行扫描,产生一个个单词符号,把字符串形式的源程序改造成为单词符号串形式的中间程序。
2、词法分析器(也叫扫描器)
执行词法分析的程序称为词法分析程序,也称为词法分析器或扫描器。
词法分析器的功能是输入源程序,输出单词符号。
3、词法分析的两种处理结构
(1)把词法分析程序作为主程序。即,把词法分析与语法分析明显分开,由词法分析程序将字符串形式的源程序改造成单词符号串形式的中间程序,以这个中间程序作为语法分析程序的输入。在这种处理结构中,词法分析和语法分析实际上是分别实现的。
(2)把词法分析程序作为语法分析程序调用的子程序。在进行语法分析时,每当语法分析程序需要一个单词时,便调用词法分析程序,词法分析程序每一次调用便从字符串源程序中识别出一个单词交给语法分析程序。在这种处理结构中,词法分析和语法分析实际上是交替进行的。
词 法 分 析 程 序 , 通 常 采 用 第 2 种 处 理 结 构 → 享 用 更 有 效 的 方 法 来 处 理 单 词 \color{green}{词法分析程序,通常采用第2种处理结构→享用更有效的方法来处理单词} 2

词法分析器的设计方法

2.1 单词符号
由语法分析程序的任务可以知道:单词符号是程序语言的基本语法单位具有确定的语法意义。
1、程序语言的单词符号通常可以分为以下5种:

保留字标识符常数运算符界符
也称为基本字,例如C语言中的if、else、while、do等,保留了语言所规定的含义,是编译程序识别各类语言语法成分的依据。几乎所有程序语言都限制用户使用保留字来作为标识符用来标记常量、数组、类型、变量、过程或函数名等,通常由用户自己定义包括各种类型的常数,如整型常数、实型常数、布尔型常数等如“ + ”、“ - ”、“ * ”、“ / ”、“ > ” 等。在语言中是作为语法上的分界符号使用的,如“ , ”、“ ; ”、“ ; ”、“ ( ”、“ ) ”等。

2、词法分析程序输出的单词符号,通常表示为:
(单词种别,单词自身的值)
一词一码的单词符号,二元式中不必写出值(用null代替即可);一类一码的单词符号,二元式中要写出值。
(1)单词种别
单词种别表示单词的种类,它是语法分析所需要的信息。通常让每种单词对应一个整数码,这样可以最大限度地把各个单词区分开来。
(2)单词自身的值
单词自身的值,是编译中其它阶段所需要的信息。

若一个种别只含有一个单词符号若一个种别含有多个单词符号
对于这个单词符号,其种别编码就完全代表了它自身的值对于他的每个单词符号,除了给出种别编码之外,还应给出单词符号自身的值,以便把同一种类的不同单词区别开来

保留字标识符常数运算符界符
可将其全体视为一种,也可以一词一种一般统一归为一种可以统一归为一种,也可按整型、实型、布尔型等分为几种可采用一符一种的分法,也可以统一归为一种可采用一符一种的分法,也可以统一归为一种
采用一词一种比较方便
如果一词一类,那么种别编码就代表自身的值标识符自身的值就是标识符自身的字符串常数自身的值是常数本身的二进制数值

注:此外,我们也可以用指向某类表格中一个特定项目的指针来区分同类中的不同单词。
eg: 对于标识符,可以用它在符号表的入口指针作为它自身的值;
常数可以用它在常数表的入口指针作为它自身的值
2.2 状态转换图
举例:无符号数的状态转换图:
在这里插入图片描述
当到达一类单词符号的终止状态时即可给出相应的单词编码。由于某些终止状态是在读入一个其它不属于该单词的符号后,才得到相应的单词编码,这表明在识别单词的过程中多读入了一个符号,所以识别处单词后应将最后多读入的这个符号予以回退。


a. 对于不含回路的分支状态来说,可以让它对应一个 switch()语句或者一组if-else语句:
在这里插入图片描述

b. 对于含回路的状态来说,可以让它对应一个 while语句。:
在这里插入图片描述
终态一般对应一个return()语句。return 意味着从词法分析器返回到调用段,一般指返回到语法分析器。

一个简单的词法分析器

一个重要的事实是:大多数程序语言的单词符号都可以用状态转换图予以识别。

举例:
1、C语言子集的单词符号及内码表示:
(由于直接使用整数编码不利于记忆,故用一些特殊符号来表示种别编码)
在这里插入图片描述
备注:表格中的保留字,采用一词一码的方式处理→种别编码就完全代表了自身的值;
标识符、常数,采用的是一类一码→分别用指向符号表、常数表的一个特定项目的指针来区分同类中的单词;
运算符、界符,采用一词一码的方式处理。


2、在设计的状态转换图中,首先对输入的串做预处理,剔除多余的空白符 → 将保留字作为一类特殊的标识符来处理,即对保留字不单独设置状态转换图,当转换图识别出一个标识符时,先去查对应的表的前5项,确定它是否为一个保留字。(也可以专设一个保留字表来进行处理)
对应的状态转换图为:
在这里插入图片描述
注意:
在图中的状态2时,先确定是否为保留字,否则就是标识符。如果是标识符,应该先查符号表,如果表中无此标识符,则将它加入到符号表中,返回它在符号表中的入口指针(地址)作为该标识符的内码值;如果表中已经有此标识符,则给出重名错误信息。
在状态4时,应将识别的常数转换成二进制常数,并将其加入到常数表中,然后返回其在常数表中的入口指针作为该常数的内码值。
3、状态转换图的实现(C语言代码)
最简单的实现状态转换图的方法:让每个状态对应一小段程序。
对于这个例子的状态转换图,引进一组变量和函数:

(1) character: 字符变量,存放新读入的源程序字符
(2)token: 字符数组,存放构成单词符号的字符串
(3) getbe(): 若character中的字符为空白,则调用getchar(), 直至character为非空白字符为止
(4) concatenation(): 将token中的字符串与character中的字符连接并作为token 中新的字符串
(5) letter()和 digit(): 判断character中的字符是否为字母和数字的布尔函数,是则返回true(即1),否则返回false(即0)。
(6) reserve(): 按token数组中的字符串查表中的前五项(即判别其是否为保留字),若是保留字则返回它的编码,否则返回0值
(7)retract(): 扫描指针回退一个字符,同时将character置为空白。
(8) buildlist(): 将标识符登灵到符号表中或将赏数登录到常数表中
(9) error(): 出现非法字符,显示出错信息。

  • 7
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值