ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:31.15KB ,
资源ID:6121518      下载积分:12 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6121518.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(LR0分析表.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

LR0分析表.docx

1、LR0分析表自动生成LR(0)分析表:彦清 学号:E10914127一、实验目的输入:任意的压缩了的上下文无关文法。输出:相应的LR(0)分析表。二、实验原理对于LR文法,我们可以自动构造相应的LR分析表。为了构造LR分析表,我们需要定义一个重要概念文法的规句型“活前缀”。这种句柄之后不含任何符号的前缀称为活前缀。在LR分析工作过程中的任何时候,栈里的文法符号(自栈底而上)X1X2Xm应该构成活前缀,把输入串的剩余部分配上之后即应成为规句型(如果整个输入串确实构成一个句子)。因此,只要输入串的已扫描部分保持可归约成一个活前缀,那就意味着所扫描过的部分没有错误。对于一个文法G,我们可以构造一个有

2、限自动机,它能识别G的所有活前缀,然后把这个自动机转变成LR分析表,按照该LR分析表进行LR分析,就能保证在分析的过程中,如果分析的句子是正确的,栈里的文法符号(自栈底而上)始终构成活前缀。假若一个文法G的拓广文法的活前缀识别自动机中的每个状态(项目集)不存在下述情况:(1)既含移进项目又含归约项目;(2)含有多个归约项目,则称G是一个LR(0)文法。该自动机的状态集合即为该文法的LR(0)项目集规族。构造识别文法活前缀DFA有3种方法:(1)根据形式定义求出活前缀的正则表达式,然后由此正则表达式构造NFA再确定为DFA;(2)求出文法的所有项目,按一定规则构造识别活前缀的NFA再确定化为DF

3、A;(3)使用闭包函数(CLOSURE)和转向函数(GO(I,X)构造文法G的LR(0)的项目集规族,再由转换函数建立状态之间的连接关系来得到识别活前缀的DFA。符号串的前缀是指该符号串的任意首部,包括空串。例如,对于符号串abc,其前缀有,a,ab,abc。如果输入串没有错误的话,一个规句型的活前缀是该句型的一个前缀,但它不含句柄之后的任何符号。之所以称为活前缀,是因为在该前缀后联接尚未输入的符号串可以构成一个规句型。活前缀与句柄的关系如下:(1)活前缀已含有句柄的全部符号,表明产生式A的右部已出现在栈顶。(2)活前缀只含句柄的一部分符号,表明A12的右部子串1已出现在栈顶,期待从输入串中看

4、到2推出的符号。(3)活前缀不含有句柄的任何符号,此时期望A的右部所推出的符号串。在文法G的每个产生式的右部(候选式)的任何位置上添加一个圆点,所构成的每个产生式称为LR(0)项目。如产生式A xyz有如下项目:A .xyz,A x.yz,A xy.z,A xyz.。为刻划分析过程中的文法的每一个产生式的右部符号已有多大一部分被识别(出现在栈顶),可以用这种标有圆点的产生式来确定。(1)A.刻划产生式A的右部已出现在栈顶。 (2)A1.2 刻划A12的右部子串1已出现在栈顶,期待从输入串中看到2推出的符号。 (3)A. 刻划没有句柄的任何符号在栈顶,此时期望A的右部所推出的符号串。(4)对于A

5、的LR(0)项目只有A。 设文法G=(VT,VN,S,P)是一个上下文无关文法,若存在一个规推导SAw12w(其中A12P),则称项目A12对活前缀=1是有效的,即LR(0) 有效项目。从直观意义上讲,一个LR(0)项目指明了在分析过程中的某一步我们看到产生式的多大部分被识别,LR(0)项目中的圆点可看成是分析栈栈顶与输入串的分界线,圆点左边为已进入分析栈的部分,右边是当前输入或继续扫描的符号串。不同的LR(0)项目,反映了分析栈顶的不同情况。我们根据LR(0)项目的作用不同,将其分为四类:(1)归约项目:表现形式:Aa.这类LR(0)项目表示句柄a恰好包含在栈中,即当前栈顶的部分容构成了所期

6、望的句柄,应按Aa进行归约。(2)接受项目:表现形式:a.其中是文法惟一的开始符号。这类LR(0)项目实际是特殊的归约项目,表示分析栈中容恰好为a,用a进行归约,则整个分析成功。(3)移进项目:表现形式:Aa.(bVT)这类LR(0)项目表示分析栈中是不完全包含句柄的活前缀,为构成恰好有句柄的活前级,需将b移进分析栈。(4)待约项目:表现形式:A.B (BVN)这类LR(0)项目表示分析栈中是不完全包含句柄的活前缀,为构成恰好有句柄的活前缀,应把当前输入字符串中的相应容先归约到B。在给出LR(0)项目的定义和分类之后,我们从这些LR(0)项目出发,来构造能识别文法所有前缀的有限自动机。其步骤是

7、:首先构造能识别文法所有活前缀的非确定的有限自动机,再将其确定化和最小化,最终得到所需的确定的有限自动机。由文法G的LR(0)项目构造识别文法G的所有活前缀的非确定有限自动机的方法:(1)规定含有文法开始符号的产生式(设A)的第一个LR(0)项目(即.A)为NFA的惟一初态。(2)令所有LR(0)项目分别对应NFA的一个状态且LR(0)项目为归约项目的对应状态为终态。(3)若状态i和状态j出自同一文法G的产生式且两个状态LR(0)项目的圆点只相差一个位置,即:若i为XX1X2Xi-1XiXn, j为 XX1X2XiXi+1Xn,则从状态i引一条标记为Xi的弧到状态j。(4)若状态i为待约项目(

8、设XA),则从状态i引弧到所有Ar的状态。为了使“接受”状态易于识别,我们通常将文法G进行拓广。假定文法G是一个以S为开始符号的文法,我们构造一个,它包含了整个G,但它引进了一个不出现在G中的非终结符,并加进一个新产生式S,以S为开始符号。那么,我们称是G的拓广文法。这样,便会有一个仅含项目S的状态,这就是惟一的“接受”态。如果I是文法G的一个项目集,定义和构造I的闭包CLOSURE(I)如下:(1) I的项目都在CLOSURE(I)中。(2) 若A .B 属于CLOSURE(I),则每一形如B. 的项目也属于CLOSURE(I)。(3) 重复(2)直到CLOSURE(I)不再扩大。 定义转换

9、函数如下:GO(I,X)= CLOSURE(J)其中:I为包含某一项目集的状态,X为一文法符号,J= A X . | A .X I。圆点不在产生式右部最左边的项目称为核,惟一的例外是S.S,因此用GOTO(I,X)状态转换函数得到的J为转向后状态闭包项目集的核。使用闭包函数(CLOSURE)和转换函数(GO(I,X)构造文法G的LR(0)的项目集规族,步骤如下:(1) 置项目S.S为初态集的核,然后对核求闭包CLOSURE(S.S)得到初态的闭包项目集。(2) 对初态集或其他所构造的项目集应用转换函数GO(I,X)= CLOSURE(J)求出新状态J的闭包项目集。(3) 重复(2)直到不出现新

10、的项目集为止。计算LR(0)项目集规族C=I0,I1 , . In 的算法伪代码如下: Procedure itemsets(G); Begin C := CLOSURE (S .S) Repeat For C 中每一项目集I和每一文法符号X Do if GO(I,X) 非空且不属于C Then 把 GO(I,X) 放入C中 Until C 不再增大End;一个项目集可能包含多种项目,若移进和归约项目同时存在,则称移进-归约冲突,若归约和归约项目同时存在,则称归约-归约冲突。三、源程序由正规文法构造正规式#include #include #include using namespace st

11、d;#define MAX_PRO_NUM 50#define MAX_PRO_SET_NUM 20#define MAX_P_NUM 20#define MAX_VT_NUM 27string vn;/非终结符集string vt;/终结符集,包括#struct Project/项目的数据结构 char left; string inputed; string uninputed; bool operator = (Project cmp) if(left = cmp.left & inputed = cmp.inputed & uninputed = cmp.uninputed) retu

12、rn true; else return false; ;struct Go char input; int nextProjectSet;goMAX_PRO_SET_NUMMAX_PRO_NUM;int goLengthMAX_PRO_SET_NUM = 0;/goLengthi是第 i 状态共有多少条箭弧struct PSet/产生式集合char left;/产生式左部 string right;/产生式右部 bool operator =(Project t)/判断项目是否是由该产生式得到的 string temp; if(left != t.left) return false; el

13、se if(t.inputed = null) temp = t.uninputed; else if(t.uninputed = null) temp = t.inputed; else temp = t.inputed + t.uninputed; if(right = temp) return true; return false; pSetMAX_P_NUM;int pSetLength = 0;/产生式个数class ProjectSet;struct DFA/识别活前缀的DFA的项目集集合 ProjectSet* stateMAX_PRO_SET_NUM; int stateLen

14、gth;aDFA;class ProjectSet/项目集private: int projectNum; Project proMAX_PRO_NUM; int proLength; int includeMAX_P_NUM; public: ProjectSet(Project in)/由一个项目构造项目集闭包 projectNum = aDFA.stateLength; proLength = 1; for(int i = 0;i MAX_P_NUM;i+) includei = 0; pro0.left = in.left; pro0.inputed = in.inputed; pro

15、0.uninputed = in.uninputed; for(int j = 0; j = a & vn = z) continue; for(int i = 0; i pSetLength; i+) if(pSeti.left = vn & includei = 0) includei = 1; proproLength.left = pSeti.left; proproLength.inputed = null; proproLength.uninputed = pSeti.right; proLength+; int getProjectNum() return projectNum;

16、 int getProLength() return proLength; Project getPro(int i) return proi; ;string actionTableMAX_PRO_SET_NUM+1MAX_VT_NUM;/ACTION表string gotoTableMAX_PRO_SET_NUM+1MAX_VT_NUM;/GOTO表void input();int getActionIndex(char t);int getGotoIndex(char t);string intToString(int t);void display()/显示LR(0)分析表 coutt

17、ttACTIONttttGOTOendl; coutendl; for(int i = 0;i 0) couti-1t; else coutt; for(unsigned j = 0;j vt.length();j+) coutactionTableijt; for( j = 0;j vn.length();j+) coutgotoTableijt; coutendl; int main() input(); for(int i = 0; i MAX_PRO_SET_NUM; i+) aDFA.statei = NULL; aDFA.stateLength = 0; Project start

18、; start.left = pSet0.left; start.inputed = null; start.uninputed = pSet0.right; aDFA.state0 = new ProjectSet(start); aDFA.stateLength+; int currState = 0;/当前分析的项目集 do for(int i = 0;i getProLength();i+) string temp = aDFA.statecurrState-getPro(i).uninputed; if(temp = null)/归约项目 continue; else gocurrS

19、tategoLengthcurrState.input = temp0;/当前状态currState的第goLengthcurrState条箭弧 受uninputed0激发 gocurrStategoLengthcurrState.nextProjectSet = aDFA.stateLength;/默认到达一个新建的状态 Project aProject,t = aDFA.statecurrState-getPro(i); aProject.left = t.left; if(t.inputed = null) aProject.inputed = t.uninputed0; else aP

20、roject.inputed = t.inputed + t.uninputed0; if(t.uninputed.length() = 1) aProject.uninputed = null; else aProject.uninputed = t.uninputed.substr(1,t.uninputed.length(); bool flag = false; if(aProject = aDFA.statecurrState-getPro(0)/状态到达自身 置一条到达自身的箭弧 gocurrStategoLengthcurrState.nextProjectSet = aDFA.

21、statecurrState-getProjectNum(); goLengthcurrState+; continue; else for(int iter = 0;iter getPro(0)/与其他某一状态吻合 置一跳到达该状态的箭弧 gocurrStategoLengthcurrState.nextProjectSet = iter; goLengthcurrState+; flag = true; break; if(flag = false)/均不满足时新建一个状态 gocurrStategoLengthcurrState.nextProjectSet = aDFA.stateLe

22、ngth; aDFA.stateaDFA.stateLength = new ProjectSet(aProject); aDFA.stateLength+; goLengthcurrState+; currState+; while(currState != aDFA.stateLength); for( i = 0;i vt.length();i+) actionTable0i = vti; for( i = 0;i vn.length();i+) gotoTable0i = vni; /以状态号顺序填表 for( i = 0;i getPro(0); if(t.uninputed = n

23、ull)/是归约项目 if(t.left = Z & t.inputed0 = vn0 & t.inputed.length() = 1)/接受状态 Z-S. actionTablei+1vt.length()-1 = acc; continue; for(int iter = 0;iter getPro(0) for(unsigned k = 0;k vt.length();k+) actionTablei+1k = r + intToString(iter); continue;for(int j = 0;j = a & goij.input = A & goij.input = Z)/非

24、终结符 跳转 int index = getGotoIndex(goij.input); gotoTablei+1index = intToString(goij.nextProjectSet); display(); getchar(); return 0;void input()char line20; char file20; coutfile; getchar(); strcat(file,.txt); ifstream myFile(file); int i = 0;myFile.getline(line,28); vn = line; myFile.getline(line,28)

25、; vt = line;myFile.getline(line,20); while(line0 != 0) pSeti.left = line0; char sub20; int k = 3; while(linek != 0) subk-3 = linek; k+; subk-3 = 0; pSeti.right = string(sub); pSet+i.left = 0; pSetLength+; myFile.getline(line,20); int getActionIndex(char t)/给出一个终结符 返回该终结符在ACTION表中是第几列 for(unsigned i = 0;i vt.length();i+) if(actionTable0i0 = t) return i; return -1;int getGotoIndex(char t)/给出一个非终结符 返回该非终结符在GOTO表中是第几列 for(unsigned i = 0;i vn.length();i+

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1