Content
- LR完整分析过程
- 画LR(0)项目 + 填LR(0)分析表
- 画SLR(1)项目 + 填SLR(1)分析表
- 画LR(1)项目 + 填LR(1)分析表
- 画LALR(1)项目 + 填LALR(1)分析表
LR分析过程
已知文法生成式(已标号)
1 | E → E + T |
2 | E → T |
3 | T → T * F |
4 | T → F |
5 | F → ( E ) |
6 | F → I |
已知LR分析表(根据项目图+已标号文法写出来的)
完整分析过程
状态栈 | 串 | 串 | 操作 |
---|---|---|---|
0 | # | i*i+i# | s5 |
05 | #i | *i+i# | r6 |
03 | #F | *i+I# | r4 |
02 | #T | i+i# | s7 |
027 | #T* | i+i# | s5 |
0275 | #T*i | +i# | r6 |
027 10 | #T*F | +i# | r3 |
02 | #T | +i# | r2 |
01 | #E | +i# | s6 |
016 | #E+ | i# | s5 |
0165 | #E+i | # | r6 |
0163 | #E+F | # | r4 |
0169 | #E+T | # | r1 |
01 | #E | # | Accept |
画LR(0)项目
方法:
- 先添加一个
S
‘
→
S
S‘ → S
S‘→S
- 不断进行状态转移并求closure闭包
已知文法,画出这个文法的所有LR(0)项目?
E
→
a
A
E → aA
E→aA
E
→
b
B
E → bB
E→bB
A
→
c
A
A → cA
A→cA
A
→
d
A → d
A→d
B
→
c
B
B → cB
B→cB
B
→
d
B → d
B→d
填LR(0)分析表
方法:
- 先对文法进行标号
- 根据LR(0)项目图画出LR(0)分析表
0 | S‘ → E |
1 | E → aA |
2 | E → bB |
3 | A → cA |
4 | A → d |
5 | B → cB |
6 | B → d |
a | b | c | d | # | E | A | B | |
---|---|---|---|---|---|---|---|---|
0 | s2 | s3 | 1 | |||||
1 | Accept | |||||||
2 | s4 | s10 | 6 | |||||
3 | s5 | s11 | 7 | |||||
4 | s4 | s10 | 8 | |||||
5 | s5 | s11 | 9 | |||||
6 | r1 | r1 | r1 | r1 | r1 | |||
7 | r2 | r2 | r2 | r2 | r2 | |||
8 | r3 | r3 | r3 | r3 | r3 | |||
9 | r5 | r5 | r5 | r5 | r5 | |||
10 | r4 | r4 | r4 | r4 | r4 | |||
11 | r6 | r6 | r6 | r6 | r6 |
画SLR(1)项目
和LR(0)的画法项目集的方法完全一样
S
‘
→
S
S‘ → S
S‘→S
S
→
r
D
S → rD
S→rD
D
→
D
?
i
D → D*i
D→D?i
D
→
i
D → i
D→i
图略
画完之后你会发现一个问题:
I
3
I3
I3集合为?
S
→
r
D
?
S → rD·
S→rD??
D
→
D
?
?
i
D → D·*i
D→D??i —— 在填分析表的时候会出现多重入口——出现了归约/移进冲突
这个冲突其实是有可能解决的,接着往下看
填SLR(1)分析表
在填SLR(1)分析表的时候,我们这样解决「归约/移进冲突」:
对于规约的那个式子,求其左侧VN的随符集Follow,只有在Follow中符号对应的地方才填r
上面例题的答案大概是下面的样子(可以验证下自己答案):
r | * | i | # | S | D | |
---|---|---|---|---|---|---|
0 | s2 | 1 | ||||
1 | acc | |||||
2 | s4 | 3 | ||||
3 | s5 | r1 | ||||
4 | r3 | r3 | r3 | r3 | ||
5 | s6 | |||||
6 | r2 | r2 | r2 | r2 |
画LR(1)项目
基本思路差不多与LR(0)和SLR(1)一致,(重点!!!)区别在于:
A
→
α
?
B
β
,
a
A→α·Bβ,a
A→α?Bβ,a? 求闭包为:
B
→
?
γ
,
b
B→·γ,b
B→?γ,b ?其中 b = First(βa)(也就是说,如果B后还有个β,b就为First(β);若B后什么都没有,b就把a继承下来)
S
‘
→
S
S‘ → S
S‘→S
S
→
B
B
S → BB
S→BB
B
→
a
B
B → aB
B→aB
B
→
b
B → b
B→b
画出其项目集:
填LR(1)分析表
移进的时候(就是s几),还是老样子
归约的时候(就是r几),不是像LR(0)那样全都填满,也不是像SLR(1)那样根据Follow集填,而是根据逗号右边的符号来填
还是给出上面例题的答案(自己对照着验证一下):
a | b | # | S | B | |
---|---|---|---|---|---|
0 | s3 | s4 | 1 | 2 | |
1 | acc | ||||
2 | s6 | s7 | 5 | ||
3 | s3 | s4 | 8 | ||
4 | r3 | r3 | |||
5 | r1 | ||||
6 | s6 | s7 | 9 | ||
7 | r3 | ||||
8 | r2 | r2 | |||
9 | r2 |
画LALR(1)项目
画法和LR(1)项目集的画法完全一样——LALR(1)只需在LR(1)基础上进行小小的改动
填LALR(1)分析表
合并LR(1)分析表的同心集——LALR(1)只需在LR(1)基础上进行小小的改动
何为同心集?
举个例子很容易明白:上面的
I
8
I8
I8和
I
9
I9
I9,即
下面话需要理解一下:
- LR(0)和SLR(1)的项目集画法完全一样——当然
I
I
I状态的个数完全一样;
- LR(1)使得同心集分裂,
I
I
I状态的数目急剧增加
- LALR(1)将LR(1)的同心集全部又合并了回去,也就是说LR(0)、SLR(1)、LALR(1)的状态集数目完全相同
下面给出前一个例题中的分析表进行同心集合并后的结果(自己验证一下答案):
a | b | # | S | B | |
---|---|---|---|---|---|
0 | s3,6 | s4,7 | 1 | 2 | |
1 | acc | ||||
2 | s3,6 | s4,7 | 5 | ||
3, 6 | s3,6 | s4,7 | 8, 9 | ||
4, 7 | r3 | r3 | r3 | ||
5 | r1 | ||||
8, 9 | r2 | r2 | r2 |