#includestdio.h#includestring.h#includeWindows.h#defineMAX_COUNT1024#defineILLEGAL_CHAR_ERR1#defineUNKNOWN_OPERATOR_ERR2/*从标准输入读入第一个非空白字符(换行符除外)*/chargetnbc(){charch;ch=getchar();while(1){if(ch=='\r'||ch=='\t'||ch==''){ch=getchar();}else{break;}}returnch;}/*判断character是否为字母*/boolletter(charcharacter){if((character='a'&&character='z')||(character='A'&&character='Z'))returntrue;elsereturnfalse;}/*判断character是否为数字*/booldigit(charcharacter){if(character='0'&&character='9')returntrue;elsereturnfalse;}/*回退字符*/voidretract(char&character){ungetc(character,stdin);character=NULL;}/*返回保留字的对应种别*/intreserve(char*token){if(strcmp(token,begin)==0)return1;elseif(strcmp(token,end)==0)return2;elseif(strcmp(token,integer)==0)return3;elseif(strcmp(token,if)==0)return4;elseif(strcmp(token,then)==0)return5;elseif(strcmp(token,else)==0)return6;elseif(strcmp(token,function)==0)return7;elseif(strcmp(token,read)==0)return8;elseif(strcmp(token,write)==0)return9;elsereturn0;}/*返回标识符的对应种别*/intsymbol(){return10;}/*返回常数的对应种别*/intconstant(){return11;}/*按照格式输出单词符号和种别*/voidoutput(constchar*token,intkindNum){printf(%16s%2d\n,token,kindNum);}/*根据行号和错误码输出错误*/boolerror(intlineNum,interrNum){char*errInfo;switch(errNum){caseILLEGAL_CHAR_ERR:errInfo=出现字母表以外的非法字符;break;caseUNKNOWN_OPERATOR_ERR:errInfo=出现未知运算符;break;default:errInfo=未知错误;}if(fprintf(stderr,***LINE:%d%s\n,lineNum,errInfo)=0)returntrue;elsereturnfalse;}/*词法分析函数,每调用一次识别一个符号*/boolLexAnalyze(){staticintlineNum=1;charcharacter;chartoken[17]=;character=getnbc();switch(character){case'\n':output(EOLN,24);lineNum++;break;caseEOF:output(EOF,25);returnfalse;//false表示已读到文件末尾case'a':case'b':case'c':case'd':case'e':case'f':case'g':case'h':case'i':case'j':case'k':case'l':case'm':case'n':case'o':case'p':case'q':case'r':case's':case't':case'u':case'v':case'w':case'x':case'y':case'z':case'A':case'B':case'C':case'D':case'E':case'F':case'G':case'H':case'I':case'J':case'K':case'L':case'M':case'N':case'O':case'P':case'Q':case'R':case'S':case'T':case'U':case'V':case'W':case'X':case'Y':case'Z':while(letter(character)||digit(character)){chars[2]={character};strcat(token,s);character=getchar();}retract(character);intnum;num=reserve(token);if(num!=0)output(token,num);else{intval;val=symbol();output(token,val);}break;case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':while(digit(character)){chars[2]={character};strcat(token,s);character=getchar();}retract(character);intval;val=constant();output(token,val);break;case'=':output(=,12);break;case'':character=getchar();if(character=='')output(,13);elseif(character=='=')output(=,14);else{retract(character);output(,15);}break;case'':character=getchar();if(character=='=')output(=,16);else{retract(character);output(,17);}break;case'-':output(-,18);break;case'*':output(*,19);break;case':':character=getchar();if(character=='=')output(:=,20);elseerror(lineNum,2);//输出“未知运算符”错误break;case'(':output((,21);break;case')':output(),22);break;case';':output(;,23);break;default:error(lineNum,1);//输出出现字母表以外的非法字符错误}returntrue;}/*获得路径*/voidgetPath(char*in,char*out){char*name;name=strrchr(in,'\\');if(name!=NULL)strncpy(out,in,strlen(in)-strlen(name)+1);elsestrcpy(out,);}/*获得文件名,不包括扩展*/voidgetFilename(char*in,char*out){char*fullName;char*extension;fullName=strrchr(in,'\\');extension=strrchr(in,'.');if(fullName!=NULL)strncpy(out,fullName+1,strlen(fullName)-1-strlen(extension));elsestrncpy(out,in,strlen(in)-strlen(extension));}/*初始化函数,接收输入文件地址,并打开输入、输出、错误文件、将标准输入重定向到输入文件,将标准输出重定向到输出文件,标准错误重定向到错误文件*/boolinit(intargc,char*argv[]){if(argc!=2){returnfalse;}else{char*inFilename=argv[1];//argv[1];charoutFilename[MAX_COUNT]=;charerrFilename[MAX_COUNT]=;charfilename[MAX_COUNT]=;charpath[MAX_COUNT]=;//获得文件名(不包括扩展名)和路径getFilename(inFilename,filename);getPath(inFilename,path);//生成输出文件全部路径strcat(outFilename,path);//strcat(outFilename,\\);strcat(outFilename,filename);strcat(outFilename,.dyd);//生成错误文件全部路径strcat(errFilename,path);//strcat(errFilename,\\);strcat(errFilename,filename);strcat(errFilename,.err);if(freopen(inFilename,r,stdin)!=NULL&&freopen(outFilename,w,stdout)!=NULL&&freopen(errFilename,w,stderr)!=NULL)returntrue;elsereturnfalse;}}voidmain(intargc,char*argv[])//argv[1]是输入文件地址{if(init(argc,argv)){while(LexAnalyze()){}}fclose(stdin);fclose(stdout);fclose(stderr);return;}