LL1文法源代码.docx
《LL1文法源代码.docx》由会员分享,可在线阅读,更多相关《LL1文法源代码.docx(20页珍藏版)》请在冰豆网上搜索。
LL1文法源代码
//**************************************************************************************************
//LL
(1)分析法
//编译环境:
g++
//语言:
C++
//**************************************************************************************************
#include
#include
#include
#include
usingnamespacestd;
//**************************************************************************************************
classGrammar
{public:
Grammar();
Grammar(constGrammar&);//复制构造函数 Grammar&operator=(constGrammar&);//赋值函数 friendostream&operator<<(ostream&output,constGrammar&rs)//输出文法 {
output<<"结终符:
"< output<<"非结终符:
"< output<<"文法内容(共"<"< inti=0;
while(i output< }
output<<"*****************************************************************"< output<<"非终结符\t\tFIRST集合\t\tFOLLOW集合"< for(unsignedintj=0;j cout< output<<"*****************************************************************"< output<<"预测分析表:
"< for(unsignedintj=0;j output< for(unsignedintj=0;j {
output< cout< output< }
returnoutput;
}
friendistream&operator>>(istream&input,Grammar&rs)//输入文法 {
unsignedintj=0;
//cout<<"请输入文法:
"<\",每一句一行,最后一行请以'#'开头,'ε'使用'^'表示!
每一行一条文法句。
)"< cout<<"请输入文件名:
";
input>>filename;
ifstreaminfile(filename,ios:
:
in);
if(!
infile){
cout<<"无法打开文件!
"< exit(0);
}
while
(1)
{
unsignedinti=0;
infile>>rs.end;
//input>>rs.end; rs.content[j++]=rs.end;
if(infile.eof())break;
while(i {
if(rs.end[i]=='|'||rs.end[i]=='^');
elseif(i==1||i==2)i++;
elseif(rs.end[i]>='A'&&rs.end[i]<='Z')rs.fei.append(1,rs.end[i]);
elsers.zhong.append(1,rs.end[i]);
i++;
}
}
rs.number=j-1;//记录文法长度 if(rs.Check()==0)
{
system("pause");
exit(0);
}
rs.Checkstr(rs.fei);
rs.Checkstr(rs.zhong);
rs.Checkstr(rs.fei);
rs.Checkstr(rs.zhong);
/* rs.Checkstr(rs.fei);
rs.Checkstr(rs.zhong);
rs.Checkstr(rs.fei);
rs.Checkstr(rs.zhong);
*/ rs.FirstAndFollow();
rs.CreateTable();
returninput;
}
intFindid(char);//在文法中查找某个非终结符 intCheck();//检查文法的正确性 stringCheckstr(string&);//去除字符串中重复字符 stringDelchar(char,string);//去除字符中某个字符 intFindchar(char,string);//查找字符中是否存在某个字符:
可用string:
:
find(...) intStrNum(conststring&);//计算字符串有多少个产生式 charRandChar();//随机产生一个大写字母,为非终结符 stringGetSub(int,conststring&,char);//获取第N个产生式右部 Grammar&DelLeft(int);//消除文法句子的直接左递归 Grammar&DelSL();//消除文法句子的左递归 stringFirst(char);//计算某个非终结符的FIRST集合 stringFirst(conststring&);//计算某个字符串的FIRST集合 stringFollow(char);//计算某个非终结符的FOLLOW集合 Grammar&FirstAndFollow();//存储所有非终符的FIRST集合和FOLLOW集合 Grammar&CreateTable();//建立预测分析表 ~Grammar();
//********************************************************** charPop();//出栈 intNext(char,char);//匹配动作 charTop();//获取分析栈栈顶元素 charIp();//获取输入栈当前元素 Grammar&Push(conststring&);//进栈 intDisplay();//输出分析结果 //**********************************************************
private:
intnumber;//文法长度 stringzhong;//终结符 stringfei;//非终结符 string*content;//文法内容 stringend;//记录输入的最后一行 string*first;//文法的FIRST集合 string*follow;//文法的FOLLOW集合 string**table;//文法的预测分析表 //************** stringstack;//分析栈 stringinstack;//输入栈 //**************};
Grammar:
:
Grammar()
{
//初始化指针 content=newstring[255];
first=newstring[255];
follow=newstring[255];
table=newstring*[255];
//初始化指针完毕}
Grammar:
:
Grammar(constGrammar&rs)//复制构造函数{
zhong=rs.zhong;
fei=rs.fei;
end=rs.end;
number=rs.number;
content=newstring[255];
first=newstring[255];
follow=newstring[255];
table=newstring*[255];
for(inti=0;i<=number;i++)
content[i]=rs.content[i];
FirstAndFollow();
CreateTable();
}
Grammar&Grammar:
:
operator=(constGrammar&rs)//赋值函数{
zhong=rs.zhong;
fei=rs.fei;
end=rs.end;
number=rs.number;
content=newstring[255];
first=newstring[255];
follow=newstring[255];
table=newstring*[255];
for(inti=0;i<=number;i++)
content[i]=rs.content[i];
FirstAndFollow();
CreateTable();
return*this;
}
intGrammar:
:
Findid(chara)//在文法中查找某个非终结符{
inti=0;
while(i {
if(content[i][0]==a)returni;
i++;
}
return-1;
}
charGrammar:
:
RandChar()//随机产生一个大写字母,为非终结符{
switch(rand()%25)
{
case0:
return'A';
case1:
return'B';
case2:
return'C';
case3:
return'D';
case4:
return'E';
case5:
return'F';
case6:
return'G';
case7:
return'H';
case8:
return'I';
case9:
return'J';
case10:
return'K';
case11:
return'L';
case12:
return'M';
case13:
return'N';
case14:
return'O';
case15:
return'P';
case16:
return'Q';
case17:
return'R';
case18:
return'S';
case19:
return'T';
case20:
return'U';
case21:
return'V';
case22:
return'W';
case23:
return'X';
case24:
return'Y';
case25:
return'Z';
}
return'Z';
}
intGrammar:
:
Check()//检查文法的正确性{
unsignedintj=0;
inti=0;
while(j intsig=1;
i=0;
while(i {
if(content[i++][0]==fei[j])
{
sig=1;
break;
}
sig=-1;
}
if(sig==-1)
{
cout<<"非终结符"<"< return0;
}
j++;
}
DelSL();//消除文法左递归 i=0;
while(i {
if(content[i].size()<=3)
{
cout<<"文法句"<"< return0;//文法长度有错 }
if(content[i][1]!
='-'||content[i][2]!
='>')
{
cout<<"文法句"<\"!
"< return0;//未使用推导符"->" }
//验证文法是否有直接左递归 intn=StrNum(content[i]);
ints=0;//记录是否有直接左递归 charz=content[i][0];//获得产生式左部非终结符 intm=0;//记录直接左递归个数 for(intk=1;k<=n;k++)
{
stringtmp=GetSub(k,content[i],'|');
if(z==tmp[0])
{
s=1;
m++;
}
}
if(m==n)
{
cout<<"文法句"<"< return0;//每个产生式都有直接左递归,将为无穷如:
A->Ac|Ab }
if(s==1)//有直接左递归 DelLeft(i);
i++;
}
j=0;
while(j intsig=1;
i=0;
while(i {
if(content[i++][0]==fei[j])
{
sig=1;
break;
}
sig=-1;
}
if(sig==-1)
{
cout<<"非终结符"<"< return0;
}
j++;
}
return1;
}
Grammar&Grammar:
:
DelSL()//消除文法左递归{//课本算法3.2(60页) for(unsignedinti=1;i... intAin=StrNum(Aistr);//获取Ai->...的产生式数 stringAinew;//用于记录更改后的文法句子 Ainew+=Ai;
Ainew+="->";
for(intk=1;k<=Ain;k++)//获取Ai的每个产生式 {
stringAitemp=GetSub(k,Aistr,'|');
stringAit;//用于记录更新后的产生式 if(Aitemp[0]==Aj)//形如Ai->Aj {
stringAjstr=content[j];//获取Aj->... intAjn=StrNum(Ajstr);//获取Aj->...的产生式数 for(intw=1;w<=Ajn;w++)//插入Aj的每一个产生式 {
stringAjtmp=GetSub(w,Ajstr,'|');
stringAitmp=Aitemp;//用于操作 Aitmp.replace(0,1,Ajtmp);//删除第一个字母后再插入Ajtmp字符串形成新串 Ait+=Aitmp;//插入Aj的每一个产生式 Ait+='|';
}
Ait.erase(Ait.size()-1,1);//删除最后一个'|'字符 }
elseAit=Aitemp;
Ainew+=Ait;
Ainew+='|';
}
Ainew.erase(Ainew.size()-1,1);//删除最后一个'|'字符 if(Ainew!
=Aistr)//如果不相同则更新,否则没有必要更新 content[i]=Ainew;//更新 }//endloop