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

📄 1.cpp

📁 编制一个读单词过程
💻 CPP
字号:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define BUFFER_SIZE 1000	//表达式缓冲区大小
#define CHAR_NUMBER 5	//输入字符的种类
#define Wmaxlen 256    //标示符的最大长度
char Buffer[BUFFER_SIZE];	//表达式缓冲区,以'\0'表示结束
char scult[BUFFER_SIZE];
int ipBuffer = 0;		//表达式缓冲区当前位置序号
int ipscult = 0;
int n=0;
struct Fbuffer
{
	int num;  //num=1,2,3,4,5,6 1:基本保留字;2:标识符;3:常数;4:运算符;5:分隔符;6:其它
	char value[Wmaxlen];
	char error[Wmaxlen];//错误
}Fbuffer1[BUFFER_SIZE];       
int ipFBuffer=0;
char KEY[26][26]={{"auto"},{"case"},{"if"},{"char"},{"const"},{"continue"},
{"default"},{"double"},{"long"},{"register"},{"switch"},{"else"},{"int"},{"for"},
{"while"},{"do"},{"return"},{"break"},{"continue"},{"short"},{"signed"},{"sizeof"},
{"static"},{"struct"},{"volatile"},{"void"}};
//int KEY_NO=strlen(KEY);
char ch;	//存放取得的一个字符
//函数声明:
bool Run();	//对存储在缓冲区的一行字符串(以'#'结束)进行运行
void system();	//全局初始化
void input();//从键盘读入程序,存于表达式缓冲区Buffer[]中
	
char GetChar(char Buffer[BUFFER_SIZE]); //从缓冲区取一个字符,返回该字符的同时将它存于全局变量ch中
void scanner(char Buffer[BUFFER_SIZE]);//扫描程序
int pt(char ch);
void output();
void manalyse(char Buffer[BUFFER_SIZE]);//词法分析程序
void main()
{
	    system();
}		
void system()
{
	printf("============================================================================\n\n");
	printf("程序功能:从输入的源程序中,先对程序进行扫描,并进行词法分析和语法分析。\n");
    printf("          1-- 输入程序和打开源程序\n");
	printf("          2-- 程序扫描\n");
	printf("          3-- 词法分析\n");
	printf("          4-- 语法分析\n");
	printf("          5-- 退出\n");
	printf("============================================================================\n\n");
	int sys;
	bool exit=false,s1=false,s2=false,s3=false;
    while(true)
	{
		
	    printf("\n请输入数字1-5来选择功能:  ");
	    scanf("%d",&sys);
		    if ( !(sys>=1 && sys<=5))  
			{
			printf("你输入的数不正确:");
		    continue;
			}
		    switch (sys) 
			{
		      case	1:  
				  {
					  input();
					  s1=true;
					  break;
				  }

			  case  2:
				  {
					  if (!s1) 
					  {
						  printf("您还没有输入源程序!!");
						  break;
					  }
					  else  
					  {
						  scanner(Buffer);
					      s2=true;
					      break;
					  }
				  }
			  case  3:  
				  {
					  if (!s2) 
					  {
						  printf("建议你先扫描源程序!!");
						  break;
					  }
                      else
					  {
                          manalyse(Buffer);
						  break;
					  }
				  }
			  case  5:  exit=true;break;
			}
		    if (exit) break;
		
    }

}

void input()
{
    
	for (int i=0;i<=strlen(Buffer);i++)
		Buffer[i]='\0';
	ipFBuffer=0;
	printf("请输入以\"@\"号结束的程序:\n");
	ipBuffer = 0;	//初始化缓冲区指针
	while ((Buffer[ipBuffer]=getchar() )!='@')
	{
	   
		ipBuffer++;
	}

}            
void output()
{
	printf("\n------------------------源程序词法分析如下---------------------\n");
	  printf("%5s%16s%10s\n","类型值","数据类型","数据值");
	  for (int i=0;i<ipFBuffer;i++)
	   {
		//printf("%5d   ",i); 
		printf("%5d",Fbuffer1[i].num);
		switch(Fbuffer1[i].num)
		  {
			  case 1 : printf("      关键字      ");break;
	          case 2 : printf("      标识符      ");break;
              case 3 : printf("      常数        ");break;
	          case 4 : printf("      运算符      ");break;
	          case 5 : printf("      分隔符      ");break;
			  case 6 : printf("      其它        ");
		  }
		
		for (int j=0;j<=strlen(Fbuffer1[i].value);j++)
		        printf("%c",Fbuffer1[i].value[j]);
       
		printf("\n");
	   }
      
}
char GetChar(char Buffer[BUFFER_SIZE])
{
	
	if((ch = Buffer[ipBuffer]) != '@')
		ipBuffer ++; 
	return ch;
}


void scanner(char Buffer[BUFFER_SIZE])  //扫描程序,对它进行判断
{
	for (int j=0;j<=strlen(scult);j++)
		scult[j]='\0';

	printf("\n扫描源程序开始!!\n");

	ipBuffer=0;
	int flat;
	while (Buffer[ipBuffer]!='@')     //扫描注释, 去掉没用程序
    {
		if (Buffer[ipBuffer]=='/' && Buffer[ipBuffer+1]=='/')
		{
			while (Buffer[ipBuffer]!='\n')
			{
				Buffer[ipBuffer]=32;
                ipBuffer++;
			}
		}
		if  (Buffer[ipBuffer]=='/' && Buffer[ipBuffer+1]=='*')
		{
			while (!((Buffer[ipBuffer]='*') && (Buffer[ipBuffer+1]=='/')))
			{
				Buffer[ipBuffer]=32;
                ipBuffer++;
			}
             Buffer[ipBuffer]=32;
			 Buffer[ipBuffer+1]=32;
		}
         ipBuffer++;
}
	ipBuffer=0;              
    ch=GetChar(Buffer);
    flat=pt(ch);
		if (flat==5 || flat==0)      //扫描没用的字符
			printf("");
		else 
		{
			printf("%c",ch);
			scult[ipscult++]=ch;
		}
	
	while(ch!='@')              //将不同类型的这符用#号分开
	{
	    ch=GetChar(Buffer);
		if (ch=='@') 
			break;
		if (pt(ch)==5 || pt(ch)==0)
			printf("");
		else if (flat!=pt(ch) || (flat==3))   //pt(ch)!=1 && flat==pt(ch)
		{
			printf("%c%c",'#',ch);
			scult[ipscult++]='#';
            scult[ipscult++]=ch;

		}
		else if (flat==pt(ch) && flat==2)
		{
             printf("%c",ch);
			 scult[ipscult++]=ch;
		}
		else 
		{ 
			printf("%c",ch);
			scult[ipscult++]=ch;
		}
		flat=pt(ch);
	}

	scult[ipscult]='#';
	printf("\n扫描完成!!\n");


}

int pt(char ch)
{   

    if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'||ch>='0' && ch<='9'||ch==95)
          return 1;
	else if(ch==32)
		  return 0;
	else  if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='%'||ch=='>'||ch=='<'||ch=='='||ch=='!'||ch=='&'||ch=='~'||ch=='^')
		   return 2; //操作符
	else  if(ch==','||ch==';'||ch=='{'||ch=='}'||ch=='('||ch==')'||ch=='"'||ch=='['||ch==']')
		   return 3; //分隔符
       else  if (ch=='?'||ch==':')
	       return 4;  //条件运算符
	else   return 5;//没有用的字符
}




void manalyse(char Buffer[BUFFER_SIZE])//从缓冲区中取一个单词
{    
	//printf("%d",ipscult);
	//int scult=ipscult;
	ipscult=0;
    int k;//表示取出的字符放在单词数组的指针
    ipFBuffer=0;
	ipBuffer=0;
	Fbuffer1[ipFBuffer].num=1;      //预先定义的取出的单词的类型
    char Word[Wmaxlen];
        //scanner(Buffer);// 扫描程序去掉不能显示的字符
        ipBuffer=0; //使数组指针回到开始。
        char ch=GetChar(scult); //对扫描后的程序一个个字符取出。
    //int p=1;	//测试用的
    while(ch!='\0')
	{   
	  bool flag=false;//用来表示取出的单词是否为关键词,如果是则flag的值为true,否则为false
		//printf("第%d次\n",p++);//测试用的
	  if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z')//取出标识符或者是关键词
	  {
	    k=-1;       
		while(true)//取出的单词长度不超过Wmaxlen,如果超过,则其后的字符无效
		{  
			if((++k)<Wmaxlen)//(++k)为了使取出的单词最长为WMaxlen
			{
				 Word[k]=ch;
			     ch=GetChar(scult);
			}
            if  (!(ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'||ch>='0' && ch<='9'||ch=='_'))
			break; //如果取出的当前的字符不是字母或是数字,则此次取单词结束
		}
           
	          //printf("%c",Word[j]);
	       Word[++k]='\0';//以'\0'标识取出单词的结束,以方便后面的判断此单词是标识符还是关键词
		   for (int i=0;i<Wmaxlen;i++)//用来判断取出的当前单词是不是关键词
			if (strcmp(Word,KEY[i])==0)
			{ 
				flag=true;
				break;
			} 
			
            if  (flag) 
                Fbuffer1[ipFBuffer].num=1;  //如果是关键词,则把此单词的类型定义为1型
			else 
				Fbuffer1[ipFBuffer].num=2;   //否则是标识符,其类型为2
		   for (int j=0;j<=k;j++)
			   Fbuffer1[ipFBuffer].value[j]=Word[j];
		   ipFBuffer=ipFBuffer+1;   
	  }
	  
	  //printf("输出%c",ch);
    else if (ch>='0' && ch<='9')   //判断是不是为整数
	{   k=-1;
	    
		Word[++k]=ch;
		ch=GetChar(scult);
		while(true)//如果是数字,则一直接受,且定义它的类型为3
			if(ch>='0' && ch<='9')
			{
				Word[++k]=ch;
				ch=GetChar(scult);
			}
			else  //不是数字则跳出循环
			{
		    	Fbuffer1[ipFBuffer].num=3;
				for (int j=0;j<=k;j++)
			    Fbuffer1[ipFBuffer].value[j]=Word[j];
		           ipFBuffer=ipFBuffer+1; 
				break;}
	}
	else if (pt(ch)==2)//取出是运算符号的单词
	{   
		k=-1;
		Word[++k]=ch;
         ch=GetChar(scult);
		 while (ch!='#')
		 {
             Word[++k]=ch;
             ch=GetChar(scult);
		 }
         	Fbuffer1[ipFBuffer].num=4;
			for (int j=0;j<=k;j++)
			    Fbuffer1[ipFBuffer].value[j]=Word[j]; 
            ipFBuffer=ipFBuffer+1;
  
}
	else if (pt(ch)==3)//判断当前取出的单词是不是界符,如果是界符,则定义其类型为5
	{     
		
		Fbuffer1[ipFBuffer].num=5;
	    Fbuffer1[ipFBuffer].value[0]=ch; 
            ipFBuffer=ipFBuffer+1;
	}
	ch=GetChar(scult);
}

output();

}	

⌨️ 快捷键说明

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