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

📄 cifafenxi.cpp

📁 一个简单的词法分析器~~~~~~~~实现最简单的词法分析功能
💻 CPP
字号:
#include<string.h>
#include<iostream>
using namespace std;
#include<stdio.h>
#include <ctype.h>//包含大小写的头文件

int cmp_word(char *fword)// 初始化关键字的函数
{
	char *word[13];//声明一个字符型的数组指针
	word[1]="else";//设置保留字
	word[2]="if";
	word[3]="int";
	word[4]="return";
	word[5]="void";
	word[6]="while";
	
	int n,i;
	for(i=1;i<7;i++)
	{
	n=strcmp(fword,word[i]);//两个字符串相等返回0,第一个大于第二个返回>0的数,否则返回<0的数
	if(n==0){break;}//两个串相等直接中断
	}
	if(n==0){return i;}
	else{return 0;}

	
}

void save_word(int i,FILE *fw)
{
    char *word[13];
	word[1]="else";
	word[2]="if";
	word[3]="end";
	word[4]="then";
	word[5]="for";
	word[6]="while";
    word[7]="begin"
	word[8]="to"
	word[9]="do"
	word[10]="not"
	word[11]="and"
	word[12]="or"

	//设置保留字类型
	char *wordsym[13];
	wordsym[1]="elsesym";
	wordsym[2]="ifsym";
	wordsym[3]="endsym";
	wordsym[4]="thensym";
	wordsym[5]="forsym";
	wordsym[6]="whilesym";

    
	fputc('(',fw);
	cout<<'(';
	fputs(word[i],fw);
	cout<<word[i];
	fputs("          ",fw);
	cout<<"          ";
	fputs(wordsym[i],fw);
	cout<<wordsym[i];
	fputs(")\n",fw); //fputc(),fputs()分别是将字符,字符串写入一个文件中
	cout<<")\n";

}



int ident_numbers(char fword[], int i, int n)//给函数的作用是判读一个字符串中有多少个连续的字母i表示
{
   int m=n+1;	                            //数组fword[]的长度,n表示当前所读的字符的位置
   while(m<i)
   {
	   if(isupper(fword[m])||islower(fword[m]))
	   {
		   m++;
	   }
	   else{break;}
   }
   return m;
}



void save_ident(char ch[],FILE *fw,int n)//保留标识符的函数
{
   fputc('(',fw);
   cout<<'(';
   if(n>1){fputs(ch,fw);cout<<ch;}
   if(n==1){fputc(ch[0],fw);cout<<ch[0];}
   fputs("          ",fw);
   cout<<"          ";
   fputs("ident)\n",fw);
   cout<<"ident)\n";
}




int Numbers(char fword[],int i,int n)//判断有多少个连续的0-9的无符号整数
{
	int m=n+1;
	while(m<i)
	{
		if(isdigit(fword[m])){m++;}
		else{break;}
	}
	return m;
}


void save_Numbers(char fwordTwo[],FILE *fw,int length)//保存无符号整数
{
	fputc('(',fw);
	cout<<'(';

	for(int l=0;l<length;l++)
	{
		fputc(fwordTwo[l],fw);
		cout<<fwordTwo[l];
	}
	fputs("         ",fw);
	cout<<"         ";
	fputs("Number",fw);
	cout<<"Number";
	fputs(")\n",fw);
	cout<<")\n";
}


int ssym_Numbers(char fword[],int i,int n)//判断有多少个界符和运算符,一般不会超过两个,n表示起始位置
{
	int m=n+1;
	while(m<i)
	{
		if(isupper(fword[m])||islower(fword[m])||isdigit(fword[m])){break;}
		else{m++;}
	}
	return m;//m表示界符和运算符的个数
}



int getssym(char b[])  //取界符和运算符,两个放在一起了,也可以分开
{
	char ssym[17];
	ssym[1]='+';  ssym[2]='-';  ssym[3]='*';  ssym[4]='/'; 
	ssym[5]='<';  ssym[6]='>';  ssym[7]='=';  ssym[8]=';'; 
	ssym[9]=',';  ssym[10]='('; ssym[11]=')'; ssym[12]='['; 
	ssym[13]=']'; ssym[14]='{'; ssym[15]='}'; ssym[16]='!'; 

	int i;
	int n=1;
	for (i=1;i<17;i++)
	{
		if(b[0]==ssym[i]){n=0;break;}
	
	}
	if(n==0)
	{
		if(b[0]==':'&&b[1]=='='){i=16;}
		if(b[0]=='<'&&b[1]=='>'){i=17;}
		if(b[0]=='<'&&b[1]=='='){i=18;}
		if(b[0]=='>'&&b[1]=='='){i=19;}
        if(b[0]=='/'&&b[1]=='*'){i=20;}
		if(b[0]=='*'&&b[1]=='/'){i=21;}
		return i;
	}
	else{return 0;}
	
}


void savessym(int i ,FILE *fw)
{
	char *ssym[22];
	ssym[1]="+";   ssym[2]="-";   ssym[3]="*";   ssym[4]="/"; 
	ssym[5]="<";   ssym[6]=">";   ssym[7]="=";   ssym[8]=";"; 
	ssym[9]=",";   ssym[10]="(";  ssym[11]=")";  ssym[12]="[";
	ssym[13]="]";  ssym[14]="{";  ssym[15]="}";  ssym[16]="<>"; 
	ssym[17]=":="; ssym[18]="<="; ssym[19]=">="; ssym[20]="/*";
	ssym[21]="*/";

	char *rsym[22];
	rsym[1]="plus";    rsym[2]="minus";      rsym[3]="times";
	rsym[4]="slash";   rsym[5]="less";       rsym[6]="more"; 
	rsym[7]="geql";     rsym[8]="semicolon";  rsym[9]="comma";
	rsym[10]="lparen"; rsym[11]="rparen";    rsym[12]="lspbr"; 
	rsym[13]="rspbr";  rsym[14]="lswne";     rsym[15]="rswne"; 
	rsym[16]="ueql";   rsym[17]="eql";       rsym[18]="leql";
	rsym[19]="meql";   rsym[20]="lnote";     rsym[21]="rnote"; 
	fputc('(',fw);
	cout<<'(';
	fputs(ssym[i],fw);
	cout<<ssym[i];
	fputs("                 ",fw);
	cout<<"                 ";
	fputs(rsym[i],fw);
	cout<<rsym[i];
	fputs(")\n",fw);
	cout<<")\n";

}


void main()
{
    
	FILE *fr,*fw;                         //声明两个文件指针,因为任何对文件的操作都是通过文件指针来实现的
	char Fname[10],fword[30],fwordTwo[20];             //此处声明一个字符数组存放文件名
    char ch;
	int L=1;                              //L表示字符所处的
	

	cout<<"Please enter your filename:"<<endl;
	cin>>Fname; 
	fr=fopen(Fname,"rt");                 //以读的方式打开所输入的文件,指针fr指向该文件
    cout<<"Please enter a new filename you want to put up:"<<endl;
	cin>>Fname;
	fw=fopen(Fname,"wt"); //以写的方式建立一个txt文件,指针fw指向该文件
    cout<<"################";
   	cout<<"Intepreting! Waiting Please!!"; //系统函数fgetc()读取所输入文件的字符保存在字符变量ch中	                              
   cout<<"#################"<<endl;
	
	while(1)
  {
     int i=0,n=0,m=0,p=0,r=0,length=0;
	 ch=fgetc(fr);
	 if(ch=='\n'){L++;}
	 if(ch==-1){ break;}
	 while((ch!=' ')&&(ch!='\n'))         //将文件中连续的字符存入数组fword[]中
	 {	 
         fword[i]=ch;
		 i++;
	     if(i>30){ cout<<"单词长度大于数组长度,数组越界,请增加数组的长度"<<endl;break;}
		 ch=fgetc(fr);
		 if(ch==-1){ break;}
	 }                                     //注意:i的值比字符长度大1
                                           //while语句把连续的字符读完后,接下来的第一个可能是空格,也可能是换行
	 fword[i]=0;                          //字符串结束标志,必须加这一句,否则无法得到正确的结果
     if(ch=='\n'){L++;}                   //如果是换行的话,行标志加1
	
	//接下来是判断所读的字符序列似乎属于哪一种,首先判断是不是保留字,其次是标识符,界符,运算符,无符号整数,用if语句实现
       
	 if((r=cmp_word(fword))!=0) {save_word(r,fw);continue;}
	 else
	 {
		 while(n<i)
		 {
			 if(isupper(fword[n])||islower(fword[n]))
			 {
				 m=ident_numbers(fword,i,n); //字母终结位置
				 length=m-n;                //字母个数
				 for(p=0;p<length;p++,n++)
				 {
					 fwordTwo[p]=fword[n]; //将字符串存放在另外一个数组里
				 }
               fwordTwo[++p]=0;           //字符串结束标志
			   if((r=cmp_word(fwordTwo))!=0){save_word(r,fw);n=m;continue;}
			   else{save_ident(fwordTwo,fw,length);n=m;continue;}  //不是关键字就是标识符了

			 }

			 if(isdigit(fword[n]))
			 {
				 m=Numbers(fword,i,n);
				 length=m-n;
				 if(length<10)
				 {
					 for(p=0;p<length;p++,n++)
						 fwordTwo[p]=fword[n];
                     fwordTwo[++p]=0;
					 save_Numbers(fwordTwo,fw,length);
					 n=m;
					 continue;
				 }
				 else{cout<<"数组越界"<<endl;break;}
			 }

			 else
			 {
				 m=ssym_Numbers(fword,i,n);
				 length=m-n;
				 for(p=0;p<length;p++,n++)
					 fwordTwo[p]= fword[n];
				  fwordTwo[++p]=0;
				 if((r=getssym(fwordTwo))!=0)
				 {
				   savessym(r,fw);
				 }
                  n=m;
				  continue;
 			 }
			 
		 }
	 }
	
	}

  fclose(fr);
  fclose(fw);
  cout<<"编译结束"<<endl;
          

}

	

⌨️ 快捷键说明

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