编译原理词法分析程序实现实验报告实验一词法分析程序实现一、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。
输入:由无符号数和+,,,*,/, ( , ) 构成的算术表达式,如1.5E+2,100。
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
二、设计部分因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:输入字符p指向第一个字符符号识别*p=+||-||*||/YYNN*p=0~9*p=E*p=0~9||"."N无效符号Y*p=“.”GOTO 2GOTO 1GOTO 1:NY无符号数GOTO 1*p=0~9*p='/0'YNP++NNP++*p=E*p='+'||'-'YYP++P++continueYY*p=0~9*p=0~9NN无符号数无符号数P++P++continuecontinueGOTO 2:GOTO 2*p=EcontinueY无符号数P++continue三、源程序代码部分#include <stdio.h>#include<stdlib.h>#include <math.h>#define MAX 100#define UNSIGNEDNUMBER 1 #define PLUS 2#define SUBTRACT 3#define MULTIPLY 4#define DIVIDE 5#define LEFTBRACKET 6 #define RIGHTBRACKET 7 #define INEFFICACIOUSLABEL 8 #define FINISH 111int count=0;int Class;void StoreType();int Type[100];char Store[20]={'\0'}; void ShowStrFile();//已经将要识别的字符串存在文件a中 void Output(int a,char *p1,char *p2);//字符的输出过程 int Sign(char *p);//'+''-''*''/'整体识别过程int UnsignedNum(char *p);//是否适合合法的正整数0~9 int LegalCharacter(char *p);//是否是合法的字符:Sign(p)||UnsignedNum(p)||'E'||'.'void DistinguishSign(char *p);//'+''-''*''/'具体识别过程 void TypyDistinguish();//字符的识别过程void ShowType();//将类别码存储在Type[100]中,为语法分析做准备void ShowStrFile()//已经将要识别的字符串存在文件a中 {FILE *fp_s;char ch;if((fp_s=fopen("a.txt","r"))==NULL){printf("The FILE cannot open!");exit(0);}elsech=fgetc(fp_s);while(ch!=EOF){putchar(ch);ch=fgetc(fp_s);}printf("\n");}void StoreStr()//将文件中的字符串存储到数组Store[i] { FILE *fp=fopen("a.txt","r");char str;int i=0;while(!feof(fp)){fscanf(fp,"%c",&str);if(str=='?'){Store[i]='\0';break;}Store[i]=str;i++;}Store[i]='\0';}void ShowStore(){int i;for (i=0;Store[i]!='\0';i++)printf("%c",Store[i]);printf("\n");}void Output(int a,char *p1,char *p2){printf("%3s\t%d\t%s\t","CLASS",a,"VALUE");while(p1<=p2){printf("%c",*p1);p1++;}printf("\n");}int Sign(char *p){char ch=*p;if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')') return 1;elsereturn 0;}int UnsignedNum(char *p) {char ch=*p;if('0'<=ch&&ch<='9')return 1;elsereturn 0;}int LegalCharacter(char *p) {char ch=*p;if(Sign(p)||UnsignedNum(p)||ch=='E'||ch=='.') return 1;else return 0;}void DistinguishSign(char *p) { int Class;char ch=*p;switch(ch){case '+':Output(PLUS,p,p);Type[count++]=PLUS;break;case '-':Output(SUBTRACT,p,p);Type[count++]=SUBTRACT;break; case '*':Output(MULTIPLY,p,p);Type[count++]=MULTIPLY;break; case '/':Output(DIVIDE,p,p);Type[count++]=DIVIDE;break; case '(':Output(LEFTBRACKET,p,p);Type[count++]=LEFTBRACKET;break; case ')':Output(RIGHTBRACKET,p,p);Type[count++]=RIGHTBRACKET;break; default:break;}}void TypyDistinguish(){printf("词法开始,分析结果如下:\n");char *p;p=&Store[0];while(*p!='\0'){if(Sign(p)){DistinguishSign(p++);continue;}else if(UnsignedNum(p)||*p=='.'){char *p1=p;if(UnsignedNum(p)){while(UnsignedNum(p))p++;if(*p=='\0'){Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='E'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='+'||*p=='-'){p++;while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~"); break; Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}else if(*p=='.'){p++;while(UnsignedNum(p))p++;if(*p=='\0'){Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='E'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='+'||*p=='-'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~ /n");break;Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~因为他的后面既不是0~9也不是“+”或者“-…");break;//1.5E*2这样的字符串不是无符号数Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}else{Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}}else{Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}}if(*p=='.'){p++;if(UnsignedNum(p)){p++;while(UnsignedNum(p))p++;if(*p=='\0'){Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='E'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='+'||*p=='-'){p++;while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}}else{Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~"); break; Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}}else if(*p=='E'){Output(INEFFICACIOUSLABEL,p,p); break;Type[count++]=INEFFICACIOUSLABEL;printf("输入的这个符号是不合法的~");p++;continue;}}printf("\n\n词法分析完毕~");}void ShowType()//将类别码存储在Type[100]中,为语法分析做准备{printf("\n用类别码表示输入的字符如下:\n");int i;printf("\n");for(i=0;Type[i]!=FINISH;i++){printf("%d",Type[i]);}printf("\n\n");}void main(){//词法分析部分StoreStr();ShowStore();TypyDistinguish();Type[count]=FINISH;ShowType();}四、实验结果正确的结果:错误的结果:输入的字符串中有1.5E*2因为实验是以文件的形式进行读取的所以,在读取不合法的过程中只是将存在project 中的a.txt 中的内容改变改为1.5E*2+100*555实验结果如下:结果分析:对于正确的结果,我以二元式的形式输出,包括他的值和他的类别码,其中将类别码存放在另外的一个数组中,为了在实验二中的语法识别打下基础。