c语言词法分析器

来源:互联网 发布:网络电视开机黑屏 编辑:程序博客网 时间:2024/05/17 03:43

#include<stdio.h>
#include<ctype.h>
#include<string.h>

void  main(void);
int reserver(char *);

void main(void)
{
 FILE *input,*output;
 char ch,*token="";
 int i=0,isReserver=0;
 int count=0;
 /*打开文件*/
 if((input=fopen("input.txt","rt"))==NULL)
 { printf("file open in readonly mode,but an error generate!/n");
  exit(0);
 }
 if((output=fopen("output.txt","wt"))==NULL)
 {
  printf("file open in new_create mode,but an error generate!/n");
  exit(0);
 }
 
 fprintf(output,"%4s/t/%8s/t %-16s)/t%4s/n","位置","符号类型","识别符","长度");
 ch=fgetc(input);
 while(ch!=EOF)
 {
  i=0;
  /*去掉前导空格,换行符*/
  while((ch==' '||ch=='/n'||ch=='/t')&&ch!=EOF)
   ch=fgetc(input);
  /*字母开头*/
  if(isalpha(ch))
  {
  while(isalpha(ch)||isdigit(ch))
   {
   token[i++]=ch;
   ch=fgetc(input);
   }

  token[i]='/0';
  isReserver=reserver(token);
  if(isReserver==1)
   {count++;fprintf(output,"%4d/t(标识符/t/t,%-16s)/t%4d/n",count,token,i);}
  else if(isReserver==0)
   {count++;fprintf(output,"%4d/t(保留字/t/t,%-16s)/t%4d/n",count,token,i);}
  else if(isReserver==2)
   {count++;fprintf(output,"%4d/t(算符/t/t,%-16s)/t%4d/n",count,token,i);}
  continue;   
  }
  /*识别数字*/
  else if(isdigit(ch))
   {
    while(isdigit(ch))
    {
    token[i++]=ch;
    ch=fgetc(input);
    }
   /*出现非数字且为点时*/   
   if (ch=='.')
    {
    token[i++]=ch; /*将点加入*/
    ch=fgetc(input);/*读入下一个字符*/
    if (isdigit(ch))
     {
      while(isdigit(ch)) /*是数字时,收入,并将加一*/
      {
      token[i++]=ch;
      ch=fgetc(input);
      }
      /*如果是数字加点再加数字再出现字母时,就是错误*/
             if(isalpha(ch))
      {
       while(isdigit(ch)||isalpha(ch)||ch=='.')
       {
        token[i++]=ch;
        ch=fgetc(input);
       }
       token[i]='/0';
       count++;fprintf(output,"%4d/t(标识错误/t,%-16s)/t%4d/n",count,token,i);
       continue; 
      }
      /*当出现结束符时,就收入为实数内*/
      else
      {
      token[i]='/0';
      count++;fprintf(output,"%4d/t(实数/t/t,%-16s)/t%4d/n",count,token,i);
      continue;
      }
     }
    }
   
   /*如果是字符,则判断为标识错误*/
   else if(isalpha(ch))
    {
     while(isdigit(ch)||isalpha(ch)||ch=='.')      
     {
     token[i++]=ch;
     ch=fgetc(input);
     }
     token[i]='/0';
     count++;fprintf(output,"%4d/t(标识错误/t,%-16s)/t%4d/n",token);
     continue; 
    }
   /*如果是单词段结束符时,就判断为常数*/  
   else
    {
     token[i]='/0';
     count++;fprintf(output,"%4d/t(常数/t/t,%-16s)/t%4d/n",count,token,i);
     continue;
    }
   }     
  else if(ch=='(')
   {
    token[i++]=ch;
    ch=fgetc(input);
    token[i]='/0';
    count++;fprintf(output,"%4d/t(右括号运算符/t,%-16s)/t%4d/n",count,token,i);
    continue;
   }
  else if(ch==')')
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(左括号运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch=='[')
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(右中括号运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch==']')
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(左中括号运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch=='-')
   {
   token[i++]=ch;
   ch=fgetc(input);
   if(ch=='-')
    {
    token[i++]=ch;
    token[i]='/0';
    count++;fprintf(output,"%4d/t(自加运算符/t,%-16s)/t%4d/n",count,token,i);
    ch=fgetc(input);
    continue;
    }
   else if (ch=='>')
    {
    token[i++]=ch;
    token[i]='/0';
    count++;fprintf(output,"%4d/t(指针运算符/t,%-16s)/t%4d/n",count,token,i);
    ch=fgetc(input);
    continue;
    }
   token[i]='/0';
   count++;fprintf(output,"%4d/t(负运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch=='.')
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(点运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch=='&')  
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(地址与运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;   
   }
  else if(ch=='!')  
   {
   token[i++]=ch;
   ch=fgetc(input);
   if(ch=='=')
    {
    token[i++]=ch;
    token[i]='/0';
    count++;fprintf(output,"%4d/t(不等于比较符/t,%-16s)/t%4d/n",count,token,i);
    ch=fgetc(input);
    continue;
    }
   token[i]='/0';
   count++;fprintf(output,"%4d/t(取反运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;   
   }
  else if(ch=='~')  
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(按位运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;   
   }
  else if(ch=='*')
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(乘运算符/t,%-16s)/t%4d/t/n",count,token,i);
   continue;   
   }
  else if(ch=='%')  
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(求余运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;   
   }
  else if(ch=='/')  
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(除法运算符/t,%-16s)/t%4d/t/n",count,token,i);
   continue;   
   }  
  else if(ch=='<')
   {
   token[i++]=ch;
   ch=fgetc(input);
   if(ch=='=')
    {
    token[i++]=ch;
    token[i]='/0';
    count++;fprintf(output,"%4d/t(小于等于比较符/t,%-16s)/t%4d/n",count,token,i);
    ch=fgetc(input);
    continue;
    }
   if(ch=='<')
    {
    token[i++]=ch;
    token[i]='/0';
    count++;fprintf(output,"%4d/t(左移运算符/t,%-16s)/t%4d/t/n",count,token,i);
    ch=fgetc(input);
    continue;
    }
   token[i]='/0';
   count++;fprintf(output,"%4d/t(小于比较符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch=='>')
   {
   token[i++]=ch;
   ch=fgetc(input);
   if(ch=='=')
    {
    token[i++]=ch;
    token[i]='/0';
    count++;fprintf(output,"%4d/t(大于等于比较符/t,%-16s)/t%4d/n",count,token,i);
    ch=fgetc(input);
    continue;
    }
   if(ch=='>')
    {
    token[i++]=ch;
    token[i]='/0';
    count++;fprintf(output,"%4d/t(右移运算符/t,%-16s)/t%4d/n",count,token,i);
    ch=fgetc(input);
    continue;
    }
   token[i]='/0';
   count++;fprintf(output,"%4d/t(大于比较符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch=='=')
   {
   token[i++]=ch;
   ch=fgetc(input);
   if(ch=='=')
    {
    token[i++]=ch;
    token[i]='/0';
    count++;fprintf(output,"%4d/t(等于比较符/t,%-16s)/t%4d/n",count,token,i);
    ch=fgetc(input);
    continue;
    }
   token[i]='/0';
   count++;fprintf(output,"%4d/t(赋值运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch==',')
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(逗号界符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   } 
  else if(ch==';')
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(分号界符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  
  else if(ch=='{')
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(边界运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch=='}')
   {
   token[i++]=ch;
   ch=fgetc(input);
   token[i]='/0';
   count++;fprintf(output,"%4d/t(边界运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch=='+')
   { 
   token[i++]=ch;
   ch=fgetc(input);
   if(ch=='+')
    {
    token[i++]=ch;
    token[i]='/0';
    count++;fprintf(output,"%4d/t(自加运算符/t,%-16s)/t%4d/n",count,token,i);
    ch=fgetc(input);
    continue;
    }
   token[i]='/0';
   count++;fprintf(output,"%4d/t(加运算符/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  else if(ch=='"')
   { 
   token[i++]=ch;
   ch=fgetc(input);
   while(ch!='"'&&ch!=EOF)
    {
    token[i++]=ch;
    ch=fgetc(input);    
    }
   if(ch=='"')
    {
    token[i++]=ch;
    ch=fgetc(input);
    token[i]='/0';
    count++;fprintf(output,"%4d/t(字符串/t/t,%-16s)/t%4d/n",count,token,i);
    continue;
    }
   else
    {
    while(ch!=EOF)
    {
    token[i++]=ch;
    ch=fgetc(input);
    }
    token[i]='/0';
    count++;fprintf(output,"%4d/t(字符串错误/t,%-16s)/t%4d/n",count,token,i);
    }
   } 
  else
   {
   while(ch!=' '&&ch!='/t'&&ch!='/n'&&ch!=EOF)
   {
    token[i++]=ch;
    ch=fgetc(input);
   }
   token[i]='/0';
   count++;fprintf(output,"%4d/t(无法识别错误/t,%-16s)/t%4d/n",count,token,i);
   continue;
   }
  }
 fclose(input);
 fclose(output);
}

/*判断是不是关键字:
 1,则是标识符
 0,则是关键字
  2,则是运算符
 */

int reserver(char *str)
{
 FILE *fpReserver;
 char *tmpStr='/0';

 if(strcmp(str,"sizeof")==0)
  return 2;
 /*打开关键字文件*/
 if((fpReserver=fopen("keyword.txt","r"))==NULL)
 { printf("file open in readonly mode,but an error generate!/n");
  exit(0);
 }
 while(fscanf(fpReserver,"%s",tmpStr)!=EOF)
  if(strcmp(str,tmpStr)==0)
   {fclose(fpReserver);return 0;}
 fclose(fpReserver);
 return 1; 



/*

输入文件input.txt

#include<stdio.h>

void E(char *);
void E1(char *);
void T(char *);
void T1(char *);
void F(char *);

void main()
{
 char *str="i+(i*i";
 printf("%s/n",str);
 E(str);
}

void E(char *str)
{
 T(str);
 printf("1%s/n",str);
 E1(str);
 printf("2%s/n",str);
}

void E1(char *str)
{
 if (*str=='+')
 {
  str++;
  T(str);
  E1(str);
 }

}

void T(char *str)
{
 F(str);
 T1(str);
}
void T1(char *str)
{
 if(*str=='*')
  {
   str++;
   F(str);
   T1(str);
  }
}

void F(char *str)
{
 if(*str=='(')
 {
  str++;
  E(str);
  if(*str==')')
   str++;
  else
  {
   printf("lost ')'/n");
   exit(0);
  }
 }
 else if(*str=='i')
  str++;
      else
  {
   printf("lost variable/n");
   exit(0);
  }
}

*/

/*

关键字文件keyword.txt

auto  break  case  char  const
continue default  do  double  else
enum  extern  float  for  goto
if  int  long  register return 
short  signed  sizeof  static  struct
switch  typedef  union  unsigned void
volatile while

*/