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

📄 scanner.cpp

📁 这是一个scanner源程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			*Tail=Word[j];
			Tail++;
			c1++;
		}
		ENTRY=i+1;
		
	}
}



//取出一个字符
char Getch()
{ 
	int i;
	ch=Buffer[column];
	if(ch=='\n')//读入下一行
	{ 
		for(i=0;i<1000;i++) //清空缓冲区
			Buffer[i]='#';
		
		fgets(Buffer,n,fp1);
		row++;
		column=0;
	}
	else
	{
		if(!feof(fp1))//文件还没结束
	
		   column++;
		
		else return  -1;
	}
	return ch;
} 



//查找标识符
void checksign()
{
	int k=0,p=0,j=0;
	char *w;
	if(c==0)
	{
		c++;
		Tab[0].head=Tail;
		Tab[0].len=idlen+1;
		fprintf(fp3,"%d\t%d\t_\t_\t_\t_\t\n",c1,Tab[0].len);//fp3指向符号表
		
		for(k=0;k<=idlen;k++)
		{*Tail=Word[k];
		Tail++;
		c1++;
		}
		Tab[0].type[0]=Tab[0].kind[0]='v';
		ENTRY=1;
		return;
	}
	
	else
	{ //查找是否有同名项
		for(p=0;p<c;p++)
		{
			if(Tab[p].type[0]=='v')
			{
				w=Tab[p].head;
				for(j=0;j<=idlen;j++)
				{
					if(Word[j]==*w)
						w++;
					else break;
				} 
			}
			if(j==idlen+1)
				break;
		}
		
		if(j==idlen+1)
		{
			ENTRY=p+1;
			return;
		}
		
		else
		{//没有同名项
			
			while(Tab[p].type[0]!='#')
				p++;
			c++;
			
			Tab[p].len=idlen+1;
			Tab[p].head=Tail;
			fprintf(fp3,"%d\t%d\t_\t_\t_\t_\n",c1,Tab[p].len);
			Tab[p].type[0]=Tab[p].kind[0]='v';
			
			for(j=0;j<=idlen;j++)
			{
				*Tail=Word[j];
				c1++;
				Tail++;
			}
			
			ENTRY=p+1;
		} 
		
		//	return;
	}
	
}











//查找是否为关键字
int Checktab()
{
	int k=0,i;
	bool flag=false;
	while(k<33)  //种别码关键字最后一个为33
	{i=0;
	
	while (Word[i]!='#' && tolower(Word[i])==Simple[k].word[i])
		
	{
		i++;
	}
    if(i==idlen+1 && Simple[k].word[i]=='#' )
		  {
			  flag=true;
			  break;
		  }
    else k++;
		  
	}
	
	if(flag==true)
	{
		for(i=0;i<=idlen;i++)
		{  
			fprintf(fp2,"%c",Word[i]);
		}
		token.code=Simple[k].kindcode;
		token.addr=NULL;
		fprintf(fp2,"\t\t(%d\t_)\n",token.code);
		return OK;
		//break;
	}
	
	
	else return ERROR;
	
}

//查添符号表
void Lookup()
{
	int i;
	switch(kind)
	{
	case 1: checksign();//查找标识符
		for(i=0;i<=idlen;i++)
			fprintf(fp2,"%c",Word[i]);
		token.code=34;
		token.addr=ENTRY;
		fprintf(fp2,"\t\t(%d\t%d)\n",token.code,token.addr);
		break;
		
	case 2: checknum();break;//查找数字
		
		
		
		
	case 3: checkch();//查找字符常数
		for(i=0;i<=idlen;i++)
			fprintf(fp2,"%c",Word[i]);
		token.code=37;      //字符常数种别码为37
		token.addr=ENTRY;   //entry
		fprintf(fp2,"\t\t(%d\t%d)\n",token.code,token.addr);
		break;
	default:break;
	}
}


//识别标识符

void RECOGID()
{
	int i,k=0;
	for(i=0;i<80;i++)//初始化
		Word[i]='#';
	idlen=0;
	Word[idlen]=ch;  //ch字符常量或变量
	Getch();
	while(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'||ch>='0'&&ch<='9'&&ch!='\n')
	{
		idlen++;
		Word[idlen]=ch;
		Getch();
		if(ch=='\n')
			break;
	}
	if(ch!='\n')
		column--;
	if(Checktab()==ERROR)//如果不是关键字查添符号表
	
	{
		kind=1;
	    Lookup();
	}
}
  








//识别数字

void  RECODIG(){
	int j=0,count=0,a[10],k,x1=0,column1=0;
	for(k=0;k<80;k++)
		Num[k]=0;
	column1=column;
	numlen=0;
	Num[numlen]=ch-48;//将字符的ASCII码转化为数字
	Getch();
	while(ch>='0'&&ch<='9'||ch=='.'){
		numlen++;
		if(ch=='.'){
			Num[numlen]=ch;
			count++;
			a[j]=numlen;
			j++;}//if
		else
			Num[numlen]=ch-48;
		Getch();
	}//while
	if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')//若出现字母,则打印错误信息
		fprintf(fp5,"%d行%d列:出现非数字的字符\n",row,(column-1));
	column--;
    kind=2;
	if(count==0){         //若是整数
		token.code=35;
		Lookup();
		fprintf(fp2,"%d",int(num1));
		token.addr=ENTRY;
		fprintf(fp2,"\t\t(%d\t%d)\n",token.code,token.addr);
		 return;
	}//if
	else{//若是实数
		if(count==1){
			token.code=36;
			Lookup();
			fprintf(fp2,"%f",num1);
			token.addr=ENTRY;
			fprintf(fp2,"\t(%d\t%d)\n",token.code,token.addr);
			return;	
		}//if
		else{//若出现多个小数点,则打印错误信息
			fprintf(fp5,"%d 行 %d 列:有多余小数点\n",row,(column1+a[1]-1));
			for(k=0;k<=numlen;k++){
					if(Num[k]==46)
						fprintf(fp2,".");
					else
						fprintf(fp2,"%d",Num[k]);
				}//for
				//处理错误数字
		
			token.code=36;
			Lookup();
			token.addr=ENTRY;
			fprintf(fp2,"\t(%d\t%d)\n",token.code,token.addr);
			T=false;
			return;	
		}//else1;
	}//else2;
}//




//识别注释
void HANDLECOM()
{
	char  ch1;
	ch1=ch;
	Getch();
	
	if(ch!='*')             //是除号
	{
		column--;
		token.code=48;
		token.addr=NULL;
		fprintf(fp2,"%c",ch1);
		fprintf(fp2,"\t\t(%d\t_)\n",token.code); 
		return;
	}
	else                    //是注释
        token.code =-1;
	token.addr =NULL;
	Getch();
	while(ch!='\n')
	{
		ch1=ch;
		Getch();
		if(ch1=='*'&&ch=='/')
			token.code =0;
		//break;
	}
	if(token.code !=0)
	{ 
		fprintf(fp5,"%d 行:注释未完\n",row-1);
		T=false;
		//return;
	}
    token.code =0;
    token.addr =NULL;		
}


//识别字符常数
void RECOGSTR()
{
	int i;
	for(i=0;i<80;i++)//初始化
	{
		Word[i]='#';
	}
	idlen=-1;
	
	while(Getch()!=39)   //39 为ASCii “‘”,字符常数为‘a’
	{   idlen++;
		Word[idlen]=ch;
		if(idlen+1>=80)
		{
			fprintf(fp5,"%d行:字符常数没有封闭\n",row-1);  
			T=false;
			column--;
			break;
		}
	}
	
	kind=3;
	Lookup();
}



 //识别其它界符
void RECOGDEL()
{
	bool flag=false;//标记是否为双界符
	switch(ch) 
	{
	case'+':token.code=43;token.addr=NULL;break;
	case'-':token.code=45;token.addr=NULL;break;
	case'*':token.code=41;token.addr=NULL;break;
	case')':token.code=40;token.addr=NULL;break;
	case'(':token.code=39;token.addr=NULL;break;
	case',':token.code=44;token.addr=NULL;break;
	case'[':token.code=59;token.addr=NULL;break;
	case']':token.code=60;token.addr=NULL;break;
	case'=':token.code=56;token.addr=NULL;break;
	case';':token.code =52;token.addr=NULL;break;
	case'.':
		
		fprintf(fp2,"%c",ch);
		flag=true;
		Getch();
		if(ch=='.') 
		{
			token.code=47;
			token.addr=NULL;
			fprintf(fp2,"%c",ch);
		}
		else 
		{
			column--;token.code=46;
			token.addr=NULL;
		}
		
		break;
		
		
	case':':
		
		fprintf(fp2,"%c",ch);
		flag=true;
		Getch();
		if(ch=='=') 
		{ 
			token.code=51;
			token.addr=NULL;
			fprintf(fp2,"%c",ch);
			
		}
		else 
		{ 
			column--; 
			token.code=50;
			token.addr=NULL;
		}
		
		break;
		
		
	case'<':
		
		fprintf(fp2,"%c",ch);
		flag=true;
		Getch();
		if(ch=='=')  
		{
			token.code=54;
			token.addr=NULL;
			fprintf(fp2,"%c",ch);
			
		}
		else if(ch=='>')  
		{
			token.code=55;
			token.addr=NULL;
			fprintf(fp2,"%c",ch);
		}
		else 
		{
			column--;
			token.code=53;
			token.addr=NULL;
		}
		
		break;
		
		
	case '>':
		
		fprintf(fp2,"%c",ch);
		flag=true;
		Getch();
		if(ch=='=') 
		{
			
			token.code=58;token.addr=NULL;
			fprintf(fp2,"%c",ch);
		}
		else 
		{
			column--;
			token.code=57;token.addr=NULL;
			
		}
		
		break;
		
	default:if(ch==' ')
			{//若是空格,继续读入
				do Getch();
				while (ch==' ');
				column--;
				return;
			}
		   else 
		   {
			  if(ch=='\n')
				 return;
			  else 
			{
				fprintf(fp5,"%d 行 %d 列:有非法字符\n",row,column);
				T=false;
				return;
			}
			
		}	
       // break;    
 }	
	
	
	if(flag==false)
	{
		fprintf(fp2,"%c",ch);
	}
	fprintf(fp2,"\t\t(%d\t_)\n",token.code);
	//break;
	
	
 }

 
 
 //单词分类模块

void Sort()
{
	if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')    
		RECOGID();//识别标识符
	else if(ch>='0'&&ch<='9')                      
        RECODIG();//识别数字
	else if(ch=='/')                               
		HANDLECOM();//识别注释
	else if(ch==39)                               
		RECOGSTR();//识别字符常数
	else                                     
		RECOGDEL();//识别其它界符
}



void main()
{
	int i;        
	char  file[20];
	printf("请输入源文件名,包括后缀名:\n");
	scanf("%s",&file);
	if((fp1=fopen(file,"r"))==NULL)
	{
		printf("不能打开file文件\n");
		return;
	}
	
	if((fp2=fopen("token串.txt","w+"))==NULL)
	{
		printf("不能建立token串文件");
		return;
	}
	
	if((fp3=fopen("符号表.txt","w+"))==NULL)
	{
		printf("不能建立符号表文件");
		return ;
	}
	
	if((fp4=fopen("源程序清单.txt","w+"))==NULL)
	{
		printf("不能建立字符串表");
		return;
	}
	
	if((fp5=fopen("错误信息.txt", "w+"))==NULL)
	{
		printf("不能建立错误信息表");
		return ;
	}
	fprintf(fp2,"\t\t\t\ttoken串\t\t\t\t\n\n\n");
	fprintf(fp3,"head\tlength\ttype\tkind\tval\taddr\n");
	unit();
	fgets(Buffer,n,fp1);//从文件中读入一行到缓冲区
	row++;
	while(Getch()!=-1)
		Sort();
	fprintf(fp3,"\n\n\n");
	fprintf(fp3,"\t\t\t字符串表\n");
	for(i=0;String[i]!='#';i++)
		fprintf(fp3,"%c",String[i]);



    fclose(fp1);
	fclose(fp2);
	fclose(fp3);
	fclose(fp4);
	fclose(fp5);
	if (T==true)
	{
		printf("\n\n\n");
		printf("恭喜你,你的程序没有出错,请查看符号表文件,字符串表文件,token串文件\n");
	}
	else
	{
		printf("\n\n\n");
		printf("你的程序中有错误,请查看错误信息表\n");
	}
}
 

⌨️ 快捷键说明

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