www.pudn.com > wdj.rar > tt.cpp


#include  
#include  
#include  
 
#define  BMaxlen  10000     //定义缓冲区的最大长度 
#define  WMaxlen  11        //用来定义取出的标识符的最大长度,如果长度大于这个值,则接下去的字忽略不计 
#define  KEY_No    8        //定义要比较的关键字的个数 
#define  Sign_No  12      //定义要比较的符号的个数 
#define  Limit_No  6       //定义要比较的界符的个数 
#define  Maxtype  '5'       //定义单词的总类型共有5种 
#define  Longtype  '8'       //定义单词不合法且过长时的类型 
#define  Errtype  '7'       //定义单词不合法但没超过长度的类型 
 
 
int scanner();//用来从缓冲区中取一个字符 
void insource();//用来把文件中的内容放到缓冲区中 
char getsym();//从缓冲区中取一个单词 
 
using namespace std; 
char Str[BMaxlen];//建立缓冲区 
char Filename[100];//定义存放路径名的字符串 
int  pStr=-1;     //用来表示从缓冲区取字母时的指针,定义为-1,为使以下的程序++pStr可以先指到缓冲区的第一个字母 
char ch;        //用来表示从缓冲区中取出的一个字母 
char *KEY[KEY_No]={{"if"},{"int"},{"for"},{"while"},{"do"},{"return"},{"break"},{"continue"}}; 
char *Sign[Sign_No]={{"+"},{"-"},{"*"},{"/"},{"%"},{"="},{"<"},{">="},{"<="},{"!="},{"=="},{">"}}; 
char *Limit[Limit_No]={{","},{";"},{"{"},{"}"},{"("},{")"}}; 
int  Fbuffer;//标志缓冲区中是否还有字母,如果没有的话,则Fbuffer的值为-1;如果还有的话,则其值为1 
char Word[WMaxlen];//用来标识标识取出的单词,且其长度不超过 
char CType;//用来标识得到的单词的类型 
char Lasttype;//用来标识是其前面的单词的类型,如果是 
char ty;//定义在调用取单词后取出的单词的类型 
 
int scanner()//用来从缓冲区中取一个字符,如果成功,则返回1,否则为-1 
{  
	ch=Str[++pStr]; 
	if (ch=='\0') return(-1);//当取出的字符是'\0',则表明缓冲区中已无字符,返回值为-1 
	else return(1); 
} 
 
 
void insource()//用来把文件中的内容放到缓冲区中,以'\0'作为标识符 
{ 
	int i=0;//用来表示放入缓冲区数组的指针 
	char c; //表示从文件中读取的一个字符 
	fstream infile(Filename);//根据输入的路径名来打开这个文件 
	while (infile.get(c)) 
		Str[i++]=c; 
	Str[i]='\0'; //以'\0'作为标识符 
} 
 
 
char getsym()//从缓冲区中取一个单词 
{ 
	bool flag=false;//用来表示取出的单词是否为关键词,如果是则flag的值为true,否则为false 
	int k=-1;       //表示取出的字符放在单词数组的指针 
	CType='0';      //预先定义的取出的单词的类型 
	Lasttype='0';   //初始化先前的类型,此变量为判断正负数用 
	while (ch<=32 && ch>0)//去掉不能显示的字符 
		Fbuffer=scanner(); 
	if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z')//取出标识符或者是关键词 
	{ 
		k=-1; 
		while(true)//取出的单词长度不超过WMaxlen,如果超过,则其后的字符无效 
		{   
			if((++k)='a'&& ch<='z'|| ch>='A'&& ch<='Z'||ch>='0' && ch<='9')) 
				break;  
		} 
		Word[++k]='\0';//以'\0'标识取出单词的结束,以方便后面的判断此单词是标识符还是关键词 
		for (int i=0;i='0' && ch<='9')//判断是不是为整数 
	{   
		Word[++k]=ch; 
		Fbuffer=scanner(); 
		while(true)//如果是数字,则一直接受,且定义它的类型为3 
			if(ch>='0' && ch<='9') 
			{ 
				Word[++k]=ch; 
				Fbuffer=scanner(); 
			} 
			else  {CType='3';break;}//不是数字则跳出循环 
			//如果以字母开头,且长度不超过WMaxlen,且下面跟有字母,则此整数非法,输出类型为8,在主程序中输出出错信息 
			if (k='a'&& ch<='z'|| ch>='A'&& ch<='Z') 
				{ 
					Word[++k]=ch; 
					Fbuffer=scanner(); 
					//取这个非法整数的单词,其中可包含英文字母和数字 
					while (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'|| ch>='0' && ch<='9'||Fbuffer==-1) 
						if (kWMaxlen)//如果长度大于取出单词定义的最大长度,则返回类型为8,在主程序中打出出错信息 
							CType=Longtype; 
						else CType=Errtype;//否则返回类型7,在主程序出错,并明确写出此单词的具体内容 
		} 
			Word[++k]='\0';	 
	} 
	else if (ch=='+'||ch=='-'||ch=='*'||ch=='/')//取出是运算符号的单词 
	{    
		Word[++k]=ch; 
		if (ch=='+' || ch=='-')//如果是+号或者是-号,则还要判断是不是正负数 
			if (Lasttype=='6')//判断其取出的当前字母的前一个单词是6号类型的,即是<、>、<=、>=、==、=时则可判断现在取出的是整数 
			{	 
			 
				Fbuffer=scanner(); 
				while(ch>='0' && ch<='9')//取出整数 
				{ 
					Word[++k]=ch; 
					Fbuffer=scanner(); 
				} 
				CType='3';//如果正负整数,则直接返回类型为3,则表示此单词为整数 
				return(CType); 
          
			} 
			else Fbuffer=scanner();//如果不是整数,则定义当前取出的单词是运算符,定义此类型为4 
			Word[++k]='\0'; 
			CType='4'; 
	} 
	else if (ch=='>'||ch=='<'||ch=='='||ch=='!')//取出运算符的另几类,即<、<=、>、>=、==、=、!= 
	{     
		Word[++k]=ch;Fbuffer=scanner(); 
		if( ch=='=')//判断是不是<=、>=、==、!= 
		{  
			Word[++k]=ch; 
			Fbuffer=scanner(); 
		} 
		Word[++k]='\0'; 
		for (int i=0;i