当前位置:文档之家› 编译原理 3.2正规文法和状态转换图

编译原理 3.2正规文法和状态转换图


2020/6/18
第30页/共24页
一个简单的词法分析器示例
1 C语言子集的单词符号表示 2 C语言子集对应的状态转换图的设计 3 状态转换图的实现
2020/6/18
第31页/共24页
1 C语言子集的单词符号表示
大多数程序语言的单词符号都可用 状态转换图予以识别。下面构造一个C 语言子集的简单词法分析器,该C语言 子集的所有单词符号及其种别编码和内 码值如下表所示。
开始符号S作为初始状态; S 设一符号F不属于V作为终止状态; F
2020/6/18
第7页/共24页
形如A→aB的规则:从结点A引一条矢线到结
点B,并用符号a标记这条矢线;
a
A
B
形如A→a的规则:从结点A引一条矢线到终态
结点F,并用符号a标记这条矢线;
a
A
F
2020/6/18
第8页/共24页
则有:S=> a1A1=> a1 a2A2=> a1 a2 a3A3=> … => a1 a2 a3 … an-1An-1=> a1a2a3…an
事实上,在利用状态转换图M对符号串ω进行识别的 过程中,M中的每一次状态转换都模拟了G中的一步 直接推导,所以,上述方法是一个自顶向下的分析
方法。
2020/6/18
a
R
A
2020/6/18
第16页/共24页
例如:G[Z]:Z→U0∣V1 U →Z1∣1 V →Z0∣0
1
2020/6/18
1
U
初态 R
0
V
0
Z
1
0
第17页/共24页
二、状态图的使用——识别句子
对于已知的字符串ω =a1a2a3……an,利用状态 转换图识别的步骤:
从初态R开始,自左向右扫描ω的字符,在当前状态 所射出的弧中,找出标记有该字符的弧,并沿此弧 过渡到下一当前状态;
(8)buildlist( ): 将标识符登录到符号表或将常数 登录到常数表;若登录表中已存在该标识符 或常数,则返回相关信息。
(9)error( ): 进行出错处理。 (10)getchar():把下一个输入字符读到character 中,读入源程序字符的指针前移一个字符。
2020/6/18
第40页/共24页
Sk:其含义是,在Si状态下,扫描到输入符
号aj时,按序偶(Si,aj)查矩阵B,扫描
Bij=
器根据Bij的指示,先执行相应的语义动作,
再转换到下个状态Sk;
空白:“出错”,则说明输入符号串有误,
拒绝接受,扫描器将调用出错处理程序进
行处理。
2020/6/18
第26页/共24页
在一个状态矩阵中,有很多元素都是出错状态, 为了节省存放状态矩阵的存储空间,在具体实现 时,常采用更为紧凑和有效的数据结构(见P55 表3-1 )。
一、状态图
文法中的每一个非终结符号代表一结点 (状态) ;
开始符号S作为终止状态 S 设一符号R不属于V作为初始状态 R
2020/6/18
第15页/共24页
形如A→Ba的规则:从结点B引一条矢线到 结点A,并用符号a标记这条矢线;
a
B
A
形如A→a的规则:从初始状态R引一条矢 线到结点A,并用符号a标记这条矢线;
助记符
while if else
switch case id num
+ − * relop relop relop = ;
内码值
— — — — —
id在符号表中位置
num在常数表中位置


— LE LT EQ — —
第33页/共24页
2 C语言子集对应的状态转换图的设计 首先对输入串做预处理。
即剔除多余的空格、注释、制表符和 换行符等。
其它
其它
第23页/共24页
3.2.3 状态转换图的一种实现
状态矩阵法:状态转换图可方便地用于识别 单词,但是,如何让计算机利用状态转换图 来进行词法分析呢?一个简单实用的方法就 是将图以矩阵的形式保存在内存中,这就是 所谓的状态矩阵法。
2020/6/18
第24页/共24页
状态(转换)矩阵:以状态转换图中各个状态S1,
字母
其它
*
0
1
2
2020/6/18
( a)
第21页/共24页
识别无符号整数的状态转换图如下:
数字
数字 0
其它
*
1
2
(b)
2020/6/18
第22页/共24页
识别无符号数的状态转换图如下:
E
数字
数字
数字
数字 · 数字 E +或- 数字 其它
0
1
2
3
4
5
6
27
数字
另见:P51 图 3-3
2020/6/18
(5)letter( )和digit( ): 判断character中的 字
符是否为字母和数字的布尔函数,若是 则返回true, 否则返回false。 (6)reserve( ): 按token数组中的字符串查 保留字表, 若是保留字则返回其编码, 否则返回0。
2020/6/18
第39页/共24页
(7) retract( ): 扫描指针回退一个字符, 同 时将character置为空白。
第13页/共24页
从状态转换图的初态出发,分别沿着一切可能 的路径到达终态结点,并将每条路径各矢线上 的标记字符依次连接起来,便得到状态转换图 所能识别的全部符号串,这些符号串所组成的 集合也就是该状态转换图所识别的语言。
2020/6/18
第14页/共24页
3.2.2.2 左线性文法的状态转换图
其次把保留字作为一类特殊标识符处理。
即对保留字不专设对应的状态转换图, 当状态转换图识别出一个标识符时就去查 表,确定它是否为一个保留字。
2020/6/18
第34页/共24页
对保留字专设对应的状态转换图:
C语言子集对应的状态转换图如下:
2020/6/18
第35页/共24页
空白 字母或数字
开始 字母
<标识符>→<标识符>数字 <标识符>→字母
凡是能用正规文法描述的语言,均可由某种有 限状态算法进行分析;
2020/6/18
第3页/共24页
3.2.1 状态转换图
状态转换图是设计和实现扫描器的一种有效工具; 状态转换图:是一组矢线连接的有限个结点组成
的方向图
每一个结点对应在识别或分析状态中扫描器所处的状 态,用小圆圈表示;
特别的A → ε:从A引一条矢线到终态,且在这 条失线上标记未曾在A的射出弧中出现终结符号。
例如:
Vt ={a,b,c} A→aB|ε
a
B
A
b,c F
表示读到a以外的其他任何终结符号都进入终态
2020/6/18
第9页/共24页
例如:G[Z]:Z→0U∣1V U →1Z∣1 V →0Z∣0
2020/6/18
满足:识别到字符串最后一个字符,进入终态; 否则:ω不是文法的句子(单词符号);
2020/6/18
第18页/共24页
例如:
G[Z]: Z→U0∣V1 U →Z1∣1 V →Z0∣0
1U 初态 R
0V
2020/6/18
1 0
Z
1
0
ω =100110?
100110 U00110 Z0110 V110 Z10 U0 Z
构造出状态矩阵之后,整个单词的识别过程就可 在一个驱动程序(见P54 程序3-2)的控制之下自 动地进行,直到从输入字符串中识别出全部单词 为止;
2020/6/18
第27页/共24页
P55 表3-1
2020/6/18
第28页/共24页
P54 程序 3-2
2020/6/18
第29页/共24页
P54 程序 3-2
(2)状态4识别出一个常数后可以将它 转换成二进制常数再登录到常数表,然后返 回它在常数表中的入口指针作为内码值。
2020/6/18
第37页/共24页
3 状态转换图的实现 状态转换图易于用程序实现,最简单的
办法是让每个状态对应一小段程序。对于 图3–00,首先引进一组变量和过程:
(1)character: 字符变量,存放最新读入 的源程序字符。
(2)token: 字符数组,存放构成单词符号 的字符串。
(3)getbe( ): 若character中字符为空,则 调用getchar( ),直至character为非空。
2020/6/18
第38页/共24页
(4)concatenation( ): 将token中字符串与 character中字符连接作为token中的新 字符串。
返回(relop, LE) 返回(relop, LT)
返回(relop, EQ) 返回(=, -) 返回(; , -)
图 3-00
非法字符错
第36页/共24页
注意: (1)状态2识别出一个单词符号后需先
查保留字表,若匹配则为保留字,否则为标 识符。若为标识符,还需查符号表,看表中 是否有此标识符。若符号表中无此标识符, 则先将它登录到符号表中,再返回它在符号 表中入口地址作为内码值;若表中有此标识 符,则直接返回其入口地址作为内码值。
Z U0 Z1 V1 Z0 U0
1
此过程是一种归约过程
第19页/共24页
用对左线性文法所构造的状态转换图来识别 文法的句子,其过程与上面对右线性文法中 所述的过程并无二致。不过,就识别的方法 而论,它却属于自底向上的分析。
相关主题