最近在复习编译原理,考试之前以为自己懂了,眼高手低就没去实践。结果一考试出问题了。。。。
学习就要脚踏实地,容不得半点模糊。凭着侥幸心理很危险的。以后要引以为戒啊。
特别写出这篇文章 :一来总结一下这几天的收获。二来与君共勉。
一、概念
1.概念解释
1、活前缀:不包含句柄右侧任一符号的规范句型的前缀称为该句型的活前缀。
例如:Bab是下面那个文法的一个句型,其中b是句柄。
那么针对这个句型的活前缀有:ε、B、Ba 和Bab
(其实,LR分析器的工作过程实际上就是逐步产生规范句型的活前缀。
如果能构造出一个识别文法所有规范句型活前缀的确定有穷自动机即DFA,就能很方便的构造出LR分析表)
2、LR(0)项目:右部某位置上标有圆点的产生式称为相应文法的一个LR(0)项目
注意:A --> ε 只对应一个项目 A --> .
(LR(0)项目描述了活前缀和句柄的不同识别状态)
3、ε-可达:从 S' --> .S 出发,不必再识别任何符号就可以到达 S --> .BB,就称 S --> .BB是从
S' --> .S 出发 ε-可达的。
4、项目集闭包:用Item0表示DFA的初始状态,对应分析的开始,并期待着逐步将输入符号串
归约为开始符号S‘。因此将S' --> .S 放到 Item0 中,意即等待归约出S,且目前尚未
得到S的任何符号。
Item0 = CLOSURE({S' --> .S}) = {S' --> .S,S --> .BB,B --> .aB,B --> .b}
该项目集合中所有的项目都是从S' --> .S 出发 ε-可达的,称为{S' --> .S}的项目集闭包
(每个项目集闭包对应着分析器的一个状态)
5、后继项目:项目 A --> αX.β 称为 A --> α.Xβ 的后继项目
6、后继项目集:假定Item0是文法G的一个LR(0)项目集,
则称 GO(Item0,X) = CLOSURE({A --> αX.β}) 为 Item0 关于X的后继项目集。
GO为项目集的转移函数。
7、项目集规范族:项目集的全体
2.例子
文法:
S --> BB
B --> aB
B --> b
二、实现步骤
1.扩展文法
S' --> S
S --> BB
B --> aB
B --> b
2.求出项目集规范族
Item0 = CLOSURE({S' --> .S}) = {S' --> .S,S --> .BB,B --> .aB,B --> .b}
Item1 =GO(Item0,S) = CLOSURE({S' --> S.}) = {S' --> S.}
Item2 = GO(Item0,B) = CLOSURE({S --> B.B}) = {S --> B.B,B --> .aB,B --> .b}
Item3 = GO(Item0,a) = CLOSURE({B --> a.B}) = {B --> a.B,B --> .aB,B --> .b}
Item4 = GO(Item0,b) = CLOSURE({B --> b.}) = {B --> b.}
至此Item0已经遍历完,开始遍历下一个,由于Item1圆点已经到达末尾,所以跳过Item1。
Item5 = GO({Item2,B) = CLOSURE({S --> BB.}) = {S --> BB.}
由于 GO(Item2,a) 和 GO(Item2,b) 重复,所以去掉。
Item6 = GO(Item3,B) = CLOSURE({B --> aB.}) = {B --> aB.}
由于 GO(Item3,a) 和 GO(Item3,b) 重复,所以去掉。
至此,项目集闭包不再增加,所以项目集规范族构造完毕!
3.构造DFA
方法很简单,看一下结果就懂了,在这里就不赘述了。
需要注意的是:要找到每个集合和其他集合所有的转移路径,容易遗漏!
![](https://images2015.cnblogs.com/blog/699056/201705/699056-20170501210114773-1055044207.jpg)
4.构造LR(0)分析表(根据自己画出的DFA图,将分析表填充)
输入:文法G的扩展文法G'
输出:G'的LR(0)分析表(即 Action表和Goto表)步骤:
1、本例中Item2 --B--> Item5,则在 状态号为2的行,列名为B的格中填入状态5
(转移条件为非终结符,填充Goto表,填入状态号, 转移条件为终结符,填充Action表,
填入Sn,Sn表示移进,移进符号并且移进状态号n)
Item2 --a--> Item3 ,则在状态号为2的行,列名为a的格填入S3。
2、对于圆点在右部最右边:
if A --> α. ∈ Itemk (0<k<n) & A --> α 为G的第 j 个产生式,
then for 任意 a ∈ T U {#} do
Action[k,a] = Rj
(Rn表示归约,不移进符号,用第n个产生式的右部替换符号栈的X)
3、if S' --> S. ∈Itemk (0<k<n) then Action[k,#] = acc.
![](https://images2015.cnblogs.com/blog/699056/201705/699056-20170501210153351-1752911041.jpg)