编译原理语法分析器算符优先文法分析器.docx
- 文档编号:10804009
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:22
- 大小:83.56KB
编译原理语法分析器算符优先文法分析器.docx
《编译原理语法分析器算符优先文法分析器.docx》由会员分享,可在线阅读,更多相关《编译原理语法分析器算符优先文法分析器.docx(22页珍藏版)》请在冰豆网上搜索。
编译原理语法分析器算符优先文法分析器
编译原理实验报告
实验名称:
编写语法分析分析器
实验类型:
验证型实验
指导教师:
何中胜
专业班级:
12软件一
姓名:
学号:
电子邮件:
实验地点:
秋白楼B720
实验成绩:
日期:
2015年6月25日
一、实验目的
通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
1、选择最有代表性的语法分析方法,如LL
(1)语法分析程序、算符优先分析程序和LR分析分析程序,至少选一题。
2、选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
二、实验过程
编写算符优先分析器。
要求:
(a)根据算符优先分析算法,编写一个分析对象的语法分析程序。
读者可根据自己的能力选择以下三项(由易到难)之一作为分析算法中的输入:
Ⅰ:
通过构造算符优先关系表,设计编制并调试一个算法优先分析程序
Ⅱ:
输入FIRSTVT,LASTVT集合,由程序自动生成该文法的算符优先关系矩阵。
Ⅲ:
输入已知文法,由程序自动生成该文法的算符优先关系矩阵。
(b)程序具有通用性,即所编制的语法分析程序能够使用于不同文法以及各种输入单词串,并能判断该文法是否为算符文法和算符优先文法。
(c)有运行实例。
对于输入的一个文法和一个单词串,所编制的语法分析程序应能正确地判断,此单词串是否为该文法的句子,并要求输出分析过程。
三、实验结果
算符优先分析器:
测试数据:
E->E+T|T
T->T*F|F
F->(E)|i
实验结果:
(输入串为i+i*i+i)
四、讨论与分析
自下而上分析技术-算符优先分析法:
算符文法:
一个上下无关文法G,如果没有且没有P→..QR...(P,Q,R属于非终结符),则G是一个算符文法。
FIRSTVT集构造
1、若有产生式P→a...或P→Qa...,则a∈FIRSTVT(P)。
2、若有产生式P→...,则FIRSTVT(R)包含在FIRSTVT(P)中。
由优先性低于的定义和firstVT集合的定义可以得出:
若存在某个产生式:
…P…,则对所有:
b∈firstVT(P)都有:
a≦b。
构造优先关系表:
1、如果每个非终结符的FIRSTVT和LASTVT集均已知,则可构造优先关系表。
2、若产生式右部有...aP...的形式,则对于每个b∈FIRSTVT(P)都有a≦b(优先集);
3、若产生式右部有...Pb的形式,则对于每个a∈LASTVT(P)集,都有a≧b;
4、若产生是形如:
A→…ab…或A→…aBb…形式,则有a≒b。
5、#与其他终结符的优先关系可利用拓广文法S‟à#S#来获得。
五、附录(全部代码):
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"iostream.h"
intanalyze();//对输入串的分析
intisTerminator(charc);//判断字符c是否是终结符
intgetIndex(charc);//求字符c在算符优先关系表中的下标
voidprintS(intj,intk,char*s);//打印s栈
voidfirstvt(charc);//求非终结符c的first集
voidlastvt(charc);//求非终结符c的LASTVT集
voidrelationTable();//创建文法优先关系表
chardata[10][10];//算符优先关系
chars[50];//模拟符号栈s
charlable[30];//文法终极符集
charinput[50];//文法输入符号串
charstring[20][10];//用于输入串的分析
intk,j,r=0,r1;
chara,q;
charst[10][30];//用来存储文法规则
charfirst[10][10];//文法非终结符first集
charlast[10][10];//文法非终结符LASTVT集
intfflag[10]={0};//标志第i个非终结符的first集是否已求出
intlflag[10]={0};//标志第i个非终结符的LASTVT集是否已求出
intmain()
{
inti=0,j,k=0;
printf("请输入文法规则(以#结束)\n");
while
(1)
{
scanf("%s",st[i++]);//存储文法规则,初始化first集和LASTVT集*/
if(strcmp(st[i-1],"#")==0)
{
r=i-1;
break;
}
first[i][0]=0;/*first[i][0]和last[i][0]分别表示st[i][0]非终极
符的first集和LASTVT集中元素的个数*/
last[i][0]=0;
}
for(i=0;i { for(j=0;st[i][j]! ='\0';j++) { if(st[i][0]<'A'||st[i][0]>'Z') { printf("不是算符文法! \n"); exit(-1); } if(st[i][j]>='A'&&st[i][j]<='Z') { if(st[i][j+1]>='A'&&st[i][j+1]<='Z') { printf("不是算符文法! \n"); exit(-1); } } } } for(i=0;i { for(j=0;st[i][j]! ='\0';j++) { if((st[i][j]<'A'||st[i][j]>'Z')&&st[i][j]! ='-'&&st[i][j]! ='>'&&st[i][j]! ='|') lable[k++]=st[i][j]; } } lable[k]='#'; lable[k+1]='\0'; relationTable(); printf("每个非终结符的FIRSTVT集为: \n");//输出每个非终结符的first集 for(i=0;i { printf("%c: ",st[i][0]); for(j=0;j { printf("%c",first[i][j+1]); } printf("\n"); } printf("每个非终结符的LASTVT集为: \n");//输出每个非终结符的LASTVT集 for(i=0;i { printf("%c: ",st[i][0]); for(j=0;j { printf("%c",last[i][j+1]); } printf("\n"); } printf("算符优先分析表如下: \n"); for(i=0;lable[i]! ='\0';i++) printf("\t%c",lable[i]); printf("\n"); for(i=0;i { printf("%c\t",lable[i]); for(j=0;j { printf("%c\t",data[i][j]); } printf("\n"); } printf("请输入文法输入符号串: "); scanf("%s",input); analyze(); } voidrelationTable() { chartext[20][10]; inti,j,k,t,l,x=0,y=0; intm,n; x=0; for(i=0;i { firstvt(st[i][0]); lastvt(st[i][0]); } for(i=0;i { text[x][y]=st[i][0]; y++; for(j=1;st[i][j]! ='\0';j++) { if(st[i][j]=='|') { text[x][y]='\0'; x++; y=0; text[x][y]=st[i][0]; y++; text[x][y++]='-'; text[x][y++]='>'; } else { text[x][y]=st[i][j]; y++; } } text[x][y]='\0'; x++; y=0; } r1=x; printf("转化后的文法为: \n"); for(i=0;i { printf("%s\n",text[i]); } for(i=0;i 后的转化文法,用于最后的规约)*/ { string[i][0]=text[i][0]; for(j=3,l=1;text[i][j]! ='\0';j++,l++) string[i][l]=text[i][j]; string[i][l]='\0'; } for(i=0;i { for(j=1;text[i][j+1]! ='\0';j++) { if(isTerminator(text[i][j])&&isTerminator(text[i][j+1])) { m=getIndex(text[i][j]); n=getIndex(text[i][j+1]); data[m][n]='='; } if(text[i][j+2]! ='\0'&&isTerminator(text[i][j])&&isTerminator(text[i][j+2])&&! isTerminator(text[i][j+1])) {//(终结符非终结符终结符)情形 m=getIndex(text[i][j]); n=getIndex(text[i][j+2]); data[m][n]='='; } if(isTerminator(text[i][j])&&! isTerminator(text[i][j+1]))//(终结符a非终结符A)a { for(k=0;k { if(st[k][0]==text[i][j+1]) break; } m=getIndex(text[i][j]); for(t=0;t { n=getIndex(first[k][t+1]); data[m][n]='<'; } } if(! isTerminator(text[i][j])&&isTerminator(text[i][j+1]))//(非终结符A终结符a)LASTVT(A)>a { for(k=0;k { if(st[k][0]==text[i][j]) break; } n=getIndex(text[i][j+1]); for(t=0;t { m=getIndex(last[k][t+1]); data[m][n]='>'; } } } } m=getIndex('#'); for(t=0;t { n=getIndex(first[0][t+1]); data[m][n]='<'; } n=getIndex('#'); for(t=0;t { m=getIndex(last[0][t+1]); data[m][n]='>'; } data[n][n]='='; } voidfirstvt(charc)//求first集 { inti,j,k,m,n; for(i=0;i { if(st[i][0]==c) break; } if(fflag[i]==0) { n=first[i][0]+1; m=0; do { if(m==2||st[i][m]=='|')//P->a...则a属于first(P) { if(isTerminator(st[i][m+1])) { first[i][n]=st[i][m+1]; n++; } else { if(isTerminator(st[i][m+2]))//或P->Qa....则a属于first(P) { first[i][n]=st[i][m+2]; n++; } if(st[i][m+1]! =c)//如a属于first(Q)且P->Q则a属于first(P) { firstvt(st[i][m+1]); for(j=0;j { if(st[j][0]==st[i][m+1]) break; } for(k=0;k { intt; for(t=0;t { if(first[i][t]==first[j][k+1]) break; } if(t==n) { first[i][n]=first[j][k+1]; n++; } } } } } m++; }while(st[i][m]! ='\0'); first[i][n]='\0'; first[i][0]=--n; fflag[i]=1; } } voidlastvt(charc)//求LASTVT集 { inti,j,k,m,n; for(i=0;i { if(st[i][0]==c) break; } if(lflag[i]==0) { n=last[i][0]+1; m=0; do { if(st[i][m+1]=='\0'||st[i][m+1]=='|')//P->.....a则a属于LASTVT(P) { if(isTerminator(st[i][m])) { last[i][n]=st[i][m]; n++; } else { if(isTerminator(st[i][m-1]))//或P->....aQ则a属于LASTVT(P) { last[i][n]=st[i][m-1]; n++; } if(st[i][m]! =c)//如a属于LASTVT(Q)且P->Q则a属于LASTVT(P) { lastvt(st[i][m]); for(j=0;j { if(st[j][0]==st[i][m]) break; } for(k=0;k { intt; for(t=0;t { if(last[i][t]==last[j][k+1]) break; } if(t==n) { last[i][n]=last[j][k+1]; n++; } } } } } m++; }while(st[i][m]! ='\0'); last[i][n]='\0'; last[i][0]=--n; lflag[i]=1; } } intanalyze() { inti,j; intx,y; intz;//输入串的长度 k=1; s[k]='#';//栈置初值 for(i=0;input[i]! ='\0';i++);//计算输入串的长度 z=i--; i=0; while((a=input[i])! ='\0') { if(isTerminator(s[k])) j=k; else j=k-1; x=getIndex(s[j]); y=getIndex(a); if(data[x][y]=='>') { printS(1,k,s); printf("%c",a); printS(i+1,z,input); printf("规约\n"); do { q=s[j]; if(isTerminator(s[j-1])) j=j-1; elsej=j-2; x=getIndex(s[j]); y=getIndex(q); }while(data[x][y]! ='<'); intm,n,N; for(m=j+1;m<=k;m++) { for(N=0;N for(n=1;string[N][n]! ='\0';n++) { if(! isTerminator(s[m])&&! isTerminator(string[N][n])) { if(isTerminator(s[m+1])&&isTerminator(string[N][n+1])&&s[m+1]==string[N][n+1]) { s[j+1]=string[N][0]; break; } } else if(isTerminator(s[m])) if(s[m]==string[N][n]) { s[j+1]=string[N][0]; break; } } } k=j+1; if(k==2&&a=='#') { printS(1,k,s); printf("%c",a); printS(i+1,z,input); printf("结束\n"); printf("输入串符合文法的定义! \n"); return1;//输入串符合文法的定义 } } else if(data[x][y]=='<'||data[x][y]=='=') {//移进 printS(1,k,s); printf("%c",a); printS(i+1,z,input); printf("移进\n"); k++; s[k]=a; i++; } else { printf("\nflase\n"); return0; } } printf("\nflase\n"); return0; } voidprintS(intj,intk,char*s) { intn=0; inti; for(i=j;i<=k;i++) { printf("%c",s[i]); n++; } for(;n<15;n++) { printf(""); } } intgetIndex(charc)//求字符c在算符优先关系表中的下标 { inti; for(i=0;lable[i]! ='\0';i++) { if(c==lable[i]) returni; } return-1; } intisTerminator(charc)//判断字符c是否是终极符 { inti; for(i=0;lable[i]! ='\0';i++) { if(c==lable[i]) return1; } return0; } 六、实验者自评(主要从实验态度、方法、效果上给一个客观公正的自我评价) 这次实验编写了两个词法分析方法的程序,但是在LL (1)分析器的编写中我只达到了最低要求,就是自己手动输入的select集,first集,follow集然后通过程序将预测分析表构造出来了,并且没有做出对输入串的分析。 在算符优先分析的程序里,从对文法的分析以及firstvt集和lastvt集的求出,算符优先分析表,输入串的分析都是通过程序实现的,虽然过程比较困难,也花了很久才弄懂这个程序。 通过本次试验,我能够设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。 还能选择最有代表性的语法分析方法,如LL (1)语法分析程序、算符优先分析程序和LR分析分析程序。 并且有能力选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 语法 分析器 优先 文法