编译原理 LL1文法源代码.docx
- 文档编号:4566509
- 上传时间:2022-12-06
- 格式:DOCX
- 页数:14
- 大小:18.02KB
编译原理 LL1文法源代码.docx
《编译原理 LL1文法源代码.docx》由会员分享,可在线阅读,更多相关《编译原理 LL1文法源代码.docx(14页珍藏版)》请在冰豆网上搜索。
编译原理LL1文法源代码
LL
(1)文法(源代码)
#include"stdio.h"
#include"stdlib.h"
#defineMaxRuleNum8
#defineMaxVnNum5
#defineMaxVtNum5
#defineMaxStackDepth20
#defineMaxPLength20
#defineMaxStLength50
structpRNode/*产生式右部结构*/{intrCursor;
structpRNode*next;
};
structpNode{intlCursor;
intrLength;/*右部长度*/
structpRNode*rHead;/*右部结点头指针*/
};
charVn[MaxVnNum+1];/*非终结符集*/
intvnNum;
charVt[MaxVtNum+1];/*终结符集*/
intvtNum;
structpNodeP[MaxRuleNum];
intPNum;
charbuffer[MaxPLength+1];
charch;
charst[MaxStLength];/*要分析的符号串*/
structcollectNode{intnVt;
structcollectNode*next;
};
structcollectNode*first[MaxVnNum+1];/*first集*/
structcollectNode*follow[MaxVnNum+1];/*follow集*/
intanalyseTable[MaxVnNum+1][MaxVtNum+1+1];
intanalyseStack[MaxStackDepth+1];/*分析栈*/
inttopAnalyse;/*分析栈顶*/
voidInit();/*初始化*/
intIndexCh(charch);
voidInputVt();/*输入终结符*/
voidInputVn();/*输入非终结符*/
voidShowChArray(char*collect,intnum);/*输出Vn或Vt的内容*/
voidInputP();/*产生式输入*/
boolCheckP(char*st);/*判断产生式正确性*/
voidFirst(intU);
voidAddFirst(intU,intnCh);/*加入first集*/
boolHaveEmpty(intnVn);
voidFollow(intV);/*计算follow集*/
voidAddFollow(intV,intnCh,intkind);
voidShowCollect(structcollectNode**collect);/*输出first或follow集*/
voidFirstFollow();/*计算first和follow*/
voidCreateAT();/*构造预测分析表*/
voidShowAT();/*输出分析表*/
voidIdentify(char*st);
voidInitStack();
voidShowStack();
voidPop();
voidPush(intr);
voidmain(void){chartodo,ch;
Init();
InputVn();
InputVt();
InputP();
getchar();
FirstFollow();
printf("所得first集为:
");
ShowCollect(first);
printf("所得follow集为:
");
ShowCollect(follow);
CreateAT();
ShowAT();
todo='y';
while('y'==todo){printf("\n是否继续进行句型分析?
(y/n):
");
todo=getchar();
while('y'!
=todo&&'n'!
=todo){printf("\n(y/n)?
");
todo=getchar();}if('y'==todo){inti;
InitStack();
printf("请输入符号串(以#结束):
");
ch=getchar();
i=0;
while('#'!
=ch&&i =ch&&'\n'! =ch){st[i++]=ch;}ch=getchar();}if('#'==ch&&i Identify(st);}else printf("输入出错! \n");}} getchar();}voidInit(){inti,j; vnNum=0; vtNum=0; PNum=0; for(i=0;i<=MaxVnNum;i++) Vn[i]='\0'; for(i=0;i<=MaxVtNum;i++) Vt[i]='\0'; for(i=0;i P[i].rHead=NULL; P[i].rLength=0;}PNum=0; for(i=0;i<=MaxPLength;i++) buffer[i]='\0'; for(i=0;i follow[i]=NULL;}for(i=0;i<=MaxVnNum;i++){for(j=0;j<=MaxVnNum+1;j++) analyseTable[i][j]=-1;}} intIndexCh(charch){intn; n=0;/*isVn? */ while(ch! =Vn[n]&&'\0'! =Vn[n]) n++; if('\0'! =Vn[n]) return100+n; n=0;/*isVt? */ while(ch! =Vt[n]&&'\0'! =Vt[n]) n++; if('\0'! =Vt[n]) returnn; return-1;}/*输出Vn或Vt的内容*/ voidShowChArray(char*collect){intk=0; while('\0'! =collect[k]){printf("%c",collect[k++]);}printf("\n");}/*输入非终结符*/ voidInputVn(){intinErr=1; intn,k; charch; while(inErr){printf("\n请输入所有的非终结符,注意: "); printf("请将开始符放在第一位,并以#号结束: \n"); ch=''; n=0; /*初始化数组*/ while(n while(('#'! =ch)&&(n =ch&&'\n'! =ch&&-1==IndexCh(ch)){Vn[n++]=ch; vnNum++;}ch=getchar();}Vn[n]='#';/*以“#”标志结束用于判断长度是否合法*/ k=n; if('#'! =ch){if('#'! =(ch=getchar())){while('#'! =(ch=getchar()));printf("\n符号数目超过限制! \n"); inErr=1; continue;}} /*正确性确认,正确则,执行下下面,否则重新输入*/ Vn[k]='\0'; ShowChArray(Vn); ch=''; while('y'! =ch&&'n'! =ch){if('\n'! =ch){printf("输入正确确认? (y/n): ");}scanf("%c",&ch);}if('n'==ch){printf("录入错误重新输入! \n"); inErr=1;}else{inErr=0;}}}/*输入终结符*/ voidInputVt(){intinErr=1; intn,k; charch; while(inErr){printf("\n请输入所有的终结符,注意: "); printf("以#号结束: \n"); ch=''; n=0; /*初始化数组*/ while(n while(('#'! =ch)&&(n =ch&&'\n'! =ch&&-1==IndexCh(ch)){Vt[n++]=ch; vtNum++;}ch=getchar();}Vt[n]='#'; k=n; if('#'! =ch){if('#'! =(ch=getchar())){while('#'! =(ch=getchar()));printf("\n符号数目超过限制! \n"); inErr=1; continue;}} Vt[k]='\0'; ShowChArray(Vt); ch=''; while('y'! =ch&&'n'! =ch){if('\n'! =ch){printf("输入正确确认? (y/n): ");}scanf("%c",&ch);}if('n'==ch){printf("录入错误重新输入! \n"); inErr=1;}else{inErr=0;}}}/*产生式输入*/ voidInputP(){charch; inti=0,n,num; printf("请输入文法产生式的个数: "); scanf("%d",&num); PNum=num; getchar();/*消除回车符*/ printf("\n请输入文法的%d个产生式,并以回车分隔每个产生式: ",num); printf("\n"); while(i ",i); /*初始化*/ for(n=0;n buffer[n]='\0'; /*输入产生式串*/ ch=''; n=0; while('\n'! =(ch=getchar())&&n =ch) buffer[n++]=ch;}buffer[n]='\0'; if(CheckP(buffer)){pRNode*pt,*qt; P[i].lCursor=IndexCh(buffer[0]); pt=(pRNode*)malloc(sizeof(pRNode)); pt->rCursor=IndexCh(buffer[3]); pt->next=NULL; P[i].rHead=pt; n=4; while('\0'! =buffer[n]){qt=(pRNode*)malloc(sizeof(pRNode)); qt->rCursor=IndexCh(buffer[n]); qt->next=NULL; pt->next=qt; pt=qt; n++;}P[i].rLength=n-3; i++;}else printf("输入符号含非法在成分,请重新输入! \n");}} /*判断产生式正确性*/ boolCheckP(char*st){intn; if(100>IndexCh(st[0])) returnfalse; if('-'! =st[1]) returnfalse; if('>'! =st[2]) returnfalse; for(n=3;'\0'! =st[n];n++){if(-1==IndexCh(st[n])) returnfalse;}returntrue;}voidFirst(intU){inti,j; for(i=0;i pt=P[i].rHead; j=0; while(j pt->rCursor){AddFirst(U,pt->rCursor); break;}else{if(NULL==first[pt->rCursor-100]){First(pt->rCursor);}AddFirst(U,pt->rCursor); if(! HaveEmpty(pt->rCursor)){break;}else{pt=pt->next;}} j++;}if(j>=P[i].rLength)/*当产生式右部都能推出空时*/ AddFirst(U,-1);}}}/*加入first集*/ voidAddFirst(intU,intnCh){structcollectNode*pt,*qt; intch;/*用于处理Vn*/ pt=NULL; qt=NULL; if(nCh<100){pt=first[U-100]; while(NULL! =pt){if(pt->nVt==nCh) break; else{qt=pt; pt=pt->next;}} if(NULL==pt){pt=(structcollectNode*)malloc(sizeof(structcollectNode)); pt->nVt=nCh; pt->next=NULL; if(NULL==first[U-100]){first[U-100]=pt;}else{qt->next=pt;/*qt指向first集的最后一个元素*/}pt=pt->next;}} else{pt=first[nCh-100]; while(NULL! =pt){ch=pt->nVt; if(-1! =ch){AddFirst(U,ch);}pt=pt->next;}}}boolHaveEmpty(intnVn){if(nVn<100) returnfalse; structcollectNode*pt; pt=first[nVn-100]; while(NULL! =pt){if(-1==pt->nVt) returntrue; pt=pt->next;}returnfalse;}voidFollow(intV){inti; structpRNode*pt; if(100==V)/*当为初始符时*/ AddFollow(V,-1,0); for(i=0;i while(NULL! =pt&&pt->rCursor! =V) pt=pt->next; if(NULL! =pt){pt=pt->next; if(NULL==pt){if(NULL==follow[P[i].lCursor-100]&&P[i].lCursor! =V){Follow(P[i].lCursor);}AddFollow(V,P[i].lCursor,0);}else{while(NULL! =pt&&HaveEmpty(pt->rCursor)){AddFollow(V,pt->rCursor,1); pt=pt->next;}if(NULL==pt){if(NULL==follow[P[i].lCursor-100]&&P[i].lCursor! =V){Follow(P[i].lCursor);}AddFollow(V,P[i].lCursor,0);}else{AddFollow(V,pt->rCursor,1);}}}}}voidAddFollow(intV,intnCh,intkind){structcollectNode*pt,*qt; intch; pt=NULL; qt=NULL; if(nCh<100)/*为终结符时*/{pt=follow[V-100]; while(NULL! =pt){if(pt->nVt==nCh) break; else{qt=pt; pt=pt->next;}} if(NULL==pt){pt=(structcollectNode*)malloc(sizeof(structcollectNode)); pt->nVt=nCh; pt->next=NULL; if(NULL==follow[V-100]){follow[V-100]=pt;}else{qt->next=pt;/*qt指向follow集的最后一个元素*/}pt=pt->next;}} else{if(0==kind){pt=follow[nCh-100]; while(NULL! =pt){ch=pt->nVt; AddFollow(V,ch,0); pt=pt->next;}} else{pt=first[nCh-100]; while(NULL! =pt){ch=pt->nVt; if(-1! =ch){AddFollow(V,ch,1);}pt=pt->next;}}}} /*输出first或follow集*/ voidShowCollect(structcollectNode**collect){inti; structcollectNode*pt; i=0; while(NULL! =collect[i]){pt=collect[i]; printf("\n%c: \t",Vn[i]); while(NULL! =pt){if(-1! =pt->nVt){printf("%c",Vt[pt->nVt]);}else printf("#"); pt=pt->next;}i++;}printf("\n");}/*计算first和follow*/ voidFirstFollow(){inti; i=0; while('\0'! =Vn[i]){if(NULL==first[i]) First(100+i); i++;}i=0; while('\0'! =Vn[i]){if(NULL==follow[i]) Follow(100+i); i++;}} /*构造预测分析表*/ voidCreateAT(){inti; structpRNode*pt; structcollectNode*ct; for(i=0;i while(NULL! =pt&&HaveEmpty(pt->rCursor)){ct=first[pt->rCursor-100]; while(NULL! =ct){if(-1! =ct->nVt) analyseTable[P[i].lCursor-100][ct->nVt]=i; ct=ct->next;}pt=pt->next;}if(NULL==pt){ct=follow[P[i].lCursor-100]; while(NULL! =ct){if(-1! =ct->nVt) analyseTable[P[i].lCursor-100][ct->nVt]=i; else analyseTable[P[i].lCursor-100][vtNum]=i; ct=ct->next;}} else{if(100<=pt->rCursor)/*不含空的非终结符*/{ct=first[pt->rCursor-100]; while(NULL! =ct){analyseTable[P[i].lCursor-100][ct->nVt]=i; ct=ct->next;}} else/*终结符或者空*/{if(-1==pt->rCursor){ct=follow[P[i].lCursor-100]; while(NULL! =ct){if(-1! =ct->nVt) analyseTable[P[i].lCursor-100][ct->nVt]=i; else/*当含有#号时*/ analyseTable[P[i].lCursor-100][vtNum]=i; ct=ct->next;}} else/*为终结符*/{analyseTable[P[i].lCursor-100][pt->rCursor]=i;}}}}}/*输出分析表*/ voidShowAT(){inti,j; printf("构造预测分析表如下: \n"); printf("\t|\t"); for(i=0;i printf("---\t|---\t"); for(i=0;i<=vtNum;i++) printf("---\t"); printf("\n"); for(i=0;i for(j=0;j<=vtNum;j++){if(-1! =analyseTable[i][j]) printf("R(%d)\t",analyseTable[i][j]); else printf("error\t");}printf("\n");}} voidIdentify(char*st){intcurrent,step,r;/*r表使用的产生式的序号*/ printf("\n%s的分析过程: \n",st); printf("步骤\t分析符号栈\t当前指示字符\t使用产生式序号\n");
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理 LL1文法源代码 编译 原理 LL1 文法 源代码
![提示](https://static.bdocx.com/images/bang_tan.gif)