编译课程.docx
《编译课程.docx》由会员分享,可在线阅读,更多相关《编译课程.docx(23页珍藏版)》请在冰豆网上搜索。
编译课程
课程设计
(2010-2011学年度第二学期)
课程名称编译原理
设计题目语法分析——规约
专业:
计算机
姓名:
蒋小荣
学号:
20084440205
班级:
计算机082
教师:
陈星
地点:
8栋实验室
一、设计目的
通过设计、编制、调试一个具体的语法分析程序,加深对语法分析原理的理解,加深对语法及语义分析原理的理解,并实现对文法的判断,是算符优先文法的对其进行FirstVT集及LastVT集的分析,并对输入的字符串进行规约输出规约结果成功或失败。
二、设计内容及步骤
内容:
在C++6.0中编写程序代码实现语法分析功能,调试得到相应文法的判断结果:
是算符优先或不是。
若是,则输出各非终结符的FirstVT与LastVT集的结果,还可进行字符串的规约,输出详细的规约步骤,程序自动判别规约成功与失败。
步骤:
1.看书,找资料,了解语法分析器的工作过程与原理
2.分析题目,列出基本的设计思路
定义栈,进栈,出栈函数
栈为空时的处理
构造函数判断文法是否是算符文法,算符优先文法
构造FirstVT和LastVT函数对文法的非终结符进行分析
是算符优先文法时,构造函数对其可以进行输入待规约串,输出规约结果
构造主函数,对过程进行分析
3.上机实践编码,将设计的思路转换成C++语言编码,编译运行
4.测试,输入不同的文法,观察运行结果
三、详细的算法描述
详细设计伪代码如下:
首先要声明变量,然后定义各个函数
1.voidInitstack(charstack&s)
{//定义栈
s.base=newcharLode[20];
s.top=-1;}
2.voidpush(charstack&s,charLodew)
{//字符进栈
s.top++;
s.base[s.top].E=w.E;
s.base[s.top].e=w.e;
}
3.voidpop(charstack&s,charLode&w)
{//字符出栈
w.E=s.base[s.top].E;
w.e=s.base[s.top].e;
s.top--;
}
4.intIsEmpty(charstacks)
{//判断栈是否为空
if(s.top==-1)
return1;
elsereturn0;
}
5.intIsLetter(charch)
{//判断是否为非终结符
if(ch>='A'&&ch<='Z')
return1;
elsereturn0;
}
6.intjudge1(intn)
{//judge1是判断是否是算符文法:
若产生式中含有两个相继的非终结符则不是算符文法
}
7.voidjudge2(intn)
{//judge2是判断文法G是否为算符优先文法:
若不是算符文法或若文法中含空字或终结符的优先级不唯一则不是算符优先文法
8.intsearch1(charr[],intkk,chara)
{//search1是查看存放终结符的数组r中是否含有重复的终结符}
9.voidcreateF(intn)
{//createF函数是用F数组存放每个终结符与非终结符和组合,并且值每队的标志位为0;F数组是一个结构体}
10.voidsearch(charLodew)
{//search函数是将在F数组中寻找到的终结符与非终结符对的标志位值为1}
分情况讨论:
//产生式的后选式的第一个字符就是终结符的情况
//产生式的后选式的第一个字符是非终结符的情况
11.voidLastVT(intn)
{//求LastVT
}
12.voidFirstVT(intn)
{//求FirstVT
}
13.voidcreateYXB(intn)
{//构造优先表
分情况讨论:
//优先级等于的情况,用1值表示等于}
//优先级小于的情况,用2值表示小于
//优先级大于的情况,用3值表示大于
}
14.intjudge3(chars,chara)
{//judge3是用来返回在归约过程中两个非终结符相比较的值
}
15.voidprint(chars[],charSTR[][20],intq,intu,intii,intk)
{//打印归约的过程}
16.voidprocess(charSTR[][20],intii)
{//对输入的字符串进行归约的过程
}
四、设计结果
分两大类,四种不同的情况
第一类情况:
产生式的候选式以终结符开始候选式以终结符开始经过存在递归式的非终结符后再以终结符结束
第二类情况:
产生式的候选式是两个或以上的非终结符
五、设计总结与心得
通过对语法分析的实践操作,对它在实践中的应用有了更深刻的理解,通过上机实践,提高了从错误中分析问题,解决问题的能力。
在实践的基础上,把所学的知识得到了实际应用,通过本次的编译原理课程设计,让我对用C++编程的大致思路又进行了一次回顾,设计一个可运行的程序代码的思路规范,声明变量,定义各大需要调用的函数及其调用。
在这个实验的过程中,如何运用栈,指针来达到判断是否是算符优先文法的规约的目的,当然其中也设计了多个供调用的函数,声明了多个变量,锻炼了思维逻辑能力,同时在和同学的探讨下锻炼了我的发现问题分析问题的能力。
六、程序完整代码
#include
#include
#include
typedefstruct
{
charR;
charr;
intflag;
}array;
typedefstruct
{
charE;
chare;
}charLode;
typedefstruct
{
charLode*base;
inttop;
}charstack;
charstr[80][80],arr[80][80],brr[80][80];
arrayF[20];
intm,kk,p,ppp,FF=1;
charr[10];
intcrr[20][20],FLAG=0;
charccrr1[1][20],ccrr2[20][1];
voidInitstack(charstack&s){
s.base=newcharLode[20];
s.top=-1;
}
voidpush(charstack&s,charLodew)
{
s.top++;
s.base[s.top].E=w.E;
s.base[s.top].e=w.e;
}
voidpop(charstack&s,charLode&w)
{
w.E=s.base[s.top].E;
w.e=s.base[s.top].e;
s.top--;
}
intIsEmpty(charstacks)
{
if(s.top==-1)
return1;
elsereturn0;
}
intIsLetter(charch)
{
if(ch>='A'&&ch<='Z')
return1;
elsereturn0;
}
intjudge1(intn)
{
intj=3,flag=0;
for(inti=0;i<=n;i++)
while(str[i][j]!
='\0')
{
chara=str[i][j];
charb=str[i][j+1];
if(IsLetter(a)&&IsLetter(b))
{flag=1;break;}
elsej++;
}
if(flag==1)
return0;
else
return1;
}
voidjudge2(intn)
{
for(inti=0;i<=n;i++)
if(str[i][3]=='~'||judge1(n)==0||FLAG==1)//'~'代表空字
{cout<<"文法G不是算符优先文法!
"<if(i>n)
cout<<"文法G是算符优先文法!
"<}
intsearch1(charr[],intkk,chara)
{
for(inti=0;iif(r[i]==a)
break;
if(i==kk)return0;
elsereturn1;
}
voidcreateF(intn)
{
intk=0,i=1;charg;
chart[10];//t数组用来存放非终结符
t[0]=str[0][0];
while(i<=n)
{
if(t[k]!
=str[i][0])
{k++;t[k]=str[i][0];g=t[k];i++;}
elsei++;
}
kk=0;
charc;
for(i=0;i<=n;i++)
{intj=3;
while(str[i][j]!
='\0')
{
c=str[i][j];
if(IsLetter(c)==0)
{
if(!
search1(r,kk,c))
r[kk]=c;kk++;//r数组用来存放终结符
}
j++;
}
}
m=0;
for(i=0;ifor(intj=0;j{
F[m].R=t[i];
F[m].r=r[j];
F[m].flag=0;
m++;
}
}
voidsearch(charLodew)
{
for(inti=0;iif(F[i].R==w.E&&F[i].r==w.e)
{F[i].flag=1;break;}
}
voidFirstVT(intn){
charstacksta;
charLodew;
inti=0;
Initstack(sta);
while(i<=n)
{
intk=3;
w.E=str[i][0];
chara=str[i][k];
charb=str[i][k+1];
if(!
IsLetter(a)){
w.e=a;
push(sta,w);
search(w);
i++;
}
elseif(IsLetter(a)&&b!
='\0'&&!
IsLetter(b)){
w.e=b;
push(sta,w);
search(w);
i++;
}
elsei++;
}
charLodeww;
while(!
IsEmpty(sta))
{
pop(sta,ww);
for(i=0;i<=n;i++)
{
w.E=str[i][0];
if(str[i][3]==ww.E&&str[i][4]=='\0')
{
w.e=ww.e;
push(sta,w);
search(w);
break;
}
}
}
p=0;intk=1;i=1;
while(i{
if(F[i-1].flag==1)
{
arr[p][0]=F[i-1].R;
arr[p][k]=F[i-1].r;
}
while(F[i].flag==0&&ii++;
if(F[i].flag==1)
{
if(F[i].R==arr[p][0])
k++;
else{arr[p][k+1]='\0';p++;k=1;}
i++;
}
}
}
voidLastVT(intn){
charstacksta;
charLodew;
for(inti=0;iF[i].flag=0;
i=0;
Initstack(sta);
while(i<=n)
{
intk=strlen(str[i]);
w.E=str[i][0];
chara=str[i][k-1];
charb=str[i][k-2];
if(!
IsLetter(a))
{
w.e=a;
push(sta,w);
search(w);
i++;
}
elseif(IsLetter(a)&&!
IsLetter(b))
{
w.e=b;
push(sta,w);
search(w);
i++;
}
elsei++;
}
charLodeee;
while(!
IsEmpty(sta))
{
pop(sta,ee);
for(i=0;i<=n;i++)
{
w.E=str[i][0];
if(str[i][3]==ee.E&&str[i][4]=='\0')
{
w.e=ee.e;
push(sta,w);
search(w);
}
}
}
intk=1;i=1;
ppp=0;
while(i{
if(F[i-1].flag==1)
{
brr[ppp][0]=F[i-1].R;
brr[ppp][k]=F[i-1].r;
}
while(F[i].flag==0&&ii++;
if(F[i].flag==1)
{
if(F[i].R==arr[ppp][0])
k++;
else{brr[ppp][k+1]='\0';ppp++;k=1;}
i++;
}
}
}
voidcreateYXB(intn)
{
inti,j;
for(j=1;j<=kk;j++)
ccrr1[0][j]=r[j-1];
for(i=1;i<=kk;i++)
ccrr2[i][0]=r[i-1];
for(i=1;i<=kk;i++)
for(j=1;j<=kk;j++)
crr[i][j]=0;
intI=0,J=3;
while(I<=n)
{
if(str[I][J+1]=='\0')
{I++;J=3;}
else
{
while(str[I][J+1]!
='\0')
{
charaa=str[I][J];
charbb=str[I][J+1];
if(!
IsLetter(aa)&&!
IsLetter(bb))
{
for(i=1;i<=kk;i++)
{
if(ccrr2[i][0]==aa)
break;
}
for(j=1;j<=kk;j++)
{
if(ccrr1[0][j]==bb)
break;
}
if(crr[i][j]==0)
crr[i][j]=1;
else{FLAG=1;I=n+1;}
J++;
}
if(!
IsLetter(aa)&&IsLetter(bb)&&str[I][J+2]!
='\0'&&!
IsLetter(str[I][J+2])){
for(i=1;i<=kk;i++)
{
if(ccrr2[i][0]==aa)
break;
}
for(intj=1;j<=kk;j++)
{if(ccrr1[0][j]==str[I][J+2])
break;
}
if(crr[i][j]==0)
crr[i][j]=1;
else{FLAG=1;I=n+1;}
}
if(!
IsLetter(aa)&&IsLetter(bb)){
for(i=1;i<=kk;i++)
{if(aa==ccrr2[i][0])
break;
}
for(j=0;j<=p;j++)
{if(bb==arr[j][0])
break;
}
for(intmm=1;arr[j][mm]!
='\0';mm++)
{
for(intpp=1;pp<=kk;pp++)
{
if(ccrr1[0][pp]==arr[j][mm])
break;
}
if(crr[i][pp]==0)
crr[i][pp]=2;
else{FLAG=1;I=n+1;}
}
J++;
}
if(IsLetter(aa)&&!
IsLetter(bb))
{
for(i=1;i<=kk;i++)
{
if(ccrr1[0][i]==bb)
break;
}
for(j=0;j<=ppp;j++)
{
if(aa==brr[j][0])
break;
}
for(intmm=1;brr[j][mm]!
='\0';mm++)
{
for(intpp=1;pp<=kk;pp++)
{
if(ccrr2[pp][0]==brr[j][mm])
break;
}
if(crr[pp][i]==0)
crr[pp][i]=3;
else{FLAG=1;I=n+1;}
}
J++;
}
}
}
}
}
intjudge3(chars,chara)
{
inti=1,j=1;
while(ccrr2[i][0]!
=s)
i++;
j++;
if(crr[i][j]==3)return3;
while(ccrr1[0][j]!
=a)
elseif(crr[i][j]==2)
return2;
elseif(crr[i][j]==1)
return1;
elsereturn0;
}
voidprint(chars[],charSTR[][20],intq,intu,intii,intk){
cout<
for(inti=0;i<=k;i++)
cout<
cout<<"";
for(i=q;i<=ii;i++)
cout<cout<<"";
}
voidprocess(charSTR[][20],intii)//对输入的字符串进行归约的过程
{
cout<<"步骤"<<""<<"符号栈"<<""<<"输入串"<<""<<"动作"<intk=0,q=0,u=0,b,i,j;
chars[40],a;
s[k]='#';
print(s,STR,q,u,ii,k);
cout<<"预备"<k++;u++;
s[k]=STR[0][q];
q++;
print(s,STR,q,u,ii,k);
cout<<"移进"<while(q<=ii)
{
a=STR[0][q];
if(!
IsLetter(s[k]))j=k;
elsej=k-1;
b=judge3(s[j],a);
if(b==3)//大于的情况进行归约
{
while(IsLetter(s[j-1]))
j--;
for(i=j;i<=k;i++)
s[i]='\0';
k=j;s[k]='N';u++;
print(s,STR,q,u,ii,k);
cout<<"归约"<}
elseif(b==2||b==1)//小于或等于的情况移进
{
k++;
s[k]=a;
u++;
q++;
print(s,STR,q,u,ii,k);
if(s[0]=='#'&&s[1]=='N'&&s[2]=='#')
cout<<"接受"<elsecout<<"移进"<}
else
{cout<<"出错"<}
if(s[0]=='#'&&s[1]=='N'&&s[2]=='#')
cout<<"归约成功"<elsecout<<"归约失败"<}
voidmain()
{
intn,i,j;
cout<<"请输入你要定义的文法G的产生式的个数n:
";
cin>>n;
for(i=0;i{
gets(str[i]);
j=strlen(str[i]);
str[i][j]='\0';
}
str[i][0]='Q';
str[i][1]='-';
str[i][2]='>';
str[i][3]='#';
str[i][4]=str[0][0];
str[i][5]='#';
str[i][6]='\0';
cout<<"你定义的产生式如下:
"<for(i=0;i<=n;i++)
cout<if(judge1(n)==0)//判断文法G是否为算符文法
cout<<"文法G不是算符文法!
"<if(judge1(n)==1)
{
cout<<"文法G是算符文法!
"<createF(n);
FirstVT(n);
LastVT(n);
createYXB(n);
}
judge2(n);//判断文法G是否为算符优先文法
if(FLAG==0)
{
for(i=0;i<=p;i++)//打印FirstVT
{
cout<<"FirstVT("<for(intl=1;arr[i][l+1]!
='\0';l++)
cout<cout<}
cout<<"FirstVT(Q)={#}"<for(i=0;i<=ppp;i++)//打印LastVT
{
cout<<"LastVT("<for(intl=1;brr[i][l+1]!
='\0';l++)
cout<cout<}
cout<<"LastVT(Q)={#}"<cout<<"优先表如下:
"<for(i=1;i{
cout<<"";
cout<}
cout<for(i=1;i{
cout<for(j=1;j{
if(crr[i][j]==0)
cout<<"";
elseif(crr[i][j]==1)
cout