




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验一词法分析器设计【实验目的】1.熟悉词法分析的基本原理,词法分析的过程以及词法分析中要注意的问题。2.复习高级语言,进一步加强用高级语言来解决实际问题的能力。3.通过完成词法分析程序,了解词法分析的过程。【实验内容】(编写)用C语言编写一个PL/0词法分析器,为语法语义分析提供单词,使之能把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析,并把分析结果(基本字,运算符,标识符,常数以及界符)输出。【实验步骤和要求】要求绘出词法分析过程的流程图。根据词法分析的目的以及内容,确定完成分析过程所需模块。写出每个模块的源代码。整理程序清单及所得结果。源代码:intIsword(chargetword[])//判断是否为关键字{ for(inti=0;i<13;i++) { if(strcmp(word[i],getword)==0) return1; } return0;}intIsoperator(charch)//判断是否为单字符符号{ inti=0; for(i;i<11;i++) if(ch==symbols[i]) returni; return-1;}voidWrite(chars1[],chars2[]){ FILE*fp; if((fp=fopen("PL0词法分析.txt","a+"))==NULL) { printf("无法打开文件!!\n"); exit(-1); } fprintf(fp,"%-30s\t",s1); fprintf(fp,"%10s\n",s2); fclose(fp);}voidWriteNum(inta,chars2[]){ FILE*fp; if((fp=fopen("PL0词法分析.txt","a+"))==NULL) { printf("无法打开文件!!\n"); exit(-1); } fprintf(fp,"%-30d\t",a); fprintf(fp,"%10s\n",s2); fclose(fp);}voidWriteChar(charch,chars2[]){ FILE*fp; if((fp=fopen("PL0词法分析.txt","a+"))==NULL) { printf("无法打开文件!!\n"); exit(-1); } fprintf(fp,"%-30c\t",ch); fprintf(fp,"%10s\n",s2); fclose(fp);}intAnalysis(void)//词法分析{ chargetword[NameMax],ch; inti,flag=0,num; FILE*fp; if((fp=fopen("PL0程序.txt","r"))==NULL) { printf("无法打开PL0程序.txt!!\n"); exit(-1); } do { ch=fgetc(fp);if(ch>='a'&&ch<='z')//读取的是字母,先判断是否为关键字 { for(i=0;(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9')&&i<NameMax;i++) { if(i<NameMax) { getword[i]=ch; ch=fgetc(fp); } elseif(i=NameMax) {printf("数据长度超出范围\n"); flag=-1; break; } } if(flag!=-1) { getword[i]=0; if(Isword(getword)==1) Write(getword,"关键字"); else Write(getword,"标识符"); } } else { if(ch>='0'&&ch<='9')//判断是否数字打头 { intk=0; num=0; do { num=10*num+ch-'0'; k++; ch=fgetc(fp); } while(ch>='0'&&ch<='9'); k--; if(k>NumMax) { printf("数据长度超出范围\n"); } else { WriteNum(num,"常数"); } } else {if(ch==':')//判断赋值符号 { ch=fgetc(fp); if(ch=='=') { Write(":=","运算符"); } else { printf("不能识别的符号"); } } else { if(ch=='<')//判断小于等于 { ch=fgetc(fp); if(ch=='=') { Write("<=","运算符"); } else { printf("不能识别的符号"); } } else { if(ch=='>')//判断大于等于 { ch=fgetc(fp); if(ch=='=') { Write(">=","运算符"); } else { printf("不能识别的符号"); } } else { if(Isoperator(ch)>-1&&Isoperator(ch)<5) { WriteChar(ch,"运算符"); } else { if(Isoperator(ch)>=5) { WriteChar(ch,"界符"); } } } } } } }} while(ch!=EOF); fclose(fp); returnflag;}voidmain(void){ FILE*fp; chars1[30],s2[10],ch; Analysis();printf("\n词法分析如下:\n"); printf("-----------------------------------------------------\n"); if((fp=fopen("PL0词法分析.txt","r"))==NULL) { printf("无法打开文件!!\n"); exit(-1); } do { fscanf(fp,"%s",s1); fscanf(fp,"%s",s2); printf("%-30s\t",s1);printf("%10s\n",s2); s1[0]=0; s2[0]=0; } while((ch=fgetc(fp))!=EOF);}运行结果:实验二LL(1)语法分析程序设计【实验目的】1.熟悉判断LL(1)文法的方法及对某一输入串的分析过程。2.学会构造表达式文法的预测分析表。【实验内容】(改写)编写一个语法分析程序,对于给定的输入串,能够判断识别该串是否为给定文法的句型。【实验步骤和要求】从键盘读入输入串,并判断正误;若无误,由程序自动构造FIRST、FOLLOW集以及SELECT集合,判断是否为LL(1)文法;若符合LL(1)文法,由程序自动构造LL(1)分析表;由算法判断输入符号串是否为该文法的句型。(可参考教材96页的例题1)源代码: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<MaxRuleNum;i++){P[i].lCursor=NULL;P[i].rHead=NULL;P[i].rLength=0;}PNum=0;for(i=0;i<=MaxPLength;i++)buffer[i]='\0';for(i=0;i<MaxVnNum;i++){first[i]=NULL;follow[i]=NULL;}for(i=0;i<=MaxVnNum;i++){for(j=0;j<=MaxVnNum+1;j++)analyseTable[i][j]=-1;}}/*返回Vn在Vn表中的位置+100、Vt在Vt表中的位置,-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<MaxVnNum){Vn[n++]='\0';}n=0;while(('#'!=ch)&&(n<MaxVnNum)){if(''!=ch&&'\n'!=ch&&-1==IndexCh(ch)){Vn[n++]=ch;vnNum++;}ch=getchar();}Vn[n]='#';/*以"#"标志结束用于判断长度是否合法*/k=n;/*k用于记录n以便改Vn[n]='\0'*/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<MaxVtNum){Vt[n++]='\0';}n=0;while(('#'!=ch)&&(n<MaxVtNum)){if(''!=ch&&'\n'!=ch&&-1==IndexCh(ch)){Vt[n++]=ch;vtNum++;}ch=getchar();}Vt[n]='#';/*以"#"标志结束*/k=n;/*k用于记录n以便改Vt[n]='\0'*/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<num){printf("第%d个:",i);/*初始化*/for(n=0;n<MaxPLength;n++)buffer[n]='\0';/*输入产生式串*/ch='';n=0;while('\n'!=(ch=getchar())&&n<MaxPLength){if(''!=ch)buffer[n++]=ch;}buffer[n]='\0';/*printf("%s",buffer);*/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++;/*调试时使用*/}elseprintf("输入符号含非法在成分,请重新输入!\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;}/*====================first&follow======================*//*计算first集,U->xx...*/voidFirst(intU){inti,j;for(i=0;i<PNum;i++){if(P[i].lCursor==U){structpRNode*pt;pt=P[i].rHead;j=0;while(j<P[i].rLength){if(100>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)/*当数值小于100时nCh为Vt*//*当处理非终结符时,AddFirst不添加空项(-1)*/{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;}}}/*判断first集中是否有空(-1)*/boolHaveEmpty(intnVn){if(nVn<100)/*为终结符时(含-1),在follow集中用到*/returnfalse;structcollectNode*pt;pt=first[nVn-100];while(NULL!=pt){if(-1==pt->nVt)returntrue;pt=pt->next;}returnfalse;}/*计算follow集,例:U->xVy,U->xV.(注:初始符必含#--"-1")*/voidFollow(intV){inti;structpRNode*pt;if(100==V)/*当为初始符时*/AddFollow(V,-1,0);for(i=0;i<PNum;i++){pt=P[i].rHead;while(NULL!=pt&&pt->rCursor!=V)/*注此不能处理:U->xVyVz的情况*/pt=pt->next;if(NULL!=pt){pt=pt->next;/*V右侧的符号*/if(NULL==pt)/*当V后为空时V->xV,将左符的follow集并入V的follow集中*/{if(NULL==follow[P[i].lCursor-100]&&P[i].lCursor!=V){Follow(P[i].lCursor);}AddFollow(V,P[i].lCursor,0);}else/*不为空时V->xVy,(注意:y->),调用AddFollow加入Vt或y的first集*/{while(NULL!=pt&&HaveEmpty(pt->rCursor)){AddFollow(V,pt->rCursor,1);/*y的前缀中有空时,加如first集*/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);}}}}}/*当数值小于100时nCh为Vt*//*#用-1表示,kind用于区分是并入符号的first集,还是follow集kind=0表加入follow集,kind=1加入first集*/voidAddFollow(intV,intnCh,intkind){structcollectNode*pt,*qt;intch;/*用于处理Vn*/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/*为非终结符时,要区分是加first还是follow*/{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]);}elseprintf("#");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++;}}/*=================构造预测分析表,例:U::xyz=============*/voidCreateAT(){inti;structpRNode*pt;structcollectNode*ct;for(i=0;i<PNum;i++){pt=P[i].rHead;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){/*NULL==pt,说明xyz->,用到follow中的符号*/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)/*-1为空产生式时*/{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<vtNum;i++){printf("%c\t",Vt[i]);}printf("#\t\n");printf("---\t|---\t");for(i=0;i<=vtNum;i++)printf("---\t");printf("\n");for(i=0;i<vnNum;i++){printf("%c\t|\t",Vn[i]);for(j=0;j<=vtNum;j++){if(-1!=analyseTable[i][j])printf("R(%d)\t",analyseTable[i][j]);elseprintf("\t");}printf("\n");}}/*=================主控程序=====================*/voidIdentify(char*st){intcurrent,step,r;/*r表使用的产生式的序号*/printf("\n%s的分析过程:\n",st);printf("步骤\t分析符号栈\t当前指示字符\t使用产生式序号\n");step=0;current=0;/*符号串指示器*/printf("%d\t",step);ShowStack();printf("\t\t%c\t\t--\n",st[current]);while('#'!=st[current]){if(100>analyseStack[topAnalyse])/*当为终结符时*/{if(analyseStack[topAnalyse]==IndexCh(st[current])){/*匹配出栈,指示器后移*/Pop();current++;step++;printf("%d\t",step);ShowStack();printf("\t\t%c\t\t出栈、后移\n",st[current]);}else{printf("%c-%c不匹配!",analyseStack[topAnalyse],st[current]);printf("此串不是此文法的句子!\n");return;}}else/*当为非终结符时*/{r=analyseTable[analyseStack[topAnalyse]-100][IndexCh(st[current])];if(-1!=r){Push(r);/*产生式右部代替左部,指示器不移动*/step++;printf("%d\t",step);ShowStack();printf("\t\t%c\t\t%d\n",st[current],r);}else{printf("无可用产生式,此串不是此文法的句子!\n");return;}}}if('#'==st[current]){if(0==topAnalyse&&'#'==st[current]){step++;printf("%d\t",step);ShowStack();printf("\t\t%c\t\t分析成功!\n",st[current]);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 数控技术应用试题及答案
- 2025年北京个人房屋租赁合同范本官方版下载
- 2025官方版股权投资合同范本
- 2025年高二【数学(人教A版)】两条平行直线间的距离公式-学习任务单
- 2025抵质押物的借款合同范本
- 公园养护基本知识培训总结
- 公司职工财务知识培训课件
- 高职卫生专业招生面试题库
- 2025关于汽车租赁的合同样本
- 市场调研与创意策划的关系面试题及答案解析
- 安全生产培训(完整版)课件
- 钢结构长廊施工方案
- 信保业务自查问题统计表
- 年产3万吨环保型铝箔容器系列产品生产线项目环境影响报告
- 安庆汇辰药业有限公司高端原料药、医药中间体建设项目环境影响报告书
- 关于术中知晓预防和脑功能监测专家共识
- 河道修防工高级工试题
- 保障农民工工资支付协调机制和工资预防机制
- GB/T 4458.3-2013机械制图轴测图
- GB/T 311.2-2013绝缘配合第2部分:使用导则
- GB/T 13912-2002金属覆盖层钢铁制件热浸镀锌层技术要求及试验方法
评论
0/150
提交评论