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

📄 cpp1.cpp

📁 一个简单的C词法分析器
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
char set[100000],str[100000],strtoken[30];
char sign[50][10],constant[50][10];
char ch;
int sr,to,id=0,st=0;

void writo()
{
   FILE *fp;
   if((fp=fopen("analysis.txt","a"))==NULL)
   {
	printf("cannot write file. \n");
    getch();
    exit(0);
   }
    fputs(strtoken,fp);
    fputs("\n",fp);
    fclose(fp);
}

void buildfile()
{
   FILE *fp;
   if((fp=fopen("analysis.txt","w"))==NULL)
   {
	printf("cannot create file. \n");
    getch();
    exit(0);
   }
    fclose(fp);
}

typedef struct keytable    /*放置关键字*/
{
   char name[20];
   int  kind;
}
KEYTABLE;

KEYTABLE keyword[]={      /*设置关键字*/
                      {"void",0},
                      {"int",1},
                      {"float",2},
                      {"char",3},
                      {"if",4},
                      {"else",5},
                      {"for",6},
                      {"while",7},
                      {"do",8},
                      {"switch",9},
                      {"case",10},
                      {"break",11},
                      {"default",12},
					  {"return",13},
					  {"continue",14},
					  {"double",15},
					  {"enum",16},
					  {"extern",17},
					  {"long",18},
					  {"sizeof",19},
					  {"struct",20},
					  {"typedef",21},
					  {"union",22},
					  {"short",23},
					  {"auto",24},
					  {"signed",25},
					  {"unsigned",26},
					  {"union",27},
					  {"static",28},
					  {"main",29},
					  {"printf",30},
					  {"scanf",31},
                    };

void openfile()   /*打开文件*/
{
  FILE *fp;
  char a,filename[10];
  int n=0;
  printf("Input the filename:");
  gets(filename);
  if((fp=fopen(filename,"r"))==NULL)
    {
      printf("cannot open file.\n");
	  getch();
      exit(0);
    }
  else
      while(!feof(fp))  /*文件不结束,则循环*/
       {
         a=getc(fp);    /*getc函数带回一个字符,赋给a*/
         set[n]=a;      /*文件的每一个字符都放入set[]数组中*/
         n++;
       }
  fclose(fp);            /*关闭文件*/
  set[n-1]='\0';
  printf("\n=======================源代码==========================\n");
  puts(set);
  printf("\n=======================================================\n");
}

void reflesh()  /*清空strtoken数组*/
{
   to=0;   /*全局变量to是strtoken的指示器*/
   strcpy(strtoken," ");
}

void prearrange1()  /*预处理程序1*/
{
    int i,a,b,n=0;
    do
    {
        if(set[n]=='/' && set[n+1]=='*')
          {
             a=n;     /*记录第一个注释符的位置*/
             while(!(set[n]=='*' && set[n+1]=='/'))
                n++;
             b=n+1;    /*记录第二个注释符的位置*/
             for(i=a;i<=b;i++)   /**/
             set[i]=' ';   /*把注释的内容换成空格,等待第二步预处理*/
          }
        n++;
    }while(set[n]!='\0');
}

void prearrange2()   /*预处理程序2*/
{
    int j=0;
    sr=0;    /*全局变量sr是str[]的指示器*/
    do
    {
    if(set[j]==' ' || set[j]=='\n')
        {
           while(set[j]==' '|| set[j]=='\n') /*扫描到有连续的空格或换行符*/
                 j++;
           str[sr]=' ';    /*用一个空格代替扫描到的连续空格和换行符放入str[]*/
           sr++;

        }
    else
       {
         str[sr]=set[j];  /*若当前字符不为空格或换行符就直接放入str[]*/
         sr++;
         j++;
       }
    }while(set[j]!='\0');
    str[sr]='\0';
}

char getachar()    /*把字符读入全局变量ch中,指示器sr前移*/
{
   ch=str[sr];
   sr++;
   return(str[sr-1]);
}

void getbc()    /*开始读入符号,直至第一个不为空格*/
{
   while(ch==' ')
     {
        ch=getachar();
     }
}

void conacat()    /*把ch中的字符放入strtoken[]*/
{
   strtoken[to]=ch;
   to++;            /*全局变量to是strtoken的指示器*/
   strtoken[to]='\0';

}

int isletter()       /*判断是否为字母*/
{
   if((ch>=65 && ch<=90)||(ch>=97 && ch<=122))
     return(1);
   else return(0);
}

int isdigit()      /*判断是否为数字*/
{
   if(ch>=48 && ch<=57)
      return(1);
   else return(0);
}

int raserve()  /*对strtoken中的字符串查找保留字表,若是则返回它的编码,否则返回-1*/
{
   int i,k=0; 
   for(i=0;i<=30;i++)
     {
       if(strcmp(strtoken,keyword[i].name)==0)
         { k=1;
           
           return(keyword[i].kind);
         }
     }
   if(k!=1)
      return(-1);
}

void retur()  /*指示器sr回调一个字符位置,把ch置为空*/
{
   sr--;
   ch=' ';
}


void analysis()
{
    int value;
    reflesh();              /*清空strtoken数组*/ 
    prearrange1();          /*预处理,使注释内容换成单个空格,放回set[]中*/
    prearrange2();          /*预处理,使set[]中连续的空格置换成单个空格,并把set[]的内容放到str[]中*/
    sr=0;
    getachar();
    getbc();            /*读取第一个字符*/
    while(ch!='\0')      /*当不等于结束符,继续执行*/
    {
        if(isletter() || ch=='_')
        {
            while(isletter() || isdigit() || ch=='_')  /*若第一个是字符,继续读取,直到出现空格*/  
            {
                conacat();
                getachar();
            }
			if(ch=='.')
			{
				conacat();getachar();
                while(isletter() || isdigit())
				{
                conacat();
                getachar();
				}
			}
            retur();            /*指示器sr回调一个字符位置,把ch置为空*/            
            value=raserve();      /*对strtoken中的字符串查找保留字表,若是则返回它的编码,否则返回-1*/
            if(value==-1)        /*如果返回值是-1,那就是变量,把它输出*/
			{
                
				writo();
                printf("\n'%s':2'",strtoken);
                getch();
			} 
            else                            /*否则就是关键字,也输出*/  
			{ 
				writo();
                printf("\n'%s' : 1",strtoken);
                getch();
            }
            reflesh();
        }
        else if(isdigit())        
        {
            while(isdigit())      /*否则,若第一个是数字,继续读取,知道出现空格*/
            {
                conacat();
                getachar();
            }
            if(ch=='.')
			{ 
				conacat();
				getachar();
                while(isdigit())
				{
                conacat();
                getachar();
				}
			}
            retur();
            writo();
            printf("\n'%s':3",strtoken);
            getch();
            reflesh();
        }
        else
           switch(ch)              /*否则,若是下面的符号,就直接把它输出*/
        {
                        case ',':
                        case ';':
                        case '(':
                        case ')':
                        case '{':
                        case '}':
                        case '[':
                        case ']':
                        case '~':
                        case '#':
                        case ':':
                        case '^':
                        case '"':
						case '.':
							{ 
								conacat();
								writo();
                                printf("\n'%s':5",strtoken);
                                getch();
                                reflesh();
                                break;
							}
                        default:
							{
							   if(ch==' ') break;
                               else if(ch=='&' || ch=='|' )  /*如果是这些符号,继续读取下一个*/
                                {
                                   conacat();                     /*判断是否为&&,||的情况*/
                                   getachar();
                                   if(ch==strtoken[0])
                                      conacat();
                                   else
                                      retur();
								      writo();
                                      printf("\n'%s':4",strtoken);
                                      getch();
                                      reflesh();
                                      break;
                                }
                               else if( ch=='*' || ch=='%' || ch=='/')   /*如果是这些符号,继续读取下一个*/
                                {
                                   conacat();                    /*判断是否为/=,*=,%=的情况*/
                                   getachar();
                                   if(ch=='=')
                                      conacat();
                                   else
                                      retur();
								      writo();
                                      printf("\n'%s:4'",strtoken);
                                      getch();
                                      reflesh();
                                      break;
                                 }
							   else if(ch=='+' )            /*如果是这些符号,继续读取下一个*/                                     
								{  
								   conacat();                /*判断是否为+=,++,+的情况*/
								   getachar();
								   switch(ch)
								   {
								      case '=':{
										        conacat();
												writo();
											    printf("\n'%s:4'",strtoken);
                                                getch();
                                                reflesh();
												break;
											   }
								      case '+':{
										        conacat();
												writo();
										     	printf("\n'%s:4'",strtoken);
									            getch();
                                                reflesh(); 
												break;
											   }
									   default:{ 
										        retur();
												writo();
									            printf("\n'%s':4",strtoken);
                                                getch();
                                                reflesh();
                                                break;
											   }
								   }
								      break;
								
								 }
							   else if(ch=='-')             /*如果是这些符号,继续读取下一个*/ 
							    { 
                                  conacat();
								  getachar();
								  switch(ch)                  /*判断是否为-=,--,-的情况*/
								  {
								     case '=':{ 
										       conacat();
											   writo();
											   printf("\n'%s:4'",strtoken);
                                               getch();
                                               reflesh(); 
											   break;
											  }
								     case '-':{
										       conacat();
											   writo();
											   printf("\n'%s:4'",strtoken);
									           getch();
                                               reflesh(); 
											   break;
											  }
									  default:{ 
										       retur();
											   writo();
								               printf("\n'%s':4",strtoken);
                                               getch();
                                               reflesh();
                                               break;
											  }
								  }
								     break;
								}
						       else if(ch=='<')    /*如果是这些符号,继续读取下一个*/ 
								{
								   conacat();
								   getachar();
								   switch(ch)       /*判断是否为<<,<=,<的情况*/
								   {
								      case '=':{
										        conacat();
												writo();
											   	printf("\n'%s:6'",strtoken);
                                                getch();
                                                reflesh(); 
												break;
											   }
								      case '<':{
										        conacat();
												writo();
											    printf("\n'%s:4'",strtoken);
									            getch();
                                                reflesh(); 
												break;
											   }
								       default:{
										        retur();
												writo();
									            printf("\n'%s':6",strtoken);
                                                getch();
                                                reflesh();
                                                break;
											   }
								   }
								      break;
								}
							   else if(ch=='>')    /*如果是这些符号,继续读取下一个*/ 
								{
								   conacat();
								   getachar();
								   switch(ch)         /*判断是否为>>,>=,>的情况*/
								   {
								      case '=':{
										        conacat();
												writo();
											  	printf("\n'%s':6",strtoken);
                                                getch();
                                                reflesh(); 
												break;
											   }
								       case '>':{
										         conacat();
												 writo();
												 printf("\n'%s':4",strtoken);
									             getch();
                                                reflesh(); 
												 break;
												}
									    default:{  
											     retur(); 
												 writo();
                                                 printf("\n'%s:6'",strtoken);
                                                 getch();
                                                reflesh();
                                                 break;
												}
								   }
								       break;

								}
                               else if(ch=='=' || ch=='!' )  /*如果是这些符号,继续读取下一个*/
                                {
                                   conacat();                    /*判断是否为==,!=的情况*/
                                   getachar();
                                   if(ch==strtoken[0])
                                      conacat();
                                   else
                                      retur();
								      writo();
                                      printf("\n'%s':4",strtoken);
                                      getch();
                                      reflesh();
                                      break;
                                }
                              
							
                               else
                                {
                                  
                                       break;
                                }
                            }

        }
                getachar();
                getbc();
    }
}
  main()
{
 buildfile();
 openfile();
 analysis();
 printf("\n词法分析完毕 !");
 printf("\n词法分析结果已保存在analysis.txt中\n");
 getch();
 return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -