编译原理实验报告CompilersPrinciplesExperimentReport所在学院:所在班级:学生姓名:学号:指导教师:教务处2015年12月词法分析程序一、实验目的:设计、编制和调试一个具体的词法分析程序,加深对词法分析的理解。二、实验要求:1、通过对PL/0词法分析程序(GETSYS)的分析,编制一个具有以下功能的词法分析程序:a.输入为字符串(或待进行词法分析的源程序),输出为单词串,即由(单词,类别)所组成的二元组序列;b.有一定的错误检查能力,例如能发现2a这类不能作为单词的字符串。三、实验代码#defineID12//标识符#defineINT13//常数#defineJF14//界符#defineYSF15//运算符#defineN30//字符读取的最大长度charTOKEN[N];FILE*write;//查询一个字符串,看其是否与指定的字符相匹配,如果匹配返回1个非零的值,如果不匹配,则返回一个0值*/intlooksame(char*a){inti;char*key[22]={begin,end,if,then,else,for,do,while,and,or,not,BEGIN,END,IF,THEN,ELSE,FOR,DO,WHILE,AND,OR,NOT};for(i=0;i22;i++){if(strcmp(key[i],a)==0)//该字符串是否与关键字相匹配return(i%11+1);}return0;}//把a输入到指定文件中,然后从该文件中读出字符串,放到一个数组中输出voidout(inta,char*b){FILE*write;write=fopen(E:\\b.txt,a+);if(write==NULL){printf(文件打开失败);exit(0);}fprintf(write,%d\t,a);fwrite(b,strlen(b),1,write);fprintf(write,\n);fclose(write);printf(%d%20s\t\t,a,b);}interror(){printf(书写格式错误,未被识别\n);return0;}voidfunction(FILE*fp){charch='';inti,c;while(ch!=EOF){ch=fgetc(fp);//从文件中读取字符while(ch==''||ch=='\t'||ch=='\n'){ch=fgetc(fp);}if(isalpha(ch))//isalpha()判断是否为英文字母,是则返回非零值,否则返回零{TOKEN[0]=ch;ch=fgetc(fp);i=1;while(isalnum(ch))//isalnum()判断字符是否为英文字母或数字,如果是则返回非零值,如果不是则返回零//{TOKEN[i]=ch;i++;ch=fgetc(fp);}TOKEN[i]='\0';fseek(fp,-1,1);//用于二进制方式打开的文件,移动文件读写指针位置c=looksame(TOKEN);if(c==0){out(ID,TOKEN);printf(标识符\n);}else{out(c,TOKEN);printf(关键字\n);}}elseif(isdigit(ch))//isdigit()判断是否为0-9的数字{TOKEN[0]=ch;ch=fgetc(fp);i=1;while(isdigit(ch)){TOKEN[i]=ch;i++;ch=fgetc(fp);}TOKEN[i]='\0';fseek(fp,-1,1);out(INT,TOKEN);printf(常数\n);}else{switch(ch){case'+':out(YSF,+);printf(运算符\n);break;case'-':out(YSF,-);printf(运算符\n);break;case';':out(JF,;);printf(界符\n);break;case',':out(JF,,);printf(界符\n);break;case'|':out(YSF,|);printf(运算符\n);break;case'{':out(JF,{);printf(界符\n);break;case'(':out(JF,();printf(界符\n);break;case'!':out(JF,!);printf(界符\n);break;case'^':out(JF,^);printf(界符\n);break;case')':out(JF,));printf(界符\n);break;case'}':out(JF,});printf(界符\n);break;case'':ch=fgetc(fp);if(ch=='='){out(YSF,=);printf(运算符\n);}elseif(ch==''){out(YSF,);printf(运算符\n);}else{fseek(fp,-1,1);out(YSF,);printf(运算符\n);}break;case'=':out(YSF,=);printf(运算符\n);break;case'':ch=fgetc(fp);if(ch=='='){out(YSF,=);printf(运算符\n);}else{fseek(fp,-1,1);out(YSF,);printf(运算符\n);}break;case':':ch=fgetc(fp);if(ch=='='){out(YSF,:=);printf(运算符\n);}else{fseek(fp,-1,1);out(JF,:);printf(界符\n);}break;case'/':ch=fgetc(fp);if(ch=='*'){out(JF,/*);printf(界符\n);while(1)//注释的内容在词法分析中不显示while(ch!='/')ch=fgetc(fp);fseek(fp,-2,1);ch=fgetc(fp);if(ch=='*'){fseek(fp,1,1);break;}else{fseek(fp,2,1);ch=fgetc(fp);}fseek(fp,-2,1);}else{fseek(fp,-1,1);out(JF,/);printf(界符\n);}break;case'*':ch=fgetc(fp);if(ch=='/'){out(JF,*/);printf(界符\n);}else{fseek(fp,-1,1);out(YSF,*);printf(运算符\n);}break;caseEOF:break;default:error();break;}}}}intmain(){FILE*read;read=fopen(E:\\a.txt,r);write=fopen(E:\\b.txt,a+);if(read==NULL){printf(FILEOPENFAIL!);exit(0);}printf(===========================================================\n);printf(====================词法分析程序===========================\n);printf(===========该分析程序的文件存放在E:\\a.txt目录下==========\n);printf(===========该程序的分析结果存放在E:\\b.txt目录下===========\n);printf(============================================================\n);function(read);fclose(read);system(pause);return0;}四、实验截图a.txtb.txt基于LL(1)方法的语法分析程序一、实验目的设计、编制和调试一个典型的语法分析方法,进一步掌握常用的语法分析方法。二、实验要求1、根据LL(1)分析法编写一个语法分析程序,可根据自己实际情况,选择以下一项作为分析算法的输入:a.直接输入根据已知文法构造的分析表M;b.输入文法的FIRST(α)和FOLLOW(U)集合,由程序自动生成文法的分析表M;c.输入已知文法,由程序自动构造文法的分析表M。2、程序具有通用性所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为LL(1)文法。3、有运行实例对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。三、实验代码#includestdafx.h#includestdio.h#includestdlib.h#includestring.h#includedos.hcharA[20];/*分析栈*/charB[20];/*剩余串*/charv1[20]={'i','+','*','(',')','#'};/*终结符*/charv2[20]={'E','G','T','S','F'};/*非终结符*/intj=0,b=0,top=0,l;/*L为输入串长度*/typedefstructtype/*产生式类型定义*/{charorigin;/*大写字符*/chararray[5];/*产生式右边字符*/intlength;/*字符个数*/}type;typee,t,g,g1,s,s1,f,f1;/*结构体变量*/typeC[10][10];/*预测分析表*/voidprint()/*输出分析栈*/{inta;/*指针*/for(a=0;a=top+1;a++)printf(%c,A[a]);printf(\t\t);}/*print*/voidprint1()/*输出剩余串*/{intj;for(j=0;jb;j++)/*输出对齐符*/printf();for(j=b;j=l;j++)printf(%c,B[j]);printf(\t\t\t);}int_tmain(intargc,_TCHAR*argv[]){intm,n,k=0,flag=0,finish=0;charch,x;typecha;/*用来接受C[m][n]*//*把文法产生式赋值结构体*/e.origin='E';strcpy(e.array,TG);e.length=2;t.origin='T';strcpy(t.array,FS);t.length=2;g.origin='G';strcpy(g.array,+TG);g.length=3;g1.origin='G';g1.array[0]='^';g1.length=1;s.origin='S';strcpy(s.array,*FS);s.length=3;s1.origin='S';s1.array[0]='^';s1.length=1;f.origin='F';strcpy(f.array,(E));f.length=3;f1.origin='F';f1.array[0]='i';f1.length=1;for(m=0;m=4;m++)/*初始化分析表*/for(n=0;n=5;n++)C[m][n].origin='N';/*全部赋为空*//*填充分析表*/C[0][0]=e;C[0][3]=e;C[1][1]=g;C[1][4]=g1;C[1][5]=g1;C[2][0]=t;C[2][3]=t;C[3][1]=s1;C[3][2]=s;C[3][4]=C[3][5]=s1;C[4][0]=f1;C[4][3]=f;printf(提示:本程序只能对由'i','+','*','(',')'构成的以'#'结束的字符串进行分析,\n);printf(请输入要分析的字符串:);do/*读入分析串*/{scanf(%c,&ch);if((ch!='i')&&(ch!='+')&&(ch!='*')