自己做的词法分析器,求斧正。
程序代码:
// --- main.c --- #include "main.h" void testlex() { char wds[256],ps,type; FILE *fp=fopen("test.lx","rt"); while(feof(fp)==0) { type=lex(fp,wds); printf("[%c]\t%s\n",type,wds); } } int main() { #ifdef debug testlex(); #endif return 0; } // --- Lex.c --- #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "Lex.h" #include "Public.h" char TrueLex(FILE *fp,char *words) { memset(words,'\0',256); pt=fgetc(fp); pts[0]=pt; if(pt==32||pt==9) // 跳过空白 { while(feof(fp)!=TRUE&&(pt==32||pt==9)) pt=fgetc(fp); ungetc(pt,fp); // <- return isSpa; }else if(isalpha(pt)!=FALSE||pt=='_') // 识别单词 { while(feof(fp)!=TRUE&&(isalnum(pt)!=FALSE||pt=='_')) { strcat(words,pts); pt=fgetc(fp); pts[0]=pt; } ungetc(pt,fp); // <- return isKey; }else if(isOperat(pts)==TRUE) // 识别运算符 { while(feof(fp)==FALSE&&isOperat(pts)==TRUE) { strcat(words,pts); pt=fgetc(fp); pts[0]=pt; } ungetc(pt,fp); // <- return isCal; }else if(pt=='\'') // 识别字符 { pt=fgetc(fp); if(fgetc(fp)!='\'')return SynErr; sprintf(words,"\'%c\'",pt); return isChr; }else if(pt=='\"') // 识别字符串 { do{ pts[0]=pt; strcat(words,pts); pt=fgetc(fp); if(pt==-1)return SynErr; }while(pt!='\"'); strcat(words,"\""); return isStr; }else if(pt=='\n') // 识别换行符 { return isEnt; }else if(isdigit(pt)!=0) // 识别数值 { int isFloat=FALSE; while(isdigit(pt)!=0) { strcat(words,pts); pt=fgetc(fp); if(pt=='.') // 浮点 { if(isFloat==FALSE) { isFloat=TRUE; strcat(words,"."); pt=fgetc(fp); } else return SynErr; } pts[0]=pt; } if(strstr("BbOoDdHh",pts)!=NULL) // 这是一个进制描述符 { if(isFloat==TRUE) // 进制描述符和浮点共存 strcpy(words,strtok(strdup(words),".")); if(tolower(pt)=='b') return isBin; else if(tolower(pt)=='o') return isOct; else if(tolower(pt)=='d') return isDec; else if(tolower(pt)=='h') return isHex; } ungetc(pt,fp); // <- if(isFloat==TRUE) return isFlo; else return isInt; }else if(isLimit(pt)==TRUE) // 识别定界符 { strcpy(words,pts); return isLim; } return SynErr; } int isLimit(int wd) { if(wd=='('||wd==')'|| wd=='{'||wd=='}'|| wd=='['||wd==']'|| wd==';'||wd==',' ) return TRUE; else return FALSE; } int isOperat(char *wds) { if(strcmp(wds,"+")==0||strcmp(wds,"-")==0||strcmp(wds,"*")==0|| strcmp(wds,"/")==0||strcmp(wds,"%")==0||strcmp(wds,"!")==0|| strcmp(wds,"<")==0||strcmp(wds,">")==0||strcmp(wds,".")==0|| strcmp(wds,"=")==0||strcmp(wds,"==")==0||strcmp(wds,"<=")==0|| strcmp(wds,">=")==0||strcmp(wds,"!=")==0|| strcmp(wds,"||")==0||strcmp(wds,"&&")==0||strcmp(wds,"++")==0|| strcmp(wds,"--")==0||strcmp(wds,"->")==0 ) return TRUE; else return FALSE; } char lex(FILE *fp,char *words) { type=TrueLex(fp,words); if(fgetc(fp)!=-1) fseek(fp,-1,SEEK_CUR); return type; } // --- Lex.h --- char pt,pts[]={0,0},type; char TrueLex(FILE *fp,char *words); int isLimit(int wd); int isOperat(char *wds); char lex(FILE *fp,char *words); // --- Public.h --- #define TRUE 1 #define FALSE 0 #define SynErr '\0' #define unknow '\1' #define isStr 'S' #define isInt 'I' #define isFlo 'F' #define isChr 'C' #define isKey 'K' #define isSpa ' ' #define isLim 'L' #define isCal 'A' #define isEnt 'n' #define isDec 'D' #define isBin 'B' #define isOct 'O' #define isHex 'H' /* * 带进制描述符的值只能是Dec类型的 * 如果描述符和浮点共存,那么舍去浮点数的小数部分 */ #define debug // --- main.h --- #include <stdio.h> #include <stdlib.h> #include "Public.h" extern char lex(FILE *fp,char *words);自己做的词法分析器,求斧正。