www.pudn.com > hsgbiyiyuanli.rar > cifa.h


 
 
/*==========================词法分析===========================*/ 
 
void scaner() 
 
{ 
	while( 1 ) 
	{ 
		head = readline(); 
			sort(); 
		if ( feof(in) ) 
			break; 
	} 
} 
 
void sort() 
 
{ 
	char c,nextc; 
	while (*head != '\0') 
	{ 
 
		while( isspace( *head ) || *head == '\t' ) 
		{ 
			head++; 
		} 
		c = fetch(); 
		if ( c == '@' )    // @代表没有取到缓冲区内容 
			break; 
		nextc = fetch();   // @代表没有取到缓冲区内容 
		if ( c =='+' || c=='-' ) 
		{ 
			if ( nextc == '@' )  //nextc没有取到缓冲区内容,c取的已经是最后1个 
			{ 
				unfetch(1);      //仅仅是指针退后,变量c中的内容不变。 
				symproces();      
			} 
			else			//nextc 取到缓冲区内容 
			{	 
				if ( isdigit( nextc ) )   //输入的将是数字 
				{ 
					unfetch( 2 );	//将c 和 nextc退入缓冲区; 
					dataproces(); 
				} 
				else 
				{ 
					unfetch( 2 );  //将nextc 退后 
					symproces(); 
				} 
			} 
		} 
		else if( isdigit( c ) ) 
		{ 
			if ( nextc == '@' )	//nextc没有取到缓冲区内容,c取的已经是缓冲区最后1个 
			{ 
				unfetch(1); 
				dataproces(); 
			} 
			else			//nextc 取到缓冲区内容 
			{ 
				unfetch(2); 
				dataproces(); 
			} 
		} 
		else if ( isalpha( c )) 
		{ 
			if ( nextc == '@' )	//nextc没有取到缓冲区内容,c取的已经是缓冲区最后1个 
			{ 
				unfetch(1); 
				alfaproces(); 
			} 
			else			//nextc 取到缓冲区内容 
			{ 
				unfetch(2); 
				alfaproces(); 
			} 
		} 
		else if(  c == '\'' && isalpha(nextc) )//字符常数 
		{ 
			unfetch(1); 
			char_process();	 
		} 
		else 
		{ 
			if ( nextc == '@' )	//nextc没有取到缓冲区内容,c取的已经是缓冲区最后1个 
			{ 
				unfetch(1); 
				symproces(); 
			} 
			else			//nextc 取到缓冲区内容 
			{ 
				unfetch(2); 
				symproces(); 
			} 
		} 
	} 
} 
 
 
char *readline()  //从文件中读取一行 
 
{ 
	char c =(char) fgetc(in); 
	unsigned int i = 0; 
	while(  c != '\n' && !feof(in)  ) 
	{ 
		if ( c == '@' ) 
			printf("\n\t @ is illegal charactor"); 
		else 
			newline[i++] = c; 
		c = (char)fgetc(in); 
	} 
	if( feof( in ) ) 
	{ 
		printf("\n\t the file has been end!\n"); 
 
	} 
 
	else if ( i >= MAXLEN) 
	{ 
		printf("\n\t too long word in a line!\n"); 
 
	} 
	newline[i] = '\0'; 
	return newline; 
} 
 
char fetch()  //从缓冲区中取字符 
{ 
	char c; 
	c = '@'; 
	if ( *head != '\0' ) 
	{ 
		c = *head++; 
	} 
	return c; 
} 
 
int unfetch(int n) 
 
{ 
	int i = 0; 
	while( i < n ) 
	{ 
		head--; 
		if ( head == newline ) 
		{	 
			break; 
		} 
		i++; 
	} 
	return 0; 
} 
 
 
void dataproces() 
{ 
	char s[25]; 
	int count = 0; 
	int d,d1,d2; 
	float f,f1,f2; 
	char c = fetch(); 
 
	if ( c == '+' || c == '-' ) 
	{ 
		s[count++] = c; 
		c = fetch(); 
	} 
	while( isdigit(c)) 
	{ 
		s[count++] = c; 
		c = fetch(); 
	} 
	if ( isspace( c ) ) 
	{ 
		s[count] = '\0'; 
		d = atoi(s); 
		d = fill_flagtab_int(d); 
		fprintf( out, "\n(%d,%d)", 35, d );	 
	} 
	else if ( isalpha( c ) )//接收的是字母 
	{ 
		if ( c == 'e' )      //带有指数 
		{ 
			d = atoi(s);		//前半部接收的是整数, 
 
			d1 = d; 
 
			c = fetch();  
 
			count = 0;  //继续接收后半部,将下标置为 0,以从缓冲头部开始存入 
			if (c == '+' || c == '-') 
			{ 
				s[count++] =c; 
				c = fetch(); 
			} 
			while( isdigit(c) ) 
			{ 
				s[count++] = c; 
				c = fetch(); 
			} 
			if ( isspace( c ) ) 
			{	 
				s[count] = '\0'; 
				d = atoi( s ); 
				d2 = d; 
				f = (float)pow(d1,d2); 
				d = fill_flagtab_float(f); 
				fprintf( out, "\n(%d,%d)", 36, d); 
			} 
			else if ( c == '.') 
			{ 
				s[count++] = c; 
				c = fetch(); 
 
				while( isdigit( c )) 
				{ 
					s[count++] = c; 
					c = fetch(); 
				} 
				unfetch(1); 
				s[count] = '\0';				  
				f = ( float ) atof(s); 
				f2 = f; 
				f = (float)pow(d1,f2); 
				d = fill_flagtab_float(f); 
				fprintf( out, "\n(36,%d)", d);			 
			} 
			else 
			{ 
				unfetch(1); 
				s[count] = '\0';				  
				d =  atoi(s); 
				d = fill_flagtab_int(d); 
				fprintf(out,"\n(35,%d)",d); 
			} 
		} 
		else  //所接收的字母不是 e,而是其他字母,则缓冲指针后退1个,且打印token 
		{	 
			unfetch(1); 
			s[count] = '\0'; 
			d = atoi( s ); 
			d = fill_flagtab_int(d); 
			fprintf( out, "\n(%d,%d)", 35, d );	 
		} 
	} 
 
	else if ( c == '.')   //前半部接收的将是实数 
	{ 
		s[count++] = c;	 
		c = fetch(); 
		while( isdigit(c)) 
		{ 
			s[count++] = c; 
			c = fetch(); 
		} 
		if ( isspace( c ) ) 
		{ 
			s[count] = '\0'; 
			f = (float)atof(s); 
			d = fill_flagtab_float(f); 
			fprintf( out, "\n(%d,%d)", 36, d ); 
		 
		} 
		else if( isalpha( c ) )//接收的是字母 
		{ 
			if ( c == 'e' )//带有指数 
			{ 
				f = ( float )atof(s); 
				f1 = f;  
 
				c = fetch(); 
		 
				count = 0;  //继续接收后半部,将下标置为 0,以从缓冲头部开始存入 
				 
				if ( c == '+' || c == '-' ) 
					s[count++] =c; 
 
				c = fetch(); 
 
				while( isdigit(c) ) 
				{ 
					s[count++] = c; 
					c = fetch(); 
				} 
				 
				if ( isspace( c ) ) 
				{	 
					s[count] = '\0'; 
					d = atoi( s ); 
					d2 = d; 
					f = (float)pow(f1,d2); 
					d = fill_flagtab_float(f); 
					fprintf( out, "\n(36,%d)", d );					 
				}	 
				else if ( c == '.')  //指数后半部为浮点数 
				{ 
					s[count] = '.'; 
 
					c = fetch(); 
 
					while( isdigit( c )) 
					{ 
						s[count++] = c; 
						c = fetch(); 
					} 
					 
					s[count] = '\0';				  
					f = ( float ) atof(s); 
					f2 = f; 
					f = (float)pow(f1,f2); 
					d = fill_flagtab_float(f); 
					fprintf(out,"\n(36,%d)",d); 
					unfetch(1); 
					 
				}		 
				else 
				{ 
					unfetch(1); 
					s[count] = '\0'; 
					d = atoi(s); 
					d2 = d; 
					f = (float)pow(f1,d2); 
					d = fill_flagtab_float(f); 
					fprintf( out, "\n(36,%d)", d ); 
				} 
			} 
			else    //不是指数标志e,而是其他字母则将浮点数打印,同时缓冲退1个 
			{	 
				s[count] = '\0'; 
				f = (float)atof( s ); 
				d = fill_flagtab_float(f); 
				fprintf( out, "\n(%d,%d)", 36, d ); 
				unfetch(1); 
			} 
	}		 
		else      //既不是数字,也不是字母,则将浮点数打印,同时缓冲退1个 
		{	 
			if ( c != '@' && !isspace( c ) ) 
			{ 
				unfetch(1); 
			} 
			s[count] = '\0'; 
			f = (float)atof( s ); 
			d = fill_flagtab_float(f); 
			fprintf( out, "\n(%d,%d)", 36, d ); 
		} 
	} 
	else      //既不是数字,也不是字母,也不是小数点,则为整数打印,同时缓冲退1个 
	{ 
		if ( c != '@' && !isspace( c ) ) 
		{ 
			unfetch(1); 
		} 
		s[count] = '\0'; 
		d = ( int )atoi( s ); 
		d = fill_flagtab_int(d); 
		fprintf( out, "\n(%d,%d)", 35, d ); 
	} 
} 
 
int char_process() 
{ 
	int i = 0; 
	char c,temp[6]; 
	while( (c = fetch()) != '\'') 
	{ 
		temp[i++] = c; 
	} 
	temp[i] = '\0'; 
	i = fill_flagtab_char( temp ); 
	fprintf(out,"\n(%d,%d)",37,i); 
	return 1; 
} 
 
int fill_flagtab_char(char *temp) 
{ 
	int i = 0; 
	FLAGTAB[f_amount].type = int_num; 
	while( temp[i] !='\0' ) 
	{ 
		FLAGTAB[f_amount].val.val_char[i] = temp[i++]; 
	} 
	f_amount++; 
	return f_amount - 1; 
} 
int fill_flagtab_int(int temp) 
{ 
	FLAGTAB[f_amount].type = int_num; 
	FLAGTAB[f_amount++].val.val_int = temp; 
	return f_amount - 1; 
} 
 
int fill_flagtab_float(float temp) 
{ 
	FLAGTAB[f_amount++].val.val_float = temp; 
	return f_amount - 1; 
} 
 
int fill_flagtab_bool(bool temp) 
{ 
	if (temp) 
		FLAGTAB[f_amount++].val.val_bool = true; 
	else 
		FLAGTAB[f_amount++].val.val_bool = false; 
	return f_amount - 1; 
} 
int symproces() 
 
{ 
	char c = fetch(); 
	char nextc; 
	short int  value = 0; 
	short int state = 0; 
	switch (c) 
	{ 
		case '\'': 
			value = 38; 
			state = 0; 
			break; 
		case '(': 
			value = 39; 
			state = 0; 
			break; 
		case ')': 
			value = 40; 
			state = 0; 
			break; 
		case '+': 
			value = 43; 
			state = 0; 
			break; 
		case ',': 
			value = 44; 
			state = 0; 
			break; 
		case '-': 
			value = 45; 
			state = 0; 
			break; 
		case ';': 
			value = 52; 
			state = 0; 
			break; 
		case '=': 
			value = 56; 
			state = 0; 
			break; 
		case '[': 
			value = 59; 
			state = 0; 
			break; 
		case ']': 
			value = 60; 
			state = 0; 
			break; 
		default: 
			state = 1; 
			break; 
	} 
	if ( state == 0 ) 
	{ 
		fprintf(out,"\n(%d,%c)",value,32); 
	} 
	else if ( state ==1 ) 
	{ 
		nextc = fetch(); 
		 
		if ( c == '.') 
		{ 
			if ( nextc == '.') 
				value = 47;  //   .. 
			else if ( nextc == '@')  
			{ 
				value = 46; 
			} 
			else 
			{ 
				unfetch(1);   //从@回退到.(从nextc回退) 
				value = 46; 
			} 
		} 
		else if ( c == '/') 
		{ 
 
			if ( nextc == '*') 
			{ 
				value = 49; 
				while ( *head != '\0' )  //检验 /* & */  的封闭性 
				{ 
					if( *head++ == '*' && *head =='/') 
					{ 
						value = 42; 
						head++; 
						return 0; 
					} 
				} 
				if ( *head == '\0') 
				{	 
					printf(" /*  &  */ is not fit"); 
					return 0; 
				} 
			} 
			else if ( nextc == '@') 
			{ 
				value = 48; 
			} 
			else 
			{ 
				unfetch(1); 
				value = 48; 
			} 
		} 
		else if ( c == '*') 
		{		 
			if (nextc == '/') 
			{ 
				value = 42; 
			} 
			else if ( nextc == '@') 
				value = 41; 
			else 
			{ 
				ungetch(1); 
				value = 41; 
			} 
		 
		} 
		else if ( c == ':' ) 
		{ 
			if ( nextc == '=' ) 
				value = 51; 
			else if ( nextc == '@') 
			{ 
				value = 50; 
			} 
			else 
			{ 
				unfetch(1); 
				value = 50; 
			} 
		} 
		else if ( c == '<') 
		{ 
			if ( nextc == '=') 
				value = 54; 
			else if (nextc == '>') 
				value =55; 
			else if ( nextc == '@') 
			{ 
				value = 53; 
			} 
			else 
			{ 
				unfetch(1); 
				value = 53; 
			} 
		} 
		else if ( c == '>') 
		{ 
			if ( nextc == '=' ) 
				value =58; 
			else if ( nextc == '@') 
			{ 
				value = 57; 
			} 
			else 
			{ 
				unfetch (1); 
				value = 57; 
			} 
		} 
		if ( value == 0 )				//非法字符 
		{ 
			printf("illegal alpha"); 
		} 
		else 
			fprintf(out,"\n(%d,%c)",value,32); 
	} 
	return 0; 
} 
 
void alfaproces() 
{ 
	char c = fetch(); 
	short unsigned int i = 0; 
	char s[SIZE]; 
	int ID = 0; 
	while( isalpha (c) || isdigit( c ) ) 
	{ 
		s[i++] = c; 
		if ( i > SIZE  ) 
		{ 
			printf("\n\t the length of flag can't beyond 10\n"); 
			break; 
		} 
		c = fetch(); 
 
	} 
	s[i] = '\0'; 
	if (  c!= '@' && !isspace( c ) ) 
	{ 
		unfetch(1); 
	} 
	ID = searchkeyID(s); 
	if ( !ID ) 
	{ 
		searchflag(s); 
	} 
	else 
	{ 
		fprintf(out,"\n(%d,%c)",ID,32); 
	} 
} 
 
int searchkeyID(char *s) 
{ 
	int left = 0 ; 
	int right = 32; 
	int midle = 0; 
	while( left <= right ) 
	{	 
		midle = (left + right)/2; 
		if ( strcmp(s,keyword[midle].word) < 0) 
		{    
				right = midle - 1; 
		} 
		else if ( strcmp(s,keyword[midle].word) > 0 ) 
		{ 
			left = midle + 1; 
		} 
		else 
		{	 
			break; 
		}		 
	} 
	if (left > right) 
		return 0; 
	else 
		return keyword[midle].ID; 
} 
 
 
void searchflag( char *s ) 
{ 
	short unsigned int i = 0; 
 
	while ( i < f_amount ) 
	{ 
		 if( !strcmp (s,FLAGTAB[i].name ) )  //找到标示符 
		 { 
			 fprintf(out,"\n(%d,%d)",34,i); 
			 break; 
		 } 
		 else 
		 { 
			i++; 
		 } 
	} 
	if ( i >= f_amount )//没有找到标示符 
	{ 
		strcpy( FLAGTAB[i].name, s ); //插入 
		f_amount++; 
		fprintf(out,"\n(%d,%d)",34,i); 
	} 
}