LL1预测分析法实验报告文档格式.doc
《LL1预测分析法实验报告文档格式.doc》由会员分享,可在线阅读,更多相关《LL1预测分析法实验报告文档格式.doc(19页珍藏版)》请在冰豆网上搜索。
(3)LR方法能分析的文法类是预测分析法能分析的文法类的真超集。
(4)LR分析器能及时察觉语法错误,快到自左向右扫描输入的最大可能。
为了使一个文法是LR的,只要保证当句柄出现在栈顶时,自左向右扫描的移进-归约分析器能够及时识别它便足够了。
当句柄出现在栈顶时,LR分析器必须要扫描整个栈就可以知道这一点,栈顶的状态符号包含了所需要的一切信息。
如果仅知道栈内的文法符号就能确定栈顶是什么句柄。
LR分析表的转移函数本质上就是这样的有限自动机。
不过,这个有限自动机不需要根据每步动作读栈,因为,如果这个识别句柄的有限自动机自底向上读栈中的文法符号的话,它达到的状态正是这时栈顶的状态符号所表示的状态,所以,LR分析器可以从栈顶的状态确定它需要从栈中了解的一切。
2、LR分析器由三个部分组成:
(1)总控程序,也可以称为驱动程序。
对所有的LR分析器总控程序都是相同的。
(2)分析表或分析函数,不同的文法分析表将不同,同一个文法采用的LR分析器不同时,分析表将不同,分析表又可以分为动作表(ACTION)和状态转换(GOTO)表两个部分,它们都可用二维数组表示。
(3)分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。
分析器的动作就是由栈顶状态和当前输入符号所决定。
四、程序源代码:
//edge.h
#ifndefHEAD_EDGE
#defineHEAD_EDGE
#include<
string>
usingnamespacestd;
externintSUM;
externstringNODE,ENODE;
classedge
{
public:
edge();
stringgetlf();
stringgetrg();
stringgetfirst();
stringgetfollow();
stringgetselect();
stringgetro();
intgetrlen();
voidnewfirst(stringw);
voidnewfollow(stringw);
voidnewselect(stringw);
voiddelfirst();
private:
stringleft,right,first,follow,select;
intrlen;
};
#endif
/////////////////////////////////////////////////////////////////////////////
//edge.cpp
iostream>
#include"
edge.h"
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);
//LL1.cpp
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());
}
}
else
{
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
for(i=0;
for(j=0;
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;
cout<
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,"
NODE[i];
outfu(5,"
for(k=0;
{
flag=1;
if(NODE[i]==n[j].getlf()[0])
x=n[j].getselect().find(ENODE[k]);