📄 词法.c
字号:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef enum {
ID,NUM,ASSIGN,EQ,LT,MT,PLUS,MINUS,TIMES,OVER,LPAREN,RPAREN,SEMI,ERROR}TokenType;
typedef enum {
START,INASSIGN,INNUM,INID,DONE}StateType;
typedef struct{
TokenType token;
union
{
char *stringval;
int numval;
}attribute;
}TokenRecord;
#define BUFFLEN 100/*定义缓存空间大小*/
char *TempSpace; /*store the words that have been preprocessed*/
int space=0; /*空格标志,标志是否已经空格,用以删除多余的空格*/
int filepos=0; /*词法分析的当前字符位置*/
char ctemp[BUFFLEN]; /*暂存当前读出的字符串*/
int simple(char ch)
/*标志是否有多余的空格*/
{
if((ch==' ')&&(space==1))
{
return 1;
}
else if(ch==' ')
{
space=1;
return 0;
}
else
{
space=0;
return 0;
}
}
void preProccess(FILE *fpoint)
/*预处理,去掉源代码中的注释以及多余的空格和回车符*/
{
FILE *fp;
char ch;
int flag=0;
if((fp=fopen("temp","wt+"))==NULL)/*产生一个临时交换用的文件temp用于存放修改后的源代码*/
{
printf("temp file write error!");
exit();
}
ch=fgetc(fpoint);
while((simple(ch)==1)||(ch=='\n'))/*如果有多余的空格,则省略*/
{
ch=fgetc(fpoint);
}
while(ch!=EOF)
{
if(ch=='/')
{
ch=fgetc(fpoint);
if(ch=='*')
{
ch=fgetc(fpoint);
while(flag==0)
{
if(ch==EOF) flag=1;
if(ch=='*') { ch=fgetc(fpoint);
if(ch=='/') { ch=fgetc(fpoint); flag=1; }
else ch=fgetc(fpoint);
}
else ch=fgetc(fpoint);
}
flag=0;
}
else
{
fputc('/',fp);/*如果不是注释标志则要把"/"写入临时交换区*/
}
}
while(simple(ch)==1)
{
ch=fgetc(fpoint);
}
if(ch!='\n')
{
fputc(ch,fp);
ch=fgetc(fpoint);
}
else
ch=fgetc(fpoint);
}
fclose(fp);
}
int keyword()
{
if(!stricmp(ctemp,"IF"))
return 1;
else if(!stricmp(ctemp,"WHILE"))
return 1;
else if(!stricmp(ctemp,"FOR"))
return 1;
else if(!stricmp(ctemp,"THEN"))
return 1;
else
return 0;
}
int TokenPrint(TokenType token)
{
switch(token)
{
case ID:
if(!keyword())
{
printf("ID\n");
}
else printf("Key Word\n");
break;
case NUM:printf("NUM\n");break;
case ASSIGN:printf("ASSIGN\n");break;
case EQ:printf("EQ\n");break;
case LT:printf("LT\n");break;
case MT:printf("MT\n");break;
case PLUS:printf("PLUS\n");break;
case MINUS:printf("MINUS\n");break;
case TIMES:printf("TIMES\n");break;
case LPAREN:printf("LPAREN\n");break;
case RPAREN:printf("RPAREN\n");break;
case SEMI:printf("SEMI\n");break;
case ERROR:printf("ERROR\n");break;
default:return 1;
}
return 0;
}
/*char getNextChar(FILE *fpoint)
{
filepos++;
if(fgets(ctemp,filepos,fpoint))
{
return ctemp[
}
else return EOF;
}*/
void wordscan(FILE *fpoint)
{
char ch;
int i=0,save=1;
StateType state;
TokenType currentToken;
/* TokenRecord temp;
&temp=(TokenRecord)malloc(1*sizeof(TokenRecord));*/
ch=fgetc(fpoint);
while(ch!=EOF)
{
state=START;
while(state!=DONE)
{
switch(state)
{
case START:
if(isdigit(ch))
{
state=INNUM;
ctemp[i]=ch;
i++;
}
else if(isalpha(ch))
{
state=INID;
ctemp[i]=ch;
i++;
}
else if(ch==':')
{state=INASSIGN;
ctemp[i]=ch;
i++;
}
else if((ch=='\0')||(ch==' '))
{state=DONE;save=0;}
else
{
state=DONE;
ctemp[i]=ch;
i++;
switch(ch)
{
case '=':
currentToken=EQ;
break;
case '<':
currentToken=LT;
break;
case '>':
currentToken=MT;
break;
case '+':
currentToken=PLUS;
break;
case '-':
currentToken=MINUS;
break;
case '*':
currentToken=TIMES;
break;
case '(':
currentToken=LPAREN;
break;
case ')':
currentToken=RPAREN;
break;
case ';':
currentToken=SEMI;
break;
default:
currentToken=ERROR;
}/*end switch(ch)*/
}/*end if*/
break;
case INASSIGN:
state=DONE;
if(ch=='=')
{ currentToken=ASSIGN;
ctemp[i]=ch;
i++;
}
else
{
fseek(fpoint,-1,1);
currentToken=ERROR;
}
break;
case INNUM:
ch=fgetc(fpoint);
if(!isdigit(ch))
{
fseek(fpoint,-1,1);
state=DONE;
currentToken=NUM;
}
else
{
ctemp[i]=ch;
i++;
}
break;
case INID:
ch=fgetc(fpoint);
if((!isalpha(ch))&&(!isdigit(ch)))
{
fseek(fpoint,-1,1);
state=DONE;
currentToken=ID;
}
else
{
ctemp[i]=ch;
i++;
}
break;
case DONE:
break;
default:
currentToken=ERROR;
break;
}/*end switch*/
}/*end while(state!=DONE)*/
ctemp[i]='\0';
i=0;
if(save)
{
printf("TokenString:%s\n",ctemp);
printf("TokenType:");
if(TokenPrint(currentToken))
{
printf("print error");
exit(0);
}
}
save=1;
ch=fgetc(fpoint);
}/*end While(ch!=EOF)*/
}
main(int argc,char *argv[])
{
FILE *fp;
char ch,*ctemp,*filename="test.txt";
argc=2;
argv[1]=filename;
if (argc==1)
{
printf("the filename can't be NULL!");
printf("\nusage:scan filename\n");
exit();
}
if((fp=fopen(argv[1],"rt"))==NULL)
{
printf("can not open file %s,press any key to end",argv[1]);
getch();
exit();
}
preProccess(fp);
fclose(fp);
if((fp=fopen("temp","rt"))==NULL)
{
printf("can not open file temp,press any key to end");
getch();
exit();
}
wordscan(fp);
fclose(fp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -