LR(0)文法项目集规范族、DFA和分析表的构建实例




最近在复习编译原理,考试之前以为自己懂了,眼高手低就没去实践。结果一考试出问题了。。。。

学习就要脚踏实地,容不得半点模糊。凭着侥幸心理很危险的。以后要引以为戒啊。

特别写出这篇文章 :一来总结一下这几天的收获。二来与君共勉。



一、概念

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

方法很简单,看一下结果就懂了,在这里就不赘述了。

需要注意的是:要找到每个集合和其他集合所有的转移路径,容易遗漏!

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.

时间: 2024-10-27 14:00:09

LR(0)文法项目集规范族、DFA和分析表的构建实例的相关文章

求LR(0)文法的规范族集和ACTION表、GOTO表的构造算法

原理 数据结构 1 // GO 2 private static Map<Map<Integer,String>,Integer> GO 3 = new HashMap<Map<Integer,String>,Integer>(); 4 5 // 规范族集 C 6 private static Map<Integer,Map<String,List<String>>> C 7 = new HashMap<Intege

LL(1),LR(0),SLR(1),LR(1),LALR(1)的 联系与区别

一:LR(0),SLR(1),规范LR(1),LALR(1)的关系     首先LL(1)分析法是自上而下的分析法.LR(0),LR(1),SLR(1),LALR(1)是自下而上的分析法.            自上而下:从开始符号出发,根据产生式规则推导给定的句子.用的是推导            自下而上:从给定的句子规约到文法的开始符号.用的是归约      1: SLR(1)与LR(0)的关系:            SLR(1)与LR(0):简单的LR语法分析技术(即SLR(1)分析技

LL(1),LR(0),SLR(1),LALR(1),LR(1)对比与分析

前言:考虑到这几种文法如果把具体内容讲下来肯定篇幅太长,而且繁多的符号对初学者肯定是极不友好的,而且我相信看这篇博客的人已经对这几个文法已经有所了解了,本篇博客的内容只是对 这几个文法做一下对比,加深大家对这几个文法的理解.更详细的细节,初学者可以看看这个课件https://files-cdn.cnblogs.com/files/henuliulei/%E7%AC%AC5%E7%AB%A0.ppt,或者其他相关的博客. 一:五种文法的演变 1.1 LL(1)文法 LL(1)文法是自上而下的分析方

新闻标题:PMP高级修炼:国际项目集管理PgMP与实战工作坊成功举办

新闻作者:共创国际-项目管理者联盟   新闻正文: 读了几遍PMBOK,有PMP证书,就以为懂项目管理,OUT了!组织项目管理需要构建项目组合.项目集与单项目的三级项目体系,才能支撑组织业务与项目良好运营. 作为三级项目体系承上启下的中间核心管理层,项目集管理需要收益(benefit)导向,战略(strategy)一致,治理(governance)规划,干系人争取(engagement),拥抱变更(change).面对变化的环境与高不确定性,项目集管理理念.流程与方法,才是应对现实世界的真实“项

LR(1)文法分析器 //c++ 实现

1.先读入终结符,非终结符,和全部产生式. 2.预处理:初始化:getpp()获得每一个非终结符在产生式左边时的产生式编号, 记录在 string getp[]中(能够多个). 3.获得全部的符号的first集:dfs法,从S開始DFS,遇到终结符则是递归出口,回溯时候沿路保存记录全部路径上VN的first,(遇到有左递归的,continue,左递归的产生式不用不影响求fisrt集) 4:获得项目集族:一个lr(1)项目用一个结构体记录,get_close(项目 t):bfs来完毕对t的闭包.g

LR(1)文法智能分析

LR1文法全智能分析 // by hfut yzk #include "stdafx.h" #include<fstream> #include<string> #include<map> #include<vector> #include<stack> #include<set> #include<cstring> #include<queue> using namespace std;

第十一周 项目四 类族的设计】

项目4 - 类族的设计] 按以下的提示,由基类的设计和测试开始,逐渐地完成各个类的设计,求出圆格柱体的表面积.体积并输出并且完成要求的计算任务: (1)先建立一个Point(点)类,包含数据成员x,y(坐标点),实现需要的成员函数,并设计main函数完成测试: (2)以Point为基类,派生出一个Circle(圆)类,增加数据成员r(半径),以及求面积的成员函数area,实现其他需要的成员函数,设计main函数完成测试: (3)再以Circle类为直接基类,派生出一个Cylinder(圆柱体)类

Apache 2.4.12 64位+Tomcat-8.0.32-windows-x64负载集群方案

上次搞了Apache 2.2的集群方案,但是现在自己的机器和客户的服务器一般都是64位的,而且tomcat已经到8了.重新做Apache 2.4.12 64位+Tomcat-8.0.32-windows-x64负载集群方案. 知其然知其所以然,先看下一些关键术语: 1.负载均衡(load balance)在互联网高速发展的时代,大数据量.高并发等是互联网网站提及最多的.如何处理高并发带来的系统性能问题,最终大家都会使用负载均衡机制.它是根据某种负载策略把请求分发到集群中的每一台服务器上,让整个服

C++第11周(春)项目4 - 类族的设计

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 [项目4 - 类族的设计]按下面的提示,由基类的设计和測试開始,逐渐地完毕各个类的设计,求出圆格柱体的表面积.体积并输出而且完毕要求的计算任务:    (1)先建立一个Point(点)类,包括数据成员x,y(坐标点),实现须要的成员函数,并设计main函数完毕測试:    (2)以Point为基类,派生出一个Circle(圆)类,添加数据成员r