当前位置:
文档之家› 第四章(2) 自下而上语法分析
第四章(2) 自下而上语法分析
• 关键是如何识别可归约的符号串?
语法分析中问题的提出:
① 在构造语法树的过程中,何时归约?
当可归约串出现在栈顶时就进行归约。 ② 如何知道在栈顶符号串中已经形成可归约串? 如何进行归约? 通过不同的自底向上的分析算法来解释,不 同的算法对可归约串的定义是不同的,但分析过 程都有一个共同的特点:边移进边归约。 规范归约:使用句柄来定义可归约串 算符优先:使用最左素短语来定义可归约串
动作
1) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 准备 移进 归约 归约 归约 移进 移进 归约 归约 移进 移进 归约 归约 归约 接受
栈
输入缓冲区
F→id T→F E→T
F→id T→F
F→id T→T*F E→E+T
# id1+id2*id3# #id1 +id2*id3# #F +id2*id3# #T +id 2*id3# #E +id2*id3# #E+ id2*id3# #E+id2 *id3# #E+F *id 3# #E+T *id 3# #E+T* id3# #E+T*id3 # #E+T*F # #E+T # #E #
算符优先关系表的构造算法
• 1.FIRSTVT集
–定义:对每个非终结符P, + + FIRSTVT(P)={a|P=>a...或P=>Qa...,a为终结 符,P,Q为非终结符}
由优先性低于的定义和FIRSTVT集合的定义可以得出: 若存在某个产生式:…aP…,对所有:b∈firstVT(P) 都有:a < b。
输入串 a1 a2 a3 …… 栈 X 存 1 放 X2 句 X3 型 前 缀 # ( )
#
输出
―移进-归约” 分析程序
…
• 3. 过程描述: do{ do { 将输入串最左边的符号移入栈内;} while (在栈里符号串中找到一个可归约串); 归约可归约串 while (文法开始符号出现在栈顶或者发现错误);
注: 每次归约的部分就是分析为句柄的字符串(最右推导)。
在规范归约中,关键问题就转化为如何识别句柄?
回到上例用句柄对句子abbcde进行归约有:
句型 abbcde aAbcde aAde aABe 归约规则 (2) Ab
(3)A Abc
(4)B d
(1)S aABe
(1)S aABe (2)A b (3)A Abc (4)B d
构造FIRSTVT集算法:
a
b
S
该分析过程反复执行“移进”和“归约”两个动作,直到栈中只有开始符号为止。
―移进-归约”分析法中栈的使用
• 移进-归约分析器使用了一个符号栈和一个输入缓冲区 • 1、句型表示 一般形式: 符号栈的内 剩余输入串 容 # 初态: 输入串# #S # 终态: 符号栈内容 + 输入缓冲区内容 = # 当前句型 # • 2、分析器结构
• 分析成功的条件:栈顶为文法符号,输入串为空。 • 注意:该过程并未涉及如何在栈里找可归约串。实际 上,不同的找可归约串的方法,构成了不同的分析算 法。
分析器的四种动作
• 1) 移进:读入下一个输入符号并把它下推进栈。 • 2) 归约:当栈顶符号串形成一个可归约的串(如:句 柄)时,直接进行归约,即用产生式左侧的非终结符替 换栈顶的句柄。 • 3) 接受:当栈底只有“#‖和开始符号,而输入也已经 到达右端标志符号“#‖时,识别出符号串是句子,执行 该动作,表示分析成功,是归约的一种特殊情况。 • 4) 出错:栈顶的内容与输入符号相悖,即当识别程序 发现输入符号串不是句子时,进行出错处理。 • 注意:决定移进和归约的依据是什么? 栈顶是否出现了可归约的符号串。
(1) E->E+T|T (2) T->T*F|F (3) F->(E)|id
E
T E T T F id2 * F id3
F
id1 +
所得的结果是:用产生式序列表示语法分析树
移进归约分析中的问题
• 1) 移进-归约冲突
–在分析到某一步时,既可以移进,又可以归约 –上例第10)步可以移进*,也可以按产生式 E→E+T进行归约。
• 自下而上语法分析主要有以下三种方法:
①简单优先分析法(规范归约)——文法按 一定原则规定文法符号的优先关系 ②算符优先分析法(不规范归约)——规定
算符之间的优先关系
③ LR分析法(规范归约)—— LR(0)、 LR(1)、SLR(1)和LALR(1)
语法分析树的生成演示
S aABe aAde aAbcde abbcde
1
2
3
4
5
6
7
8
9
10
移 移 归 移 移 归 移 归 移 归 进 进 约 进 进 约 进 约 进 约 动作 a b 2 b c 3 d 4 e 1 c b b A A A a a a e d B B A A A A a a a a
(1)S aABe (2)A b (3)A Abc (4)B d
由E->E+T
E * i, 得i > + => * E => E+T, 得+ > +
* E => T*F, 得* > + * E => (E), 得 ) > +
#
终结符+‗#‘
对于结束符#和其它终结符a有关系: # < a ;a > #
• 在优先表中,空白部分是一种错误关系 • 相同的终结符之间的优先关系不一定是 • 如果有a b,不一定有b a(不具传递 性),因为只定义相邻运算符之间的优先 关系,a,b相邻时,不一定b,a相邻。 • a,b之间未必有优先关系( , , )
–从语法树的角度看:从语法树的树叶开始,逐 步向上归约构造分析树,直到形成根结点。是 推导的逆过程。
• 最左推导(Left-most Derive)
– 每次推导都替换当前句型的最左边的非终结符。 – 与最右归约对应。
• 最右推导(Right-most Derive)
– 每次推导都替换当前句型的最右边的非终结符。 – 与最左归约(规范归约)对应,得规范句型。
• 3.算符优先文法
–算符文法G的任何终结符a,b之间要么没有优先 关系,若有优先关系,至多有 = ,< , > 中的一 种成立,则G为一算符优先文法。
例:E→E+E | E*E | (E) | i
因为:E→E+E , EE*E
证明不是算符优先文法。
则有 + *
又因为:E→E*E, EE+E
所以不是算符优先文法。
例:设有文法G[S]:
(1) S aABe (2) A b (3) A Abc (4) B d 使用最右推导: 2) (1 ) ( (3 ) aABe 因为S rm aAde aAbcde rm rm abbcde是文法G的句子。
abbcde,所以
rm (4 )
最左归约过程是最右推导的逆过程, 对输入串abbcde的 移进—归约过程如下: 步骤
• 2) 归约-归约冲突
–存在两个可选的句柄,可对栈顶符号进行归约 –例如上述第13)步,可以用T→F进行归约,又可 以按T→T*F进行归约。
• 各种分析方法中处理冲突的技术不同
算符优先分析
• 算符优先分析法的思想源于表达式的分析,即利用相邻 终结符号之间的关系来寻找可归约串。
• 将句型中的终结符号当作“算符”,借助于算符之间的 优先关系确定句柄。 • 显然,在一个符号串中,任意两个相邻终结符号a和b之 间,只可能存在以下四种优先关系: (1) a, b优先性相同,记作a b。 (2) a优先性高于b, 记作a b。 (3) a优先性低于b ,记作a b。 (4) a与b不可能相邻,即此符号串不是句型(出错)。 如果以上四种关系中的任意两种都不会同时成立,则可 以根据终结符号之间的归约关系进行语法分析。
自下而上的语法分析的一般过程
• 实现思想
–从输入符号串开始,从左到右进行扫描,将输 入符号逐个移入一个栈中,边移入边分析,一 旦栈顶符号串形成某个产生式的右部时,就用 该产生式的左部非终结符代替,称为归约。重 复这一过程,直到归约到栈中只剩下文法的开 始符号时,则分析成功, 称为“移进-归约” 方法。
• ―移进—归约”语法分析小结:
– 从输入串的开始依次读入单词(移进栈中) 。 – 一旦发现可归约串(某个产生式的右端)就立即归约。
– 归约就是将栈顶的一串符号用文法产生式的左部代 替,归约可能重复多次,然后继续移进。
– 若最终能归约成文法的开始符号,则分析成功(接 受);否则出错。
– 由于总是将句型的最左边的可归约串替换成非终结 符,该方法通常得到是最右推导。
S aABe A Abc | b Bd abbcde aAbcde aAde aABe 例
S aABe A Abc | b Bd abbcde aAbcde aAde aABe S 例
S aABe A Abc | b Bd abbcde aAbcde aAde aABe S S rm aABe rm aAde rm aAbcde rm abbcde 例
第四章(2) 自下向上语法分析
本章要求: 1. 掌握自下向上语法分析的基本思想和基本概念 2. 了解算符优先语法分析;求FIRSTVT集和 LASTVT集,构造算符优先关系表;能运用算 符优先分析方法进行表达式分析(选学) 3. 掌握句柄的定义与判定 4. 理解规范归约的过程和LR分析过程中的实现 5. 掌握LR语法分析的实现过程