概述
- 规范规约:句柄作为可规约串
- 工作流程:将文法交给分析表产生器,产生分析表。将输入交给总控程序,配合上分析表,得到输出
句柄和规范规约
定义
- 短语:令
G
G
G是一个文法,
S
S
S是文法的开始符号,假定
α
β
δ
\alpha \beta \delta
αβδ是文法
G
G
G的一个句型,如果有:
S ⇒ ∗ α A δ S \xRightarrow{*} \alpha A \delta S∗αAδ且 A ⇒ + β A \xRightarrow{+} \beta A+β
则 β \beta β称是句型 α β δ \alpha \beta \delta αβδ相对于非终结符 A A A的短语 - 直接短语:如果有 A ⇒ β A \Rightarrow \beta A⇒β,则称 β \beta β是句型 α β δ \alpha \beta \delta αβδ相对于规则 A → β A \rightarrow \beta A→β的直接短语。
- 句柄:一个句型的最左直接短语称为该句型的句柄
规范规约
定义:假定 α \alpha α是文法 G G G的一个句子,我们称序列 α n , α n − 1 , … , α 0 \alpha_n, \alpha_{n-1},\dots,\alpha_0 αn,αn−1,…,α0是 α \alpha α的一个规范规约,如果此序列满足:
- α n = α \alpha_n = \alpha αn=α
- α 0 \alpha_0 α0为文法的开始符号,即 α 0 = S \alpha_0 = S α0=S
- 对于任何 i i i, 0 ≤ i ≤ n 0 \leq i \leq n 0≤i≤n, α i − 1 \alpha_{i-1} αi−1是从 α i \alpha_i αi经把句柄替换成为相应产生式左部符号而得到的。
规范句型
- 规范规约是最左规约
- 规范规约的逆过程就是最右推导
- 最右推导也称为规范推导
- 由规范推导推出的句型称为规范句型
LR分析法
规范规约VS句柄
- 规范规约的关键问题是寻找句柄
- 历史:已移入符号栈的内容
- 展望:根据产生式推测未来可能遇到的输入符号
- 现实:当前的输入符号
LR分析法的结构
- LR分析方法:把“历史”及“展望”综合抽象成状态;由栈顶的状态和现行的输入符号唯一确定每一步工作
LR分析表
LR分析器的核心是一张分析表
-
A
C
T
I
O
N
[
S
,
a
]
ACTION[S, a]
ACTION[S,a]:当状态
s
s
s面临输入符号
a
a
a时,应采取什么动作
- 移进(shift):把 ( s , a ) (s, a) (s,a)的下一个状态 s ′ s' s′和输入符号 a a a推进栈,下一输入符号变成现行输入符号
- 规约(reduce):用某产生式 A → β A \rightarrow \beta A→β进行规约。假若 β \beta β的长度为 r r r,去除栈顶 r r r个项,使状态 s m − r s_{m-r} sm−r变成栈顶状态,然后把下一状态 s ′ = G O T O [ s m − r , A ] s' = GOTO[s_{m-r},A] s′=GOTO[sm−r,A]和文法符号 A A A推进栈
- 接受:宣布分析成功,停止分析器工作
- 报错
- G O T O [ s , X ] GOTO[s, X] GOTO[s,X]:状态 s s s面对文法符号 X X X时,下一状态是什么
LR分析法演示
根据文法
G
(
E
)
G(E)
G(E):
(1)
E
→
E
+
T
E \rightarrow E + T
E→E+T
(2)
E
→
T
E \rightarrow T
E→T
(3)
T
→
T
∗
F
T \rightarrow T * F
T→T∗F
(4)
T
→
F
T \rightarrow F
T→F
(5)
F
→
(
E
)
F \rightarrow (E)
F→(E)
(6)
F
→
i
F \rightarrow i
F→i
分析输入串
i
∗
i
+
i
i * i + i
i∗i+i
LR分析表为:
ACTION | GOTO | ||||||||
---|---|---|---|---|---|---|---|---|---|
状态 | i | + | * | ( | ) | # | E | T | F |
0 | s5 | s4 | 1 | 2 | 3 | ||||
1 | s6 | acc | |||||||
2 | r2 | s7 | r2 | r2 | |||||
3 | r4 | r4 | r4 | r4 | |||||
4 | s5 | s4 | 8 | 2 | 3 | ||||
5 | r6 | r6 | r6 | r6 | |||||
6 | s5 | s4 | 9 | 3 | |||||
7 | s5 | s4 | 10 | ||||||
8 | s6 | s11 | |||||||
9 | r1 | s7 | r1 | r1 | |||||
10 | r3 | r3 | r3 | r3 | |||||
11 | r5 | r5 | r5 | r5 |
步骤 | 状态 | 符号 | 输入值 |
---|---|---|---|
1 | 0 | # | i*i+i# |
2 | 05 | #i | *i+i# |
3 | 03 | #F | *i+i# |
4 | 02 | #T | *i+i# |
5 | 027 | #T* | i+i# |
6 | 0275 | #T*i | +i# |
7 | 027 10 | #T*F | +i# |
8 | 02 | #T | +i# |
9 | 01 | #E | +i# |
10 | 016 | #E+ | i# |
11 | 0165 | #E+i | # |
12 | 0163 | #E+F | # |
13 | 0169 | #E+T | # |
14 | 01 | #E | # |
15 | 接受 |
LR文法
- 定义:对于一个文法,如果能够构造一张分析表,使得它的每个入口均是唯一确定的,则这个文法就称为LR文法。
- 定义:一个文法,如果能用一个每步顶多向前检查 k k k个输入符号的LR分析器进行分析,则这个文法就称为LR(k)文法
- LR文法不是二义的,二义文法肯定不是LR文法。