⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 词法.c

📁 这是一个PL0编译系统的词法分析程序 能识别出所有的单词并分类
💻 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 + -