第6章-自底向上的LR分析法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数); 将LR(0)项目集规范族中的每个项目集作为
DFA的状态,将go函数作为状态转换函数, 构造出的DFA即为所求。
初始状态:CLOSURE({S ’ →.S})
40
例题
例6.1 对于文法G[S]: S→vI:T I→I,i I→i T→r 经拓广并对产生式编号后为G’[S]: 1. S’ →S 2. S → vI:T 3. I→I,i 4. I→i 5. T→r
第6章-自底向上的LR分析法
在第5章的自底向上分析中的关键问题是 寻找可归约串。
简单优先分析方法、算符优先分析方法, 基本上都是从左到右地向前看若干个输入符 号,找出句柄(或其变型—最左素短语)的尾, 然后回头(从右到左)查看已扫描过的符号, 找出句柄(或其变型—最左素短语)的头。
这实际上已不是严格地从左到右地查看 源程序进行归约了。
对于任何关于B的产生式B→ γ ,项目B→ .γ 也属于CLOSURE(I); ③ 重复②直到CLOSURE(I)不再增大为止。 此CLOSURE(I)即为所求的一个项目子集, 将其作为DFA的一个状态。
36
项目集闭包的例子
文法: 0. E ’ → E 1. E → E+T 2. E → T 3. T → T*F 4. T → F 5. F →i 6. F →(E)
如果文法G’的项目集规范族的每个项目 集中不存在下述冲突项目:
①移进项目和归约项目并存, ②多个归约项目并存, 则称文法G’为LR(0)文法。
化为DFA,这样工作量较大,不可取。
对于构成识别一个文法活前缀的DFA项 目集(状态)的全体称为这个文法的LR(0)项目 集规范族。
求解方法: 状态:闭包函数(CLOSURE); 转换关系:转换函数(GO)
35
项目集I的闭包CLOSURE(I)
设I是文法G’(拓广文法)的任一项目集, 则定义和构造CLOSURE(I)的规则如下: ① 属于I的任何项目也属于CLOSURE(I); ② 若A → α .Bβ 属于CLOSURE(I),那么,
17
LR分析器的逻辑结构
文法不同, 分析Βιβλιοθήκη Baidu就不同。
输入串 a1 … ai … an # 状态符号栈
LR分析表是 LR分析器的
Sn Xn Sn-1 Xn-1
核心,包括动 作(ACTION)
……
总控程序
输出 表和状态转换
…… ……
(GOTO)表。
S1 X1
它们都可以用
S0
#
动作表 action
状态转移表 goto
输入串 a1 … ai … an # 状态符号栈
Sn Xn Sn-1 Xn-1 ……
……
……
S1 X1
S0
#
总控程序
输出
动作表 action
状态转移表 goto
分析表
LR分 析法也是一 种表驱动的 分析方法, 有一个分析 栈、一个总 控程序和一 个分析表。
特殊性 栈 = 状态栈 + 文法符号栈 分析表 = 动作表(ACTION) + 状态转移表(GOTO)
定义:设I是一个项目集,X是任一文法符号, 则go(I,X)定义为:go(I,X)=CLOSURE(J),
其中J={任何具有[A → αX.β]的项目| [A → α.Xβ] ∈ I }。
I:A→α·Xβ
X
J:A→αX·β
39
识别活前缀的DFA的构造步骤
对文法进行拓广; 构造拓广文法的LR(0)项目集规范族 (由初始项目出发,利用CLOSURE和go函
“.”的左部符号表示已被 识别出来的那部分句柄符 号。
9
LR分析法的实现原理
有上述状态可见,语法分析程序完全可 以根据当前的分析栈来判断句柄的头和尾, 并实行正确的归约,这就是LR分析法的基本 原理。
10
在规范归约过程中,一方面记住已移进 和归约出的整个符号串,即记住“历史”, 另一方面根据所用的产生式推测未来可能碰 到的输入符号,即对未来进行“展望”。
2
LR分析法是严格的规范归约
LR分析法是一种自底向上的语法分析 方法,它严格地从左到右地读入输入符号串 中的符号,且最多向前看确定个数(k个)的符 号,就能无回溯地识别给定的符号串。
3
§6.1 LR分析的基本原理
6
自底向上分析法是一种移进-归约过程, 当分析的栈顶符号串形成句柄时就采取归约 动作,因而自底向上分析法的关键问题是在 分析过程中如何确定句柄。
37
若I={E ’ →.E} CLOSURE(I)为:
E ’ →.E E→.E+T E→.T T→.T*F T→.F F→.i F→.(E)
利用上述算法可以把拓广文法G’的所有 LR(0)项目分成几个等价类,每个等价类就是 识别活前缀的DFA的一个状态。
38
go(I,X)函数
如果LR(0) 项目集规范族中的每个项目 集看做DFA一个状态,则项目集规范族的go 函数把这些项目集连接成一个DFA。
简单的LR分析表:
简称SLR ,最容易实现,但功能最弱。
向前看的LR分析表:
简称LALR,功能和代价处于前两者之间,适用于 绝大多数程序语言的文法。
19
LR分析法的每一步工作都是由栈顶状态 和当前输入符号所唯一确定的。
一个LR分析器实质上是一个带先进后出 栈的确定的有限自动机。
20
§6.3 LR(0)分析表的构造
活前缀已含有句柄的全部符号,表明产生式 A→β的右部β已出现在栈顶,相应的动作是 归约。
27
对规范句型活前缀的识别
对于一个文法G,可以构造一DFA去识 别给定文法的所有规范句型的活前缀,进而 由此构造文法的LR分析表,用来指导对句柄 的识别—可根据分析栈的栈顶状态了判断是 否得到句柄,并进行归约。只要输入串的已 扫描的部分(符号栈中的内容)可构成一个活前 缀,则说明所扫描过的部分没有错误。
在讨论LR(0)分析表的构造之前,需要 定义一个重要概念,即文法的规范句型的 “活前缀”。
23
一、规范句型的活前缀
字(符号串)的前缀:字的前缀是指该字的任 意首部。
活前缀:是指规范句型的活前缀,它不包含 该句型的句柄右边的任何符号。
在活前缀的右边添上一些终结符号后,总可 以构成一个规范句型。
4. A → aBc ·
注意:一个产生式可对 应的项目为它的右部符 号长度加1,对空产生式 A→ε仅有项目A→· 。
29
直观地,一个项目指明了在分析过程的某 一时刻,已经看到的一个产生式的多少。 即 在LR(0)项目中,“·”左部符号串表示已被识 别出来的句柄符号。 “·”右部符号串表示待 识别的符号部分。
41
I1 S’ →S.
S
I0 S’ →.S S → .vI:T
I2
v
S → v.I:T I→.I,i
I→.i
i
I4 I→i.
I3
I S → vI.:T
I→I.,i

I6 I→I,.i
I5
: S → vI:.T
T→.r
I7
T S → vI:T.
r I8
T→r.
iI9 I→I,i.
42
四、LR(0)文法
回忆 算符优先分析
法是如何确定句柄 的?
7
在语法分析中,句柄是逐步形成的。 据此,可以用“状态”的概念来描述不同 时刻所形成的那部分句柄。 把每个句柄的识别过程划分为若干状态, 在每个状态下从左到右识别句柄的一个符号。
8
由于句柄就是某个产生式的右部,因此可 以利用产生式来表示识别句柄的不同状态。 例如,对于产生式A→aBcD,就可以分解为 下面几个不同的识别状态:
文法G[S]的拓广:G’[S’]=G[S]+{S’ → S}; 文法的每个项目为NFA的一个状态; 确定状态之间的转换关系; 按规则可对文法G’的所有项目对应的状态构
造出识别活前缀的NFA。
34
LR(0)项目集规范族C
提出“LR(0)项目集规范族”的原因 若按以上方法先构造NFA,然后再确定
24
LR识别过程中,栈里面的符号(自栈底 而上)就是一个活前缀,把输入串的剩余部分 配上后应成为一个规范句型。因此,只要输 入串已扫描过的部分能构成一个活前缀,则 意味着所扫描过的这一部分没有错误。
若A →β是文法的一个产生式,S是开始
符号,有S
*
=R >
αAω
=R >αβω,
r是αβ的前缀,
则称r是规范句型αβω的活前缀。
16
LR分析器的逻辑结构
对于所
有的LR分析
输入串 a1 … ai … an # 状态符号栈
器,总控程 序都是相同
Sn Xn Sn-1 Xn-1 …… ……
总控程序
的。 输出
……
S1 X1
S0
#
动作表 action
状态转移表 goto
分析表
在总控程序的控制下,自左到右扫描输入串,并 根据当前分析栈存放的文法符号和状态及下一个要入 栈的符号,按分析表的指示完成相应的动作:移进、 归约、接受或报错。
25
有一规范句型E+T*F+i,现求出该规范句型 的活前缀。
规范句型:E + T * F + i
26
活前缀和句柄的关系
活前缀不含有句柄的任何符号,此时期望从 剩余输入串中识别由A→β的右部所推出的符 号串。
活前缀只含句柄的一部分符号,表明形如 A→β1β2的产生式右部子串β1已出现在栈顶, 期待从输入串中看到β2推出的符号。
分析表
二维数组表示。
动作表中的每一个元素ACTION[S,a]规定了当栈 顶状态为S,且面临输入符号a时应采取的动作。 状 态转换表中的每一个元素GOTO[S,x]规定了当状态S 面对文法符号位x时的下一个状态。
18
LR分析表的构造方法
LR分析器的关键部分是分析表的构造。 规范的LR分析表:
LR(0),能力最弱,局限性较大,但理论上最重要; LR(1),它功能最强,但代价也最大。
32
三、识别所有规范句型全部活前缀的DFA
在作出文法的全部LR(0)项目后可以用它
们来构造识别文法全部活前缀的DFA,这种
DFA的每一个状态都由若干个LR(0)项目所组
成的集合(项目集)来表示。
为什么?
回忆 在第3章 词法
分析中,DFA是如
因为有一 些状态是 等价的。
何获得的?
33
构造识别活前缀的NFA
当一串貌似句柄的符号串呈现于分析栈的 顶端时,根据所记载的“历史”和“展望” 材料,来确定栈顶的符号串是否构成句柄。
11
为了记住分析的“历史”和汇集“展望” 的信息,LR分析法这样处理:
将归约过程的“历史”和“展望”材料 综合抽象成某些状态,存放在一个状态栈中, 栈中每个状态都概括了从分析开始直到某一 归约阶段的全部“历史”和“展望”材料。
13
LR分析法的最大优点
LR分析法是一个有效的自底向上分析技 术,它与自顶向下的LL(1)分析方法和自底向 下的优先分析方法相比对文法的限制要少得 多。
对于大多数用无二义性上下文无关文法 描述的程序语言都可以用相应的LR分析器进 行有效的分析。
14
§ 6.2 LR分析器的逻辑结构
15
LR分析器的逻辑结构
12
LR(k)的含义
L表示从左到右扫描输入串; R表示利用最右分析方法来识别句子,即构造 一个最右推导的逆过程; k表示向右查看输入串符号的个数。
规范推导的逆过程,所以LR 分析过程是规范归约的过程。
LR分析法根据当前分析栈中的符号串和 向右顺序查看输入串的k个符号就可以唯一确 定分析器的动作是移进还是归约、利用那个 产生式进行归约。
21
首先讨论一种只概括“历史”资料而不 包含推测性“展望”材料的“状态”。我们 希望仅由这种简单状态就能识别呈现在栈顶 的句柄。
LR(0)分析即LR(k)分析中k=0的特殊情 况:仅根据当前的栈顶状态就能确定应执行 何种分析动作,它主要依据LR(0)分析表进行 工作。
22
由于LR(0)分析器在分析过程中不需要向 右查看输入符号,因而它对文法的限制较大, 对绝大多数高级语言的语法分析器是不能适 用的,但它是其他LR类分析器的基础。
对句柄的识别就变成了对规范句型活 前缀的识别。因此,活前缀反映了句柄的 识别状态。
28
二、LR(0)项目及其分类
定义:在文法的每一个产生式的右部适当位 置添加一个圆点“.”,则一个 LR(0)项目。
A → aBc的LR(0)项目:
1. A → · aBc
2. A → a ·Bc
3. A → aB ·c
可以由文法的所有LR(0)项目,构造识别 文法所有活前缀的DFA。
30
文法G的拓广
为了使“接受”状态容易识别,把文法 G进行拓广。
G’=G+{S’→S} 显然,L(G)=L(G’)。当LR分析器用它来 进行归约时,整个分析工作正常结束。
31
LR(0)项目的分类
根据圆点所在的位置和圆点后是终结符 还是非终结符或为空把项目分为以下几种: 移进项目,形如 A → • a 待约项目,形如 A → • B 归约项目,形如 A → • 接受项目,形如 S’ →S •
相关文档
最新文档