SLR1文法分析实验报告.docx
- 文档编号:25749589
- 上传时间:2023-06-12
- 格式:DOCX
- 页数:34
- 大小:84.35KB
SLR1文法分析实验报告.docx
《SLR1文法分析实验报告.docx》由会员分享,可在线阅读,更多相关《SLR1文法分析实验报告.docx(34页珍藏版)》请在冰豆网上搜索。
SLR1文法分析实验报告
《编译原理》课程设计报告
—SLR
(1)分析的实现
学院计算机科学与技术
专业计算机科学与技术
学号
学生姓名
指导教师姓名
2015年12月26日
1.设计的目的与内容
1.1课程设计的目的
编译原理课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决实际问题的机会。
●进一步巩固和复习编译原理的基础知识。
●培养学生结构化程序、模块化程序设计的方法和能力。
●提高学生对于编程语言原理的理解能力。
●加深学生对于编程语言实现手段的印象。
1.2设计内容
构造LR
(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。
1.3设计要求
1)SLR
(1)分析表的生成可以选择编程序生成,也可选择手动生成;
2)程序要求要配合适当的错误处理机制;
3)要打印句子的文法分析过程。
1.4理论基础
由于大多数适用的程序设计语言的文法不能满足LR(0)文法的条件,即使是描述一个实数变量说明这样简单的文法也不一定是LR(0)文法。
因此对于LR(0)规范族中有冲突的项目集(状态)用向前查看一个符号的办法进行处理,以解决冲突。
这种办法将能满足一些文法的需要,因为只对有冲突的状态才向前查看一个符号,以确定做那种动作,因而称这种分析方法为简单的LR
(1)分析法,用SLR
(1)表示。
2算法的基本思想
2.1主要功能函数
classWF
{
WF(chars1[],chars2[],intx,inty)
WF(conststring&s1,conststring&s2,intx,inty)
booloperator<(constWF&a)const
booloperator==(constWF&a)const
voidprint()
};
classClosure
{
voidprint(stringstr)
booloperator==(constClosure&a)const
};
voidmake_item()
voiddfs(conststring&x)
voidmake_first()
voidappend(conststring&str1,conststring&str2)
bool_check(constvector
voidmake_follow()
voidmake_set()
voidmake_V()
voidmake_cmp(vector
voidmake_go()
voidmake_table()
voidprint(strings1,strings2,strings3,strings4,strings5,strings6,strings7)
stringget_steps(intx)
stringget_stk(vector
stringget_shift(WF&temp)
voidanalyse(stringsrc)
2.2算法思想
SLR文法构造分析表的主要思想:
许多冲突性的动作都可能通过考察有关非终结符的FOLLOW集而获解决。
解决冲突的方法:
解决冲突的方法是分析所有含A和B的句型,考察集合FOLLOW(A)和FOLLOW(B),如果这两个集合不相交,而且也不包含b,那么当状态I面临输入符号a时,我们可以使用如下策略:
若a=b,则移进。
若a∈FOLLOW(A),则用产生式A→α进行归约;
若a∈FOLLOW(B),则用产生式B→α进行归约;
此外,报错*SLR的基本算法:
假定LR(0)规范族的一个项目集I中含有m个移进项目
A1→α•a1β1,A2→α•a2β2,…,Am→α•amβm;
同时含有n个归约项目
B1→α•,B2→α•,…,B3→α•,
如果集合{a1,…,am},FOLLOW(B1),…,FOLLOW(Bn)两两不相交(包括不得有两个FOLLOW集合有#),则隐含在I中的动作冲突可以通过检查现行输入符号a属于上述n+1个集合中的哪个集合而活的解决:
若a是某个ai,i=1,2,…,m,则移进。
若a∈FOLLOW(Bi),i=1,2,…,m,则用产生式Bi→α进行归约;
此外,报错
这种冲突的解决方法叫做SLR
(1)解决办法。
SLR语法分析表的构造方法:
首先把G拓广为G’,对G’构造LR(0)项目集规范族C和活前缀识别自动机的状态转换函数GO。
函数ACTION和GOTO可按如下方法构造:
若项目A→α•bβ属于Ik,GO(Ik,a)=Ij,a为终结符,置ACTION[k,a]为“把状态j和符号a移进栈”,简记为“sj”;
若项目A→α•属于Ik,那么,对任何非终结符a,a∈FOLLOW(A),置ACTION[k,a]为“用产生式A→α进行归约”,简记为“rj”;其中,假定A→α为文法G’的第j个产生式
若项目S’→S•属于Ik,则置ACTION[k,#]为可“接受”,简记为“acc”;
若GO(Ik,A)=Ij,A为非终结符,则置GOTO[k,A]=j;
分析表中凡不能用规则1至4填入信息的空白格均填上“出错标志”。
语法分析器的初始状态是包含S’→•S的项目集合的状态
SLR解决的冲突只是移进-规约冲突和规约-规约冲突
3主要功能模块流程图
3.1主函数功能流程图
图3.1程序主要流程
4系统测试
图4.1输入
图4.2项目表
图4.3FIRST集
图4.4FOLLOW集
图4.5CLOSURE表
图4.6EDGE表
图4.7LR(0)表
图4.8文法分析步骤
5结论
LR分析法是一种自下而上进行规范归约的语法分析方法。
这里L是指从左到右扫描输入符号串。
R是指构造最右推倒的逆工程。
这种分析法比递归下降分析法、预测分析法和算符优先分析法对文法的限制要少得多。
附录程序源码清单
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineMAX507
//#defineDEBUG
usingnamespacestd;
#pragmawarning(disable:
4996)
classWF
{
public:
stringleft,right;
intback;
intid;
WF(chars1[],chars2[],intx,inty)
{
left=s1;
right=s2;
back=x;
id=y;
}
WF(conststring&s1,conststring&s2,intx,inty)
{
left=s1;
right=s2;
back=x;
id=y;
}
booloperator<(constWF&a)const
{
if(left==a.left)
returnright returnleft } booloperator==(constWF&a)const { return(left==a.left)&&(right==a.right); } voidprint() { printf("%s->%s\n",left.c_str(),right.c_str()); } }; classClosure { public: vector voidprint(stringstr) { printf("%-15s%-15s\n","",str.c_str()); for(inti=0;i element[i].print(); } booloperator==(constClosure&a)const { if(a.element.size()! =element.size())returnfalse; for(inti=0;i if(element[i]==a.element[i])continue; elsereturnfalse; returntrue; } }; structContent { inttype; intnum; stringout; Content(){type=-1;} Content(inta,intb) : type(a),num(b){} }; vector map map map stringstart="S"; vector vector charCH='$'; intgo[MAX][MAX]; intto[MAX]; vector boolused[MAX]; Contentaction[MAX][MAX]; intGoto[MAX][MAX]; map map voidmake_item() { memset(to,-1,sizeof(-1)); for(inti=0;i VN_set[wf[i].left].push_back(i); for(inti=0;i for(intj=0;j<=wf[i].right.length();j++) { stringtemp=wf[i].right; temp.insert(temp.begin()+j,CH); dic[wf[i].left].push_back(items.size()); if(j) to[items.size()-1]=items.size(); items.push_back(WF(wf[i].left,temp,i,items.size())); } #ifdefDEBUG puts("-------------------------项目表-------------------------"); for(inti=0;i printf("%s->%sback: %did: %d\n",items[i].left.c_str(),items[i].right.c_str(),items[i].back,items[i].id); puts("--------------------------------------------------------"); #endif } voiddfs(conststring&x) { if(vis[x])return; vis[x]=1; vector for(inti=0;i { string&left=wf[id[i]].left; string&right=wf[id[i]].right; for(intj=0;j if(isupper(right[j])) { dfs(right.substr(j,1)); set set : iteratorit=temp.begin(); boolflag=true; for(;it! =temp.end();it++) { if(*it=='~')flag=false; first[left].insert(*it); } if(flag)break; } else { first[left].insert(right[j]); break; } } } voidmake_first() { vis.clear(); map : iteratorit2=dic.begin(); for(;it2! =dic.end();it2++) if(vis[it2->first])continue; elsedfs(it2->first); #ifdefDEBUG puts("****************FIRST集***************************"); map : iteratorit=first.begin(); for(;it! =first.end();it++) { printf("FIRST(%s)={",it->first.c_str()); set set : iteratorit1=temp.begin(); boolflag=false; for(;it1! =temp.end();it1++) { if(flag)printf(","); printf("%c",*it1); flag=true; } puts("}"); } #endif } voidappend(conststring&str1,conststring&str2) { set set set : iteratorit=from.begin(); for(;it! =from.end();it++) to.insert(*it); } bool_check(constvector { for(inti=0;i { intx=id[i]; if(wf[x].right==str)returntrue; } returnfalse; } voidmake_follow() { while(true) { boolgoon=false; map : iteratorit2=VN_set.begin(); for(;it2! =VN_set.end();it2++) { vector for(inti=0;i { boolflag=true; WF&tt=wf[id[i]]; string&left=tt.left; conststring&right=tt.right; for(intj=right.length()-1;j>=0;j--) if(isupper(right[j])) { if(flag) { inttx=follow[right.substr(j,1)].size(); append(left,right.substr(j,1)); inttx1=follow[right.substr(j,1)].size(); if(tx1>tx)goon=true; if(_check(id,"~")) flag=false; } for(intk=j+1;k if(isupper(right[k])) { stringidd=right.substr(k,1); set set set : iteratorit1=from.begin(); inttx=follow[right.substr(j,1)].size(); for(;it1! =from.end();it1++) if(*it1! ='~') to.insert(*it1); inttx1=follow[right.substr(j,1)].size(); if(tx1>tx)goon=true; if(_check(id,"~")) break; } else { inttx=follow[right.substr(j,1)].size(); follow[right.substr(j,1)].insert(right[k]); inttx1=follow[right.substr(j,1)].size(); if(tx1>tx)goon=true; break; } } elseflag=false; } } if(! goon)break; } #ifdefDEBUG puts("***************FOLLOW集*******************"); map : iteratorit=follow.begin(); for(;it! =follow.end();it++) { printf("FOLLOW(%s)={",it->first.c_str()); set temp.insert('#'); set : iteratorit1=temp.begin(); boolflag=false; for(;it1! =temp.end();it1++) { if(flag)printf(","); printf("%c",*it1); flag=true; } puts("}"); } #endif } voidmake_set() { boolhas[MAX]; for(inti=0;i if(items[i].left[0]=='S'&&items[i].right[0]==CH) { Closuretemp; string&str=items[i].right; vector element.push_back(items[i]); size_tx=0; for(x=0;x if(str[x]==CH) break; memset(has,0,sizeof(has)); has[i]=1; if(x! =str.length()-1) { queue q.push(str.substr(x+1,1)); while(! q.empty()) { stringu=q.front(); q.pop(); vector for(size_tj=0;j { inttx=id[j]; if(items[tx].right[0]==CH) { if(has[tx])continue; has[tx]=1; if(isupper(items[tx].right[1])) q.push(items[tx].right.substr(1,1)); element.push_back(items[tx]); } } } } collection.push_back(temp); } for(size_ti=0;i { map for(size_tj=0;j { stringstr=collection[i].element[j].right; size_tx=0; for(;x if(str[x]==CH)break; if(x==str.length()-1) continue; inty=str[x+1]; intii; str.erase(str.begin()+x); str.inse
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SLR1 文法 分析 实验 报告