用c写的词法分析器

来源:互联网 发布:ipad软件图标上有锁 编辑:程序博客网 时间:2024/05/16 18:40

这学期开了《编译原理》这门课,为检验学习的成果,同时也是个作业,自己写了个简单的词法分析器,不是很成熟,在结构方面有些混乱,好在功能还算是实现了,值得庆幸~

要求:

给定一个C语言的子集 ,如下:

关键字(小写)main  if  else  int  return   void  while

算符或界符:=  +  -  *  /  <  <=  >  >=  = =   !=  ; : , { }  [ ]  ( )

标识符是字母开头,后面字母和数字组合

数值指无符号常数

空格一般用来分隔标识符、数值、专用符号和关键字

 

以下为代码:

/*cifa.c*/

#include <stdio.h>

#define MAX 50  /*标识符的最大长度*/

main()
{
 FILE *in,*out;
 
 char word[MAX];   /*存储标识符*/
 char cp;    /*存储当前读入字符*/
 int i;

 if((in=fopen("in.txt","r"))==NULL)
 {
  printf("不能打开文档in.txt,请检查根目录下是否存在该文档/n");
  exit(0);
 }
 else
 {
  printf("成功打开文档in.txt/n");
 }

 if((out=fopen("out.txt","w"))==NULL)
 {
  printf("不能打开文档out.txt,请检查根目录下是否存在该文档时/n");
  exit(0);
 }
 else
 {
  printf("成功打开文档out.txt/n");
 }

 cp=fgetc(in);
 while(cp!=EOF)
 {
  /*消耗掉空格,制表符,换行符*/
  while(cp==' '||cp==' '||cp=='/n')
  {
   cp=fgetc(in);
  }
  
  /*cp数组复位*/
  i=0;
  
  /*数字检测*/
  if(cp>='0'&&cp<='9')
  {
   word[i++]=cp;
   cp=fgetc(in);
   while(cp>='0'&&cp<='9')
   {
    word[i++]=cp;
    cp=fgetc(in);
   }
   if(cp==' '||cp==' '||cp=='/n'||cp=='='||cp=='+'||cp=='-'||cp=='*'||cp=='/'||cp=='>'||cp=='<'||cp=='!'||cp==';'||cp==':'||cp==','||cp=='{'||cp=='}'||cp=='['||cp==']'||cp=='('||cp==')')
   {
    word[i]='/0';
    fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',28,')');
   }
   else
   {
    while(cp!=' '&&cp!=' '&&cp!='/n'&&cp!='='&&cp!='+'&&cp!='-'&&cp!='*'&&cp!='/'&&cp!='>'&&cp!='<'&&cp!='!'&&cp!=';'&&cp!=':'&&cp!=','&&cp!='{'&&cp!='}'&&cp!='['&&cp!=']'&&cp!='('&&cp!=')')
    {
     word[i++]=cp;
     cp=fgetc(in);
    }
    word[i]='/0';
    fprintf(out,"%s%c%s%c%s/n","error: ",'"',word,'"',"不是合法的标识符");
   }
   continue;
  }
   
  /*字符串检测*/
  if((cp>='a'&&cp<='z')||(cp>='A'&&cp<='Z')||cp=='_')
  {
   while((cp>='a'&&cp<='z')||(cp>='0'&&cp<='9')||(cp>='A'&&cp<='Z')||cp=='_')
   {
    word[i++]=cp;
    cp=fgetc(in);
   }

   
   if(cp==' '||cp==' '||cp=='/n'||cp=='='||cp=='+'||cp=='-'||cp=='*'||cp=='/'||cp=='>'||cp=='<'||cp=='!'||cp==';'||cp==':'||cp==','||cp=='{'||cp=='}'||cp=='['||cp==']'||cp=='('||cp==')')
   {
    word[i]='/0';
    /*关键字/标识符检测*/
    if(strcmp(word,"main")==0)
     fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',1,')');
    else if(strcmp(word,"if")==0)
     fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',2,')');
    else if(strcmp(word,"else")==0)
     fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',3,')');
    else if(strcmp(word,"int")==0)
     fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',4,')');
    else if(strcmp(word,"return")==0)
     fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',5,')');
    else if(strcmp(word,"void")==0)
     fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',6,')');
    else if(strcmp(word,"while")==0)
     fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',7,')');
    else
     fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',29,')');
   }
   
   /*排错处理(只能以字母、数字、下划线构成)*/
   else
   {
     while(cp!=' '&&cp!=' '&&cp!='/n'&&cp!='='&&cp!='+'&&cp!='-'&&cp!='*'&&cp!='/'&&cp!='>'&&cp!='<'&&cp!='!'&&cp!=';'&&cp!=':'&&cp!=','&&cp!='{'&&cp!='}'&&cp!='['&&cp!=']'&&cp!='('&&cp!=')')     
     {
      word[i++]=cp;
      cp=fgetc(in);
     }
     word[i]='/0';
     fprintf(out,"%s%c%s%c%s/n","error: ",'"',word,'"',"不是合法的标识符");
   }
   continue;
  }

  /*运算符*/
  if(cp=='+')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',9,')');
   cp=fgetc(in);
   continue;
  }
  if(cp=='-')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',10,')');
   cp=fgetc(in);
   continue;
  }
  if(cp=='*')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',11,')');
   cp=fgetc(in);
   continue;
  }
  if(cp=='/')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',12,')');
   cp=fgetc(in);
   continue;
  }
  if(cp=='=')
  {
   word[i++]=cp;
   cp=fgetc(in);
   if(cp=='=')
   {
    word[i++]=cp;
    word[i]='/0';
    fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',17,')');
    cp=fgetc(in);
   }
   else
   {
    word[i]='/0';
    fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',8,')');
   }
   continue;
  }
  if(cp=='<')
  {
   word[i++]=cp;
   cp=fgetc(in);
   if(cp=='=')
   {
    word[i++]=cp;
    word[i]='/0';
    fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',14,')');
    cp=fgetc(in);
   }
   else
   {
    word[i]='/0';
    fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',13,')');
   }
   continue;
  }
  if(cp=='>')
  {
   word[i++]=cp;
   cp=fgetc(in);
   if(cp=='=')
   {
    word[i++]=cp;
    word[i]='/0';
    fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',16,')');
    cp=fgetc(in);
   }
   else
   {
    word[i]='/0';
    fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',15,')');
   }
   continue;
  } 
  if(cp=='!')
  {
   word[i++]=cp;
   cp=fgetc(in);
   if(cp=='=')
   {
    word[i++]=cp;
    word[i]='/0';
    fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',18,')');
    cp=fgetc(in);
   }
   else
   {
    word[i]='/0';
    fprintf(out,"%s%c%s%c%s/n","error: ",'"',word,'"',"不是合法的标识符");
   }
   continue;
  }
  /*界符*/
  if(cp==';')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',19,')');
   cp=fgetc(in);
   continue;
  }
  if(cp==':')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',20,')');
   cp=fgetc(in);
   continue;
  }
  if(cp==',')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',21,')');
   cp=fgetc(in);
   continue;
  }
  if(cp=='{')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',22,')');
   cp=fgetc(in);
   continue;
  }
  if(cp=='}')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',23,')');
   cp=fgetc(in);
   continue;
  }
  if(cp=='[')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',24,')');
   cp=fgetc(in);
   continue;
  }
  if(cp==']')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',25,')');
   cp=fgetc(in);
   continue;
  }
  if(cp=='(')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',26,')');
   cp=fgetc(in);
   continue;
  }
  if(cp==')')
  {
   word[i++]=cp;
   word[i]='/0';
   fprintf(out,"%c%c%s%c,%d%c/n",'(','"',word,'"',27,')');
   cp=fgetc(in);
   continue;
  }
  /*不能识别的字符*/
  word[i++]=cp;
  cp=fgetc(in);
  word[i]='/0';
  fprintf(out,"%s%c%s%c%s/n","error: ",'"',word,'"',"不是合法的标识符");
 }

 fclose(in);
 fclose(out);
 printf("成功对in.txt文档内代码进行词法分析,分析结果保存在out.txt文档中/n");
 return 0;
}

以下为运行截图:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击