天津理工大学编译实验语法分析.docx
- 文档编号:11533098
- 上传时间:2023-03-18
- 格式:DOCX
- 页数:22
- 大小:64.67KB
天津理工大学编译实验语法分析.docx
《天津理工大学编译实验语法分析.docx》由会员分享,可在线阅读,更多相关《天津理工大学编译实验语法分析.docx(22页珍藏版)》请在冰豆网上搜索。
天津理工大学编译实验语法分析
实验报告
学院(系)名称:
计算机与通信工程学院
姓名
*****
学号
*****
专业
计算机科学与技术
班级
2011级*班
实验项目
实验二:
语法分析
课程名称
编译原理
课程代码
0668056
实验时间
2014年4月18日第5、8节
2011年4月25日第7、8节
实验地点
计算机软件实验室7-215
批改意见
成绩
教师签字:
实验内容:
可选择LL1分析法、算符优先分析法、LR分析法之一,实现如下表达式文法的语法分析器:
(1)E→E+T|E-T|T
(2)T→T*F|T/F|F
(3)F→P^F|P
(4)P→(E)|i
实验目的:
1.掌握语法分析的基本概念和基本方法;
2.正确理解LL1分析法、算符优先分析法、LR分析法的设计与使用方法。
实验要求:
1.按要求设计实现能识别上述文法所表示语言的语法分析器,并要求输出全部分析过程;
2.要求详细描述所选分析方法针对上述文法的分析表构造过程;
3.完成对所设计语法分析器的功能测试,并给出测试数据和实验结果;
4.为增加程序可读性,请在程序中进行适当注释说明;
5.整理上机步骤,总结经验和体会;
6.认真完成并按时提交实验报告。
【实验过程记录(源程序、测试用例、测试结果及心得体会等)】
#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;
else
return0;
}
intIsLetter(charch)//判断是不是大写字母(非终结符)
{
if(ch>='A'&&ch<='Z')
return1;
else
return0;
}
//judge1判断是否是算符文法
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;
}
else
j++;
}
if(flag==1)//根据flag设定返回值
return0;
else
return1;
}
//judge2是判断文法G是否为算符优先文法
voidjudge2(intn)
{
for(inti=0;i<=n;i++)
if(str[i][3]=='~'||FLAG==1)//'~'代表空
{
cout<<"文法G不是算符优先文法!
"< FF=0; break; } if(i>n) cout<<"文法G是算符优先文法! "< } //search1是查看存放终结符的数组r中是否含有重复的终结符 intsearch1(charr[],intkk,chara) { for(inti=0;i if(r[i]==a) break; if(i==kk) return0; else return1; } //createF函数是用F数组存放每个终结符与非终结符和组合 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;i for(intj=0;j { F[m].R=t[i]; F[m].r=r[j]; F[m].flag=0; m++; } } //search函数是将在F数组中寻找到的终结符与非终结符对的标志位值为1 voidsearch(charLodew) { for(inti=0;i if(F[i].R==w.E&&F[i].r==w.e) { F[i].flag=1;break; } } voidFirstVT(intn)//求FirstVT { 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&&i i++; 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)//求LastVT { charstacksta; charLodew; for(inti=0;i F[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&&i i++; 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))//优先及等于的情况,用1值表示等于 { 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)) //优先及小于的情况,用2值表示小于 { 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)) //优先及大于的情况,用3值表示大于 { 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++; } } } } } //judge3是用来返回在归约过程中两个非终结符相比较的值 intjudge3(chars,chara) { inti=1,j=1; while(ccrr2[i][0]! =s) i++; while(ccrr1[0][j]! =a) j++; if(crr[i][j]==3) return3; else if(crr[i][j]==2) return2; else if(crr[i][j]==1) return1; else return0; } 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<<"出错"< break; } } if(s[0]=='#'&&s[1]=='N'&&s[2]=='#') cout<<"归约成功"< elsecout<<"归约失败"< } voidmain() { intn,i,j; cout<<"输入定义的文法G的产生式的个数n: "; cin>>n; cout<<"输入文法产生式: "< 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]='#'; cout<<"你定义的产生式如下: "< str[i][6]='\0'; 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); 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<<"="; elseif(crr[i][j]==2) cout<<"<"; elseif(crr[i][j]==3) cout<<">"; cout<<""; } cout< } judge2(n);//判断文法G是否为算符优先文法 if(FF==1) { charSTR[1][20]; cout<<"请输入要规约的字符串: "< gets(STR[0]); intii=strlen(STR[0]); STR[0][ii]='#'; cout<<"语法分析过程如下: "< process(STR,ii); } } 你定义的文法产生式如下: 算符优先分析表如下: 语法分析过程如下:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 天津 理工大学 编译 实验 语法分析