LR分析法
LR(0)分析法算法简述
L:left to right parsing
R:right-most derivation in reverse
k:look ahead k to token
方法:移进-归约法
框架:总控程序、分析栈、分析表
分析表中的符号:
- S i S_i Si:第i个状态
- r i r_i ri:第i个产生式
- a:输入串(符号)
- accept:接受,结束
- GOTO:归约后的状态
分析表中的列名:
- ACTION:终结符,单元格内容为S和r
- GOTO:非终结符,单元格内容为S
总控程序的算法:
- 初始化:
(S0, $)
进栈 - 读入下一个输入符号a,根据
ACTION(q, a)
的值执行不同动作;- 移进(Shift):
ACTION[q,a]==Sj
,(q,a)
进入分析栈S - 归约(Reduce):
ACTION[q,a]==rj
,采用规则j
归约- 设规则(j):
A→α
。将|α|
个状态和符号弹出分析栈S; - if(
GOTO[q,A]==null
) ERR(); - else
(GOTO[q,A],A)
入分析栈S。将该状态下A的GOTO结果状态和非终结符A都进入分析栈。
- 设规则(j):
- 报错(ERROR):if(
ACTION[q,a]==null
) ERR(); - 接受(ACCEPT):if(
ACTION[q,a]==acc
) 接受并结束
- 移进(Shift):
理解:从底部叶子往上构造语法分析树的过程
1. 使用分析表模拟主控程序的过程表
在给定分析表的前提下,根据上述总控程序模拟语法分析:
2. 可归前缀和活前缀
设文法G[S],如果S ⇒ R α A ω ⇒ α β ω \Rightarrow _R \alpha A \omega \Rightarrow \alpha\beta\omega ⇒RαAω⇒αβω,则 α β \alpha\beta αβ为可归前缀, α β \alpha\beta αβ的前缀为活前缀。
对于下图中的(3)产生式:
3.识别活前缀DFA
对于文法G:
-
首先添加一个S’,S’→S,确定为起始状态只有一个为S‘
-
对于每一个产生式都产生一个NFA,最后一个状态为句柄识别态(双圈)
①为句子的识别态
-
对于有非终结符出边的状态,同时画一条为 ε \varepsilon ε的边指向产生式左边的非终结符状态。
-
通过子集法,将NFA确定化为DFA
假设输入串为abbcde
进行分析:- S0→a→S1→b→S4,发现到达终止态;
进行归约,退回到S2,使用绿色括号中的产生式(2)即(2)号产生式A→b
归约
输入串:aAbcde
- S2→A→S3→b→S6,发现到达终止态;
进行归约,退回到S3,使用绿色括号中的产生式(3)即(3)号产生式A→Ab
归约
输入串:aAcde
- S3→c→S5→d→S8,发现到达终止态;
进行归约,退回到S5,使用绿色括号中的产生式(4)即(4)号产生式B→d
归约
输入串:aAcBe
- S5→B→S7→e→S9,发现到达终止态;
进行归约,退回到S5,使用绿色括号中的产生式(1)即(1)号产生式S→aAcBe
归约
输入串:S
- S0→S→S1,到达句子识别终止态。
- S0→a→S1→b→S4,发现到达终止态;
4. 构造LR(0)项目集规范族
在产生式中加
⋅
·
⋅来代表不同的状态:
对于:
A
→
α
β
γ
A \rightarrow\alpha\beta\gamma
A→αβγ
分为:(4个状态)
- A → ⋅ α β γ A \rightarrow·\alpha\beta\gamma A→⋅αβγ
- A → α ⋅ β γ A \rightarrow\alpha·\beta\gamma A→α⋅βγ
- A → α β ⋅ γ A \rightarrow\alpha\beta·\gamma A→αβ⋅γ
- A → α β γ ⋅ A \rightarrow\alpha\beta\gamma· A→αβγ⋅
所有上述的项目都成为LR(0)项目
第一种构造DFA的方法:两步构造DFA(先NFA后DFA)
将空边合并,(分步合并为NFA)
第二种构造DFA的方法:一步构造DFA:
规则:对于所有
⋅
·
⋅之后有非终结符的,将该非终结符在左边的产生式合并;同时根据状态之间的迁移逐渐构造出整个DFA
①移进项目:
A
→
α
⋅
a
β
A\rightarrow\alpha·a\beta
A→α⋅aβ
②待约项目:
A
→
α
⋅
X
β
A\rightarrow\alpha·X\beta
A→α⋅Xβ
③归约项目:
A
→
α
⋅
A\rightarrow\alpha·
A→α⋅
④接受项目:
S
′
→
α
⋅
S'\rightarrow\alpha·
S′→α⋅
空规则A→ ε \varepsilon ε 为A→ ⋅ · ⋅
5.根据NFA构造分析表
显然,分析表类似于状态迁移表,因此根据NFA的规则填写分析表。
LR(0)分析不适用的文法和可能产生的冲突
对于分析中会产生的操作,goto是不可能产生二义性的,因此对于Shift和Reduce进行分析。
- shift和shift产生冲突
不存在。因为shift的列为终结符,输入一个终结符不可能转移到两个不同的状态。 - shift和reduce产生冲突
- Reduce和Reduce产生冲突
LR(0)形式化定义
- MOVE运算定义:
MOVE(I,X)={ A → α X ⋅ β A\rightarrow\alpha X·\beta A→αX⋅β| A → α ⋅ X β A\rightarrow\alpha·X\beta A→α⋅Xβ}
表示:从 α ⋅ X β \alpha·X\beta α⋅Xβ状态输入X
转移到 α X ⋅ β \alpha X·\beta αX⋅β - CLOSURE运算定义
- I ⊂ \subset ⊂closure(I)
- { B → γ ∣ A → α ⋅ B β ∈ \{ B\rightarrow\gamma|A\rightarrow\alpha·B\beta \in {B→γ∣A→α⋅Bβ∈closure(I) } ⊂ \}\subset }⊂closure(I)
- 重复(2),直到closure(I)不再扩大为止
- 设文G=
(
V
N
,
V
T
,
P
,
S
)
(V_N, V_T, P, S)
(VN,VT,P,S),已经改写成为文法G’
参考资料:
https://www.bilibili.com/video/BV1jh411R7Z9
https://www.bilibili.com/video/BV1yY4y187MS