编译原理第三版 第三章 词法分析
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
利用这些规则识别单词符号的过程可用一张称为 状态转换图的有限方向图来表示,而状态转换图识 别单词符号的过程又可以方便地用程序实现。
定义
状态转换图是一张有限方向图,图中结点代表状 态,用圆圈表示,状态之间用箭弧连结;箭弧上 的标记(字符)代表在射出结点状态下的输入字 符。
一张状态转换图只包含有限个状态,其中有一个 被认为是初态,并至少有一个终态(用双圈表 Z 示)。 2 X
;
有限控制器
例4:设一小语言所有单词符号及其内部表示形式
单词符号 DIM 1 种别编码 $DIM 助忆符 内码值
IF
DO STOP END 标识符 整常数
2
3 4 5 6 7
$IF
$DO $STOP $END $ID $INT
内部字符串 标准二进制形式
=
+ * ** . ( )
8
9 10 11 12 13 14
例3: 识别FORTRAN实常数 的状态转换图
a .b E (或D)±d (a,b,d 为整数常数)
数字
0 数字 1 . .
E/D
a. .b a.b a.E±d .b E±d a.b±E d aE±d
数字
数字 E/D 2
+/3
数字
4
其它
5
7
*
6
数字
数字 其它
利用状态转换图识别单词符号的过程
1)从初态开始;
单词符号的种类
(3) 常数 常数的类型一般有整型、实型、布 尔型、字符型等。
(4) 运算符 如 +,-,*,/等,对具体语言个 数是确定的。 (5) 界符 如 , ;()等,对具体语言个数是 确定的。
单词符号的表示形式
词法分析器所输出的单词符号常常表示成如下的 二元式:<单词种别,单词符号的属性值> 单词种别:由语法分析阶段使用的抽象符号。如: 用整数编码。 最简单的编码方案为一类一码,种别编码可设为: 1,2,3,4,5。 另一种编码方案(如本教材中): 标识符:列为一种,用一个整数编码表示; 常数:按类型分种编码; 关键字、运算符、界符:采用一字一种编码。
单词符号的表示形式
单词符号的属性值 标识符的属性值是存放它符号表项的指 针或内部字符串; 常数的属性值是存放它的常数表项的指 针或二进制形式; 关键字、运算符和界符是一符一种,不 需给出其自身的值。
举例:单词符号及其内部表示形式
单词符号 DIM IF DO 1 2 3 种别编码 $DIM $IF $DO 助忆符 内码值
1
Y
W 3
含义
图1表示:在状态1下,若输入字符为X, 则读进X并转换到状态2;若输入字符为Y 则读进Y并转换到状态3,输入字符Z,状 态仍为1。
Z 1 Y X 2 W 3
图1
例1:识别标识符的状态转换图为
0 字母 1 其它 2 *
字母或数字
例2:识别整数的状态转换图为
0 数字 1 数字 其它 2 *
else if(ch==„:‟) return($SEMICOLON,-);
else if(ch==„(‟) return($LPAR,-); else if(ch==„)‟) return($RPAR,-); else if(ch==„{‟) return($LBRACE,-); else if(ch==„}‟) return($RBRACE,-); else ProcError();
1)剔除编辑用字符,如space, tab, CR, LF。
2)剔除注释语句。 3)合并空白字符串为单个space。
4)有时把独立文件中的多个源程序模块聚合在一 起。
5)把宏定义的缩写形式转换为源语句。
扫描缓冲区的设计
双指示器:(单词)起点指示器 start 搜索(词尾)指示器 search 双区缓冲:缓冲区必须分为两个等长半区
说明:
(1)运算符 ”|”读为”或”,”.”读为”连 接”,”*”读为”闭包”。一般地,连接符”.” 可省略不写,在不引起混淆的情况下,括号可省 去。 (2)正规式运算符的优先顺序为:”*”最高,”.” 次之,”|”最低。 (3)若两个正规式所表示的正规集相同,则认 为二者等价,记为U=V。
3、状态转换图的实现
(1)变量和过程 Reserve:整型函数 按strToken中字符串查保留字表 查到回送保留字编码;否则回送0 Retract:子程序过程, 搜索指针回退一字符 InsertId:函数, 将标识符插入符号表,返回符号 表指针 InsertConst函数, 将常数插入常数表,返回常数 表指针
No ID Addr type · · ·· ··
224
j
AF80 INT
227
i
DF88 INT
接口设计
独立一遍 被编译程序的总控程序调用, 完成词法分析 调用一次,生成整个单词序列(二元式), 并 存放于文件中。 待语法分析进入工作时,从文件输进这些单 词符号进行分析。 则须在文件中保存整个源程序的内码形式, 不是很必要。
$ASSIGN
$PLUS $STAR $POWER $COMMA $LPAR $RPAR
-
试构造一个能识别小语言所有单词的状态转换图
空白 字母
0
字母或数字 非字母与数字
1
2 *
约定(限制): 基本字为保留字; 保留字作为标识符 处理,并使用保留字 表识别; 基本字、标识符、 常数间若无运算符 或界限符则加一空 格
2)从输入串中读一个字符;
3)判明读入字符与从当前状态出发的哪条弧 上 的标记相匹配,便转到相应匹配的那条弧所 指向的状态; 4)重复3),均不匹配时便告失败;到达终态 时便识别出一个单词符号。
L i
n e = 8 0 ;
字母 字母
输入 输出
0
1
数 字
Байду номын сангаас
2 4
5 6
数字
3
数 字
=
id , ‘Line’ = , num, ‘80’ ;,
l
(2)程序段
含回路的状态结点对应的程序段 可表示为 GetChar(); while(IsLetter() or IsDigit()) GetChar(); i …状态j的对应程序段… 终态结点对应一条语句 return(code,value);
字母或数字
j
i
(3)扫描器总控程序
int code,value; strToken=“”; GetChar();GetBC()‟ If (IsLetter()) { while(IsLetter() or IsDigit()) { Concat();GetChar();} Retract(); code=Reserve(); if(code==0){ value=InsertId(strToken); return($ID,value);} else return(code,-);} else if(IsDigit()) { while(IsDigit()) {Concat(); GetChar();} Retract(); value=InsertConst(strToken); return($INT,value);}
#
3.3 正规表达式与有限自动机
目的: 形式化地描述词法规则和词法分析程序 词法分析程序的自动生成 主要内容 正规式与正规集 确定有限自动机 (DFA) 非确定有限自动机(NFA) 正规式与有限自动机的等价性 确定有限自动机的化简
正规文法
多数程序设计语言单词的语法都能用正规文法 (3型文法)描述 正规文法回顾 文法的任一产生式α→β的形式都为
A→αB|α或A→Bα|α,其中A,B∈VN , α∈VT* 正规文法描述的是VT*上的符号串集。
1.正规式与正规集
定义:字母表∑上的正规式和正规集递归定义如下: (1)ε和φ都是∑上的正规式,它们所表示的正规集分别为{ε} 和φ。其中:ε为空字符串,φ为空集; (2)任意元素a∈∑,a是∑上的一个正规式,它所表示的正 规集是{a}; (3)假定U和V都是∑上的正规式,它们所表示的正规集记 为L(U)和L(V),那么,(U|V),(U· V)和(U)*都是正 规式,他们所表示的正规集分别记为L(U)∪L(V), L(U)L(V)和(L(U))*。 (4)仅由有限次使用上述三步而得到的表达式才是∑上的正 规式,它们所表示的字集才是∑上的正规集。
超前搜索
例:FORTRAN语言中关键字的识别: DO99K=1,10 识别DO为关键字要搜 DO99K=1.10 索到“,” FORTRAN语言中常数的识别:
5.EQ.M, 5.E08
识别5为常数要搜索到Q
2、状态转换图
大多数程序设计语言中单词符号的词法规则可 以用正规文法描述。如: <标识符>→ 字母|<标识符>字母|<标识符>数字 <整数>→数字|<整数>数字 <运算符>→+|-|×|÷„ <界符>→; |, |( | )|„
数字 数字
= + *
3 5 6
非数字
4
*
非*
* 8 9
7 *
, ( )
其它
10 11 12 13
3、状态转换图的实现
(1)变量和过程 ch:字符变量, 放当前读入字符 strToken:字符数组, 放单词的字符串 GetChar:取字符过程 取下一字符到ch ;搜索指针+1 GetBC:滤除空字符过程 判ch =空? 若是,则调用GetChar Concat:子程序过程 把ch中的字符拼入strToken IsLetter, IsDigit:布尔函数 ch中为字母、数字时返回.T.
第三章 词法分析
本章要点
对于词法分析器的要求
词法分析器的设计
正规表达式与有限自动机
词法分析器的自动生成
3.1 对词法分析器的要求
词法分析的任务是对源程序从左到右逐个字符 进行扫描,产生一个个的单词符号。 功能 源程序 词法分析器 单词符号
单词符号的种类
(1) 关键字 由程序语言定义的具有固定意义 的标识符。有时也称为保留字或基本字。 对具体程序语言个数是确定的。如C语言的 if ,do,int等。 (2) 标识符 在多数程序设计语言中,标识符 是以字母开头的“字母/数字”串。用来表 示各种名字,如变量名,函数名等。
STOP
END 标识符 整常数 = + *
4
5 6 7 8 9 10
$STOP
$END $ID $INT $ASSIGN $PLUS $STAR
内部字符串 标准二进制形式 -
**
. ( )
11
12 13 14
$POWER
$COMMA $LPAR $RPAR
-
举例: 代码段 while (i>=j) i--;
………………… ………While……… ...abcdddeee1=….. …. .. Wh
半区长度Length >=程序语言允许的标识符长度
超前搜索
在某些程序设计语言中,识别单词符号 时,有时需要向前扫描多个字符,直到能 够肯定词性的地方为止,这种技术称为超 前搜索。
例如:C++语言中++, --, >=, <=, +=, -=等运 算符的识别。
分析后的单词符号序列为
(1) (2) (3) (4) (5) (6) (7) (8) (9) <while , - > <( ,- > < id , ptr-i> < >= , - > < id , ptr-j> <) ,- > < id , ptr-i> < -- , - > <; ,- > 符号表
接口设计
子程序
语法分析程序调用, 调用一次识别并 输出一个单词给语法分析器。 更合适,我们假定词法分析按此方式 工作。
3.2 词法分析器的设计
1、词法分析器的结构
输入、预处理
扫描缓冲区
源程序
超前搜索
预处理子程序
输入缓冲区
扫描器
扫描缓冲区
单词符号
预处理子程序
预处理子程序的任务:
else if (ch==„=„) return($ASSIGN,-);
else if (ch==„+„) return($PLUS,-); else if(ch==“*”) { Getchar();
if(ch==„*‟) return($POWER,-);
Retract();return($STAR,-);}
(2)程序段
i
字母
j k
数字
/
不含回路的分叉结点对应的程序段可表 示为 GetChar(); if (IsLetter()) {…状态j的对应程序段…} else if (IsDigit()){…状态k的对应程序 段…} else if(ch=„/‟) {…状态l的对应程序段…} else{…错误处理…}