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

📄 wanshang.cpp

📁 这是我同学做得编译原理——词法分析器
💻 CPP
字号:
#include<fstream.h>
#include <stdio.h>
#include <string.h>
#include <process.h>
FILE *keyword;//存放关键字
FILE *sourcefile;//存放源文件
char  shuzi[100][20];//存数字
char biaoshifu[100][20];//存标识符
int sz; //数字数组的下标
int bsf;//标识符数组的下标
int count=0;//记录错误个数
int line;//记录行数
void Isnumber(char c);
void Isalpha(char c);
void Isother(char c);
void error(int a);
void noblank( char &ch);
void isanotation(char ch);
void main()
{ cout<<"*************************欢迎使用词法分析器*********************"<<endl<<endl;
char filename[20];
cout<<"请输入要分析的文件路径:";
cin>>filename;
	char ch;
	sourcefile = fopen(filename,"r"); 
	if(sourcefile==NULL)cout<<"文件不存在!";
	ch=fgetc(sourcefile);
	if(ch=='\n')
		line++;
	while(ch!=EOF) 
	{
       noblank( ch ); //跳过回车,空格 
	    if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'||ch=='_'){Isalpha(ch);}
           else
         	{if(ch>='0'&&ch<='9'){Isnumber(ch);}
                    else     
					{if(ch=='/'){isanotation(ch);}
		               else{ Isother(ch);}
	                       
					}
		   }
	  ch=fgetc(sourcefile);
	  if(ch=='\n')line++;	
	}
	cout<<endl;
	//输出标识符表
	int i=0;
	cout<<"文件生成的标识符表"<<endl;
	for(;i<bsf;i++)
	cout<<i<<'\t'<<biaoshifu[i]<<endl;
	//输出常数表
	cout<<"文件生成的常数表"<<endl;
	for( i=0;i<sz;i++)
	cout<<i<<'\t'<<shuzi[i]<<endl;
}


void Isnumber(char c)
{  	ofstream outfile("aim.txt",ios::app);
	if (!outfile)
 {
  cerr<<"无法打开文件 "<<"aim.txt"<<" !!!"<<endl;
  exit(-1);
 }
	char arr[20];
    int i=0;
    arr[i]=c;
    c=fgetc(sourcefile);
	if(c=='\n')line++;//再读入下一个字符
    while(c>='0'&&c<='9')
	{
    arr[++i]=c;
    c=fgetc(sourcefile);
	if(c=='\n')line++;
    }
     if(c!='.')//如果当前读入的符号不为小数点,则常数读完毕,输出此常数
	{fseek(sourcefile,-1,SEEK_CUR);
    arr[++i]='\0';
			if(sz!=0)
			 { int j=0;
				   while(j<sz)
				   {if(strcmp(arr,shuzi[j])==0)break;
					else j++;
				   }
				   if(j>=sz)//"数字表未定义"
				   {
					strcpy(shuzi[sz],arr);   
					cout<<"("<<arr<<","<<sz<<")"<<" ";
						outfile<<"("<<arr<<","<<sz<<")"<<" ";
					sz++;
				   }
				   else //定义输出位置
				   {cout<<"("<<arr<<","<<j<<")"<<" ";
				   outfile<<"("<<arr<<","<<j<<")"<<" ";
				   }
			  }
	         else
			 {  strcpy(shuzi[sz],arr);
	           cout<<"("<<arr<<","<<sz<<")"<<" ";
			   outfile<<"("<<arr<<","<<sz<<")"<<" ";
	            sz++;
			 }	
	 }
    else//当前字符为小数点则继续向下读入
	{
       arr[++i]=c;
       c=fgetc(sourcefile);if(c=='\n')line++;
       while(c>='0'&&c<='9')
	   {
       arr[++i]=c;
       c=fgetc(sourcefile);
	   if(c=='\n')line++;
	   }
	   fseek(sourcefile,-1,SEEK_CUR);
	   arr[++i]='\0';
        if(sz!=0)
		{ int j=0;
			 while(j<sz)
			 {if(strcmp(arr,shuzi[j])==0)
			   break;
			    else j++;
			 }
			if(j>=sz)
			{
					strcpy(shuzi[sz],arr);  
					cout<<"(num,"<<sz<<")"<<" ";
				outfile<<"(num,"<<sz<<")"<<" ";
					sz++;
					
			}
			 else 
			 {cout<<"(num,"<<j<<")"<<" ";
			 outfile<<"(num,"<<j<<")"<<" ";
			 }
		}
     else
	 {  strcpy(shuzi[sz],arr);
	           cout<<"(num,"<<sz<<")"<<" ";
			    outfile<<"(num,"<<sz<<")"<<" ";
	            sz++;
	 }
	}
}  

void Isalpha(char c)
{   
    keyword = fopen("D:keyword.txt","r");
	ofstream outfile("aim.txt",ios::app);//追加方式打开
	if (!outfile)
 {
  cerr<<"无法打开文件 "<<"aim.txt"<<" !!!"<<endl;
  exit(-1);
 }
	char arr[20];
    char temp[20];	
    int i=0; 
    arr[i]=c;
    c=fgetc(sourcefile);
	if(c=='\n')line++;
    while((c>='a'&&c<='z')||(c>='0'&&c<='9')||(c>='A'&&c<='Z'))
			 {
				arr[++i]=c;
				c=fgetc(sourcefile);
				if(c=='\n')line++;
			 }
	 arr[++i]='\0';
	 fseek(sourcefile,-1,SEEK_CUR);
	 
//把字符数组arr和关键字表比较,判断单词串是关键字还是标识符 
	  c=fgetc(keyword);
	  i=0;
   	while(c!=EOF)
	{ 
		while(c!='\n') 
		{ 
			temp[i++]=c; 
		 c=fgetc(keyword); 
		} 
		temp[i]='\0'; 
		i=0;  
		if(strcmp(temp,arr)==0) 
		{ cout<<"("<<arr<<",-)"<<" ";
			outfile<<"("<<arr<<",-)";
			return; /*若找到,退出函数*/ 
		
		} 
		else 
			 c=fgetc(keyword); 
	} //结束外层while循环
	
    if(bsf!=0)
	{ int j=0;
		while(j<bsf)
		 {if(strcmp(arr,biaoshifu[j])==0)
		     break;
		  else j++;
		}
		if(j>=bsf)//"标识符表未定义"
		{
			strcpy(biaoshifu[bsf],arr);   
			cout<<"("<<"id"<<","<<bsf<<")"<<" ";
			outfile<<"("<<"id"<<","<<bsf<<")";
			bsf++;
		}
		else 
		{cout<<"("<<"id"<<","<<j<<")"<<" ";
		outfile<<"("<<"id"<<","<<bsf<<")";
		}
	}
 else
 {  strcpy(biaoshifu[bsf],arr);
	cout<<"("<<arr<<","<<bsf<<")";
	outfile<<"("<<"id"<<","<<bsf<<")";
	bsf++;
	}outfile.close();
}



void Isother(char ch)
{   ofstream outfile("aim.txt",ios::app);
	if (!outfile)
 {
  cerr<<"无法打开文件 "<<"aim.txt"<<" !!!"<<endl;
  exit(-1);
 }
	switch(ch){
	case '(':cout<<"((,-)"<<" ";
		outfile<<"((,-)"<<" ";
			break;
	case ')':cout<<"(),-)"<<" ";
		outfile<<"(),-)"<<" ";
			break;
	case '[':cout<<"([,-)"<<" ";
		outfile<<"([,-)"<<" ";
			break;
	case ']':cout<<"(],-)"<<" ";
		outfile<<"(],-)"<<" ";
			break;
	case '*':ch=fgetc(sourcefile);
		    if(ch=='\n')line++;
		      if(ch=='=')
			  {cout<<"(*=,-)"<<" ";
			  outfile<<"(*=,-)"<<" ";}
			  else{ cout<<"(*,-)"<<" ";
			  fseek(sourcefile,-1,SEEK_CUR);
			  outfile<<"(*,-)"<<" ";}
			  break;
	case '+':ch=fgetc(sourcefile);
		   if(ch=='\n')line++;
		      if(ch=='=')
			  {cout<<"(+=,-)";
			  outfile<<"(+=,-)"<<" ";
			  }
			  else 
			  {cout<<"(+,-)";
			  fseek(sourcefile,-1,SEEK_CUR);
			   outfile<<"(+,-)"<<" ";
			  }
			  break;
	case ',':cout<<"(,,-)";
		   outfile<<"(,,-)"<<" ";
			break;
	case '-':ch=fgetc(sourcefile);
		if(ch=='\n')line++;
		      if(ch=='=')
			  { cout<<"(-=,-)";
			  outfile<<"(-=,-)"<<" ";
			  }
			  else {cout<<"(-,-)";
			  fseek(sourcefile,-1,SEEK_CUR);
			  outfile<<"(-,-)"<<" ";}
			break;
	case '.':cout<<"(.,-)";
		outfile<<"(.,-)"<<" ";
			break;
	case ':': cout<<"(:,-)";
		   outfile<<"(:,-)"<<" ";
			break;
	case ';':cout<<"(;,-)"<<" ";
			outfile<<"(;,-)"<<" ";
			break;
	case '<': ch=fgetc(sourcefile);
		     if(ch=='\n')line++;
		      if(ch=='=')
			  {cout<<"(rlop,-)";
			  outfile<<"(rlop,-)"<<" ";
			  }
			  else {cout<<"(rlop,-)"<<" ";
			  fseek(sourcefile,-1,SEEK_CUR);
			  outfile<<"(rlop,-)"<<" ";
			  }
			break;
	case '=':ch=fgetc(sourcefile);
		     if(ch=='\n')line++;
		      if(ch=='=')
		     cout<<"(==,-)"<<" ";
			  else {fseek(sourcefile,-1,SEEK_CUR);
				  cout<<"(=,-)"<<" ";
				   outfile<<"(=,-)"<<" ";
			  }
			break;
	case '>': ch=fgetc(sourcefile);
		     if(ch=='\n')line++;
		      if(ch=='=')
			  { cout<<"(rlop,-)";
			  outfile<<"(rlop,-)"<<" ";
			  }
			  else { fseek(sourcefile,-1,SEEK_CUR);
				  cout<<"(rlop,-)"<<" ";
			  outfile<<"(rlop,-)"<<" ";
			  }
			break;
	case '%':ch=fgetc(sourcefile);
		     if(ch=='\n')line++;
		      if(ch=='=')
			  { cout<<"(%=,-)";
			  outfile<<"(%=,-)"<<" ";
			  }
			  else { fseek(sourcefile,-1,SEEK_CUR);
				  cout<<"(%,-)"<<" ";
			  outfile<<"(%,-)"<<" ";
			  }
			break;
	case '!':ch=fgetc(sourcefile);
		     if(ch=='\n')line++;
		      if(ch=='=')
			  { cout<<"(!=,-)";
			  outfile<<"(!=,-)"<<" ";
			  }
			  else { fseek(sourcefile,-1,SEEK_CUR);
				  cout<<"(not,-)"<<" ";
			  outfile<<"(not,-)"<<" ";
			  }
			break;
	case '|':ch=fgetc(sourcefile);
		     if(ch=='\n')line++;
		      if(ch=='|')
			  { cout<<"(or,-)";
			  outfile<<"(or,-)"<<" ";
			  }
			  else { fseek(sourcefile,-1,SEEK_CUR);
				  error(1);
			  }
			break;
	case '&':ch=fgetc(sourcefile);
		     if(ch=='\n')line++;
		      if(ch=='&')
			  { cout<<"(and,-)";
			  outfile<<"(and,-)"<<" ";
			  }
			  else { fseek(sourcefile,-1,SEEK_CUR);
				  error(1);
			  }
			break;
	default:error(1);	
			break;
	}
outfile.close();
}


void isanotation(char ch)
{  ofstream outfile("aim.txt",ios::app);
	if (!outfile)
 {
  cerr<<"无法打开文件 "<<"aim.txt"<<" !!!"<<endl;
  exit(-1);
 }
	ch=fgetc(sourcefile);
	if(ch=='\n')line++;
		else   if(ch=='=')
		   {cout<<"(/=,-)"<<" ";}
			else  if(ch=='*')		
					for(;;)
					{
						ch=fgetc(sourcefile);
						//if(ch=='\n')line++;
						if(ch==EOF){error(2);break;}
						if(ch=='*')
						{
							ch=fgetc(sourcefile);
							if(ch=='/')
							{
								return;
							}
						}
					}
							else{ fseek(sourcefile,-1,SEEK_CUR);   /*不是注释,当作除号处理*/
							 cout<<"(/,-)"<<" ";
							 outfile<<"(/,-)"<<" ";
							}	
}




void error(int a)
{
	 count++;
	switch(a)
	{
	        case 1: cout<<"错误"<<count<<":第"<<line<<"行字符非法!"<<endl;break;
			case 2: cout<<"错误"<<count<<":第"<<line<<"行没有匹配的*/"<<endl;break;
			default:break;
	}

}


void noblank( char &ch) //跳过空格,回车 
{
while(ch == ' ' || ch == '\n')
{ch = fgetc(sourcefile);
}
}

⌨️ 快捷键说明

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