编译原理实验报告LL1分析法Word文档下载推荐.docx
《编译原理实验报告LL1分析法Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告LL1分析法Word文档下载推荐.docx(17页珍藏版)》请在冰豆网上搜索。
二.实验过程及结果
代码如下:
#include<
iostream>
#include"
edge.h"
usingnamespacestd;
edge:
:
edge()
{
cin>
>
left>
right;
rlen=right.length();
if(NODE.find(left)>
NODE.length())
NODE+=left;
}
stringedge:
getlf()
returnleft;
getrg()
returnright;
getfirst()
returnfirst;
getfollow()
returnfollow;
getselect()
returnselect;
getro()
stringstr;
str+=right[0];
returnstr;
intedge:
getrlen()
returnright.length();
voidedge:
newfirst(stringw)
inti;
for(i=0;
i<
w.length();
i++)
if(first.find(w[i])>
first.length())
first+=w[i];
newfollow(stringw)
if(follow.find(w[i])>
follow.length()&
&
w[i]!
='
@'
)
follow+=w[i];
newselect(stringw)
if(select.find(w[i])>
select.length()&
select+=w[i];
delfirst()
inti=first.find('
);
first.erase(i,1);
intSUM;
stringNODE,ENODE;
//计算first
voidfirst(edgeni,edge*n,intx)
inti,j;
for(j=0;
j<
SUM;
j++)
{
if(ni.getlf()==n[j].getlf())
{
if(NODE.find(n[j].getro())<
{
for(i=0;
if(n[i].getlf()==n[j].getro())
first(n[i],n,x);
}
else
n[x].newfirst(n[j].getro());
}
}
//计算follow
voidfollow(edgeni,edge*n,intx)
inti,j,k,s;
ni.getrlen();
s=NODE.find(ni.getrg()[i]);
if(s<
NODE.length()&
s>
-1)//是非终结符
if(i<
ni.getrlen()-1)//不在最右
for(j=0;
if(n[j].getlf().find(ni.getrg()[i])==0)
if(NODE.find(ni.getrg()[i+1])<
for(k=0;
k<
k++)
if(n[k].getlf().find(ni.getrg()[i+1])==0)
{
n[j].newfollow(n[k].getfirst());
if(n[k].getfirst().find("
@"
)<
n[k].getfirst().length())
n[j].newfollow(ni.getfollow());
}
str.erase();
str+=ni.getrg()[i+1];
n[j].newfollow(str);
}
//计算select
voidselect(edge&
ni,edge*n)
if(ENODE.find(ni.getro())<
ENODE.length())
ni.newselect(ni.getro());
if(ni.getro()=="
ni.newselect(ni.getfollow());
else
if(ni.getrg()[i]==n[j].getlf()[0])
ni.newselect(n[j].getfirst());
if(n[j].getfirst().find('
)>
n[j].getfirst().length())
return;
//输出集合
voidout(stringp)
if(p.length()==0)
return;
cout<
<
"
{"
;
p.length()-1;
p[i]<
"
}"
//连续输出符号
voidoutfu(inta,stringc)
a;
c;
//输出预测分析表
voidoutgraph(edge*n,string(*yc)[50])
inti,j,k;
boolflag;
ENODE.length();
if(ENODE[i]!
outfu(10,"
"
cout<
ENODE[i];
outfu(10,"
#"
endl;
intx;
NODE.length();
outfu(4,"
cout<
NODE[i];
outfu(5,"
for(k=0;
flag=1;
for(j=0;
if(NODE[i]==n[j].getlf()[0])
x=n[j].getselect().find(ENODE[k]);
if(x<
n[j].getselect().length()&
x>
-1)
{
cout<
->
n[j].getrg();
yc[i][k]=n[j].getrg();
outfu(9-n[j].getrlen(),"
flag=0;
}
x=n[j].getselect().find('
#'
if(k==ENODE.length()-1&
x<
yc[i][j]=n[j].getrg();
if(flag&
ENODE[k]!
outfu(11,"
//分析符号串
intpipei(string&
chuan,string&
fenxi,string(*yc)[50],int&
b)
charch,a;
intx,i,j,k;
b++;
endl<
b;
if(b>
9)
outfu(8,"
outfu(9,"
fenxi;
outfu(26-chuan.length()-fenxi.length(),"
chuan;
a=chuan[0];
ch=fenxi[fenxi.length()-1];
x=ENODE.find(ch);
if(x<
ENODE.length()&
if(ch==a)
fenxi.erase(fenxi.length()-1,1);
chuan.erase(0,1);
'
a<
匹配"
if(pipei(chuan,fenxi,yc,b))
return1;
return0;
if(ch=='
if(ch==a)
分析成功"
else
if(ch=='
i=NODE.find(ch);
if(a=='
x=ENODE.find('
if(x<
j=ENODE.length()-1;
j=ENODE.length();
j=ENODE.find(a);
if(yc[i][j].length())
NODE[i]<
yc[i][j];
for(k=yc[i][j].length()-1;
k>
-1;
k--)
if(yc[i][j][k]!
fenxi+=yc[i][j][k];
voidmain()
edge*n;
stringstr,(*yc)[50];
boolflag=0;
请输入上下文无关文法的总规则数:
请输入具体规则(格式:
左部右部,@为空):
n=newedge[SUM];
n[i].getrlen();
str=n[i].getrg();
if(NODE.find(str[j])>
ENODE.find(str[j])>
ENODE+=str[j];
//计算first集合
first(n[i],n,i);
//outfu(10,"
~*~"
cout<
if(n[i].getfirst().find("
n[i].getfirst().length())
if(NODE.find(n[i].getro())<
for(k=1;
if(NODE.find(n[i].getrg()[k])<
for(j=0;
{
if(n[i].getrg()[k]==n[j].getlf()[0])
{
n[i].newfirst(n[j].getfirst());
break;
}
}
if(n[j].getfirst().find("
n[i].delfirst();
break;
}
//计算follow集合
for(k=0;
if(n[i].getlf()==n[0].getlf())
n[i].newfollow("
follow(n[i],n,i);
if(n[j].getrg().find(n[i].getlf())==n[j].getrlen()-1)
n[i].newfollow(n[j].getfollow());
//计算select集合
select(n[i],n);
str.erase();
if(n[j].getlf()[0]==NODE[i])
if(!
str.length())
str=n[j].getselect();
n[j].getselect().length();
if(str.find(n[j].getselect()[k])<
flag=1;
break;
//输出
非终结符"
outfu(SUM,"
First"
Follow"
outfu(5+SUM,"
-*-"
if(NODE[i]==n[j].getlf()[0])
outfu(3,"
outfu(SUM+4,"
out(n[j].getfirst());
outfu(SUM+4-2*n[j].getfirst().length(),"
out(n[j].getfollow());
break;
判定结论:
if(flag)
该文法不是LL
(1)文法!
该文法是LL
(1)文法!
//输出预测分析表
预测分析表如下:
yc=newstring[NODE.length()][50];
outgraph(n,yc);
stringchuan,fenxi,fchuan;
请输入符号串:
fchuan=chuan;
fenxi="
fenxi+=NODE[0];
i=0;
预测分析过程如下:
步骤"
outfu(7,"
分析栈"
剩余输入串"
推导所用产生式或匹配"
if(pipei(chuan,fenxi,yc,i))
输入串"
fchuan<
是该文法的句子!
不是该文法的句子!
截屏如下:
三.实验中的问题及心得
这次实验让我更加熟悉了LL
(1)的工作流程以及LL
(1)分析表的构造方法。
以前课堂上搞不懂的算法流程通过实验都能得到进一步的了解。