语法分析器编译报告.docx
- 文档编号:23344455
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:29
- 大小:114.12KB
语法分析器编译报告.docx
《语法分析器编译报告.docx》由会员分享,可在线阅读,更多相关《语法分析器编译报告.docx(29页珍藏版)》请在冰豆网上搜索。
语法分析器编译报告
西安郵電大學
课内实验报告书2
院系名称
:
实验题目
:
语法分析器
学生姓名
:
专业名称
:
班级
:
学号
:
时间
:
一实验目的:
结合课堂上学习的理论知识,通过C语言实现语法分析器,更加深入的掌握语法分析;同时也可以更加了解语法分析的原理。
二、实验要求:
1、试编写一个程序,用来判定给定的文法是否为简单优先文法(或算符优先文法)。
(一)对于如下的文法,试编写调试一个语法分析程序:
<程序>→PROGRAM<标识符>;<分程序>
<分程序>→<变量说明>BEGIN<语句表>END.
<变量说明>→VAR<变量说明表>;
<变量说明表>→<变量表>:
<类型>|<变量表>:
<类型>;<变量说明表>
<类型>→INTEGER|REAL
<变量表>→<变量>|<变量>,<变量表>
<语句表>→<语句>|<语句>;<语句表>
<语句>→<赋值语句>|<条件语句>|
<赋值语句>→<变量>:
=<算术表达式>
<条件语句>→IF<关系表达式>THEN<语句>ELSE<语句>
<复合语句>→BEGIN<语句表>END
<算术表达式>→<项>|<算术表达式>+<项>|<算术表达式>-<项>
<项>→<因式>|<项>*<因式>|<项>/<因式>
<因式>→<变量>|<常数>|(<算术表达式>)
<关系表达式>→<算术表达式><关系符><算术表达式>
<变量>→<标识符>
<标识符>→<标识符><字母>|<标识符><数学>|<字母>
<常数>→<整数>|<浮点数>
<整数>→<数字>|<数字><整数>
<浮点数>→·<整数>|<整数>·<整数>
<关系符>→=|<|<=|>|>=|<>
<字母>→A|B|C|···|X|Y|Z
<数字>→0|1|2|···|8|9
<空>→
三、实验内容
试编写一个程序,用来判定给定的文法是否为简单优先文法(或算符优先文法)。
提示:
·
<
·
=
·
>
(1)确定文法的机内表示方法;
B
B
B
分别编写计算布尔矩阵的程序,为此,还需要编写一个计算布尔矩阵B的闭包B+的子程序,供计算上述各布尔矩阵时调用;
(2)编制判定优先矩阵是否有多重定义元素的程序,用来判断所给文法是否为简单优先(算符优先)文法;
(3)要求输出各优先关系的布尔矩阵以及有关判定结果的信息。
(4)用来计算给定文法的全部FIRST集及FOLLOW集,并判定所给文法是否为LL
(1)文法。
要求:
(5)以给定的文法作为输入(为此,需确定文法的机内表示);
程序的输出是各FIRST及FOLLOW集,以及所给文法是否为LL
(1)文法等信息。
四、采用的数据结构
采用了队列和堆栈。
五、算法描述
六、运行结果
七、调试情况
一开始实验很生疏,很难把理论知识融
不明确输入输出;通过多次调试和反复修改才完成了这次实验要求;
八、设计技巧与体会
通过这次实验我对语法分析器有了进一步的了解,把理论知识应用于实验中。
在编写程序过程中也遇到了很多困难,不过最终通过自己细心检查得到了解决,为以后编程积累了些小知识;
九、源程序清单
#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数组存放每个终结符与非终结符和组合,并且值每队的标志位为0;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是否为算符优先文
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语法 分析器 编译 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)