自己做的词法分析器,求斧正。
程序代码:// --- 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);
自己做的词法分析器,求斧正。



