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

📄 check.c

📁 一个c语言开发的小型的dbms系统
💻 C
📖 第 1 页 / 共 2 页
字号:

#include <stdio.h>

#include <ctype.h>

#include <stdlib.h>

#include <string.h>

#include "struct.h"

#include "error.h"

/*------------------------------用来进行语法树的显示------------------------------*/

void show_condition(_conditions_type *con)	/*用来显示条件语法树中的一个叶节点*/
{						/*即比较符号的左半边或右半边*/
	switch (con->type)
	{case '2':
		{printf("type:table_field_ ,table: %s,  field: %s\n",con->table,con->value);
		break;
		}
	case '1':
		{printf("type: char,string: %s\n",con->value);
		break;
		}
	case '0':
		{printf("type: int,number: %s-%d\n",con->value,con->intval);
		break;
		}
	}
}

void conditionsexe(_conditions_type *con)	/*用来显示where子句*/
{
	_conditions_type *stack[20];		/*堆栈,存放中间节点*/
	int	st_int[20];			/*辅助堆栈,用来标识对应stack堆栈中节点的左右节点的入栈情况*/
	int	p=0;
	stack[p]=con;
	st_int[p]=0;
	do
	{
		switch (stack[p]->comp_op)
		{case	'a':
		case	'o':
			{
			switch  (st_int[p])
			{case 0 : /*表示没有子节点入栈了*/
				{p++;
				stack[p]=stack[p-1]->left;
				st_int[p]=0;
				break;
				}
			case 1 :  /*表示左节点入栈了*/
				{p++;		
				stack[p]=stack[p-1]->right;
				st_int[p]=0;
				break;
				}
			case 2 :  /*表示右节点入栈了*/
				{printf("%c\n",stack[p]->comp_op);		
				p--;
				if (p>=0) st_int[p]++;
				break;
				}
			}
			break;
			}
		case	'<':
		case	'>':
		case	'=':
			{				/*说明已经到了叶节点,该显示了*/
			show_condition(stack[p]->left);
			show_condition(stack[p]->right);
			printf("%c\n",stack[p]->comp_op);	/*显示晚左右叶节点,显示比较符号*/	
			p--;
			if (p>=0)		st_int[p]++;
			break;
			}
		}
	}while(p!=-1);
}


void selectexe(_selectstruct_type *ss)	/*用来检测select语句的语法树是否正确*/
{
	_selectedfields_type *sf1;
	_selectedtables_type *st1;
	printf("fields_star: ");
	sf1=ss->sf;
	do
	{	
		if (sf1->table!=NULL)
		{	printf("%s.",sf1->table);}
		printf("%s",sf1->field);
		if (sf1->next_sf==NULL) break;
		sf1=sf1->next_sf;
		printf(",");
	}while(1);
	printf("\n");
	
	printf("tables: ");
	st1=ss->st;
	do
	{	printf("%s",st1->table);
		if(st1->next_st==NULL) break;
		st1=st1->next_st;
		printf(",");

	}while(1);
	printf("\n");
	if (ss->cons!=NULL)	conditionsexe(ss->cons);
	
}

void createexe(_createstruct_type *cs)	/*用来检测create语句的语法树是否正确*/
{

	_createfieldsdef_type	*cfdef1;
	printf("table: %s\n",cs->table);
	cfdef1=cs->fdef;
	printf("fieldsdefinition: ");
	do
	{
		printf("%s-%s-%s",cfdef1->field,cfdef1->type,cfdef1->length);
		if (cfdef1->next_fdef==NULL) break;
		cfdef1=cfdef1->next_fdef;
		printf(",");
	}while(1);
	printf("\n");
}

void insertexe(_insertstruct_type *is)	/*用来检测insert语句的语法树是否正确*/
{
	_insertfields_type		*ifs1;
	_insertvalues_type		*iv1;
	printf("table: %s\n",is->table);
	
	if (is->ifs!=NULL)
	{	ifs1=is->ifs;
		printf("fields: ");
		do
		{
			printf("%s",ifs1->field);
			if (ifs1->next_if==NULL) break;
			ifs1=ifs1->next_if;
			printf(",");
		}while(1);
		printf("\n");
	}
	iv1=is->iv;
	printf("values: ");
	do
	{
		printf("%s--%c",iv1->value,iv1->type);
		if (iv1->next_iv==NULL) break;
		iv1=iv1->next_iv;
		printf(",");
	}while(1);
	printf("\n");
}

void deleteexe(_deletestruct_type *ds)	/*用来检测delete语句的语法树是否正确*/
{
	printf("table: %s",ds->table);
	printf("\n");
	if (ds->cons!=NULL) conditionsexe(ds->cons);
}


/*------------------------------用来显示数据字典的相关信息-----------------------*/

void show_tables(_tab_dic_type *tab,int tab_num)	/*用来显示已经存在的表*/
{
	int i=0,j=0;
	for (i=0;i<tab_num;i++)
//	for (j=0;j<tab_num;j++)
	{
		if(is_a_table_dropped(tab[i].tab_name)==0)
		{
			printf("TABLE_%d:\t%s\n",j+1,tab[i].tab_name);
			j++;
		}
	}
}

void show_tab_dic(_tab_dic_type *tab,int tab_num)	/*详细显示表字典表的信息*/
{
	int i=0;
	printf("表名\t表序号\t首地址块\t字段数\t记录数\t记录长度\n");
	for (i=0;i<tab_num;i++)
	{
		if(is_a_table_dropped(tab[i].tab_name)==1)
			continue;
		printf("%s\t%d\t%d\t\t%d\t%d\t%d\n",
	tab[i].tab_name,tab[i].tab_id,tab[i].first_free_block,tab[i].col_num,tab[i].row_num,tab[i].row_len);
	}
}

int get_tab_id(_tab_dic_type *tab,int tab_num,char *table)	/*用来取得一个表的表序号*/
{
	int i=0;
	for (i=0;i<tab_num;i++)
	{if (strcmp(table,tab[i].tab_name)==0) 
		return(tab[i].tab_id);
	}
	return(0);

}

void show_col_dic(_tab_dic_type *tab,int tab_num,_col_dic_type *col,int col_num,char *table)
{						/*用来显示一个选定表的字段信息*/
	int i=0;
	int tab_id;
	int type;
	char *type_name[5]={"整型","字符串"," ","日期"};
	tab_id=get_tab_id(tab,tab_num,table);
	printf("表_%d:%s\t的字段信息\n",tab_id,table);
	printf("名称\t类型\t长度\n");
//	printf("名称\t序号\t类型\t长度\n");
	for (i=0;i<col_num;i++)
	{
		if (tab_id==col[i].tab_id) 
		{
			type=col[i].col_type ;
			printf("%s\t%s\t%d\n",col[i].col_name,type_name[type],col[i].col_length);
		}
	}

}


/*--------------------------------进行语法树的初步语义检查----------------------------*/
/*主要就是根据数据字典,对不符合语义的语句给以出错处理*/

char *is_an_exist_table(_tab_dic_type *tab,int tab_num,char *table)
					/*判断所用的表名是不是数据字典中已经有的*/
{
	int i=0;
	for (i=0;i<tab_num;i++)
	{if (strcmp(table,tab[i].tab_name)==0) 
		return("");	/*在字典表中找到了相应的表名*/
	}
	return(ERROR0001);		/*没有找到*/

}

char *is_the_col_in_this_table(char *col,char *default_table,char *used_table,_dic_type *dic)
						/*判断一个列是不是在对应的表中*/
{			/*当default_table不为空时,就一定和used_table是一个*/
	int i=0;
	int tab_id;

	tab_id=get_tab_id(dic->tab,dic->tab_num,used_table);
	for (i=0;i<dic->col_num;i++)
	{
		if (tab_id==dic->col[i].tab_id  && strcmp(col,dic->col[i].col_name)==0) 
		{		/*如果字典表中有对应的列和选择的列一致*/
			if (strcmp(default_table,"")==0)
			{
				strcpy(default_table,used_table);
			}
			return("");
		}
	}
	if (strcmp(default_table,"")==0)		/*没有找到相应的列*/
	{	
		return(ERROR0003);		/*找不到相应列对应的默认表名*/
	}
	else
	{	
		return(ERROR0004);		/*表名和列名不对应*/
	}

}

int is_a_table_dropped(char *table)
{
	if(table[0]=='$')
//		printf("table=%s,type=1\t",table);
		return(1);
	else
//		printf("table=%s,type=0\t",table);
		return(0);
}
char *is_a_table_selected(_selectedtables_type *st,char *table)
{				/*判断一个要用的表是不是已经选择出来的表中的*/
	_selectedtables_type *st1;
	st1=st;
	do
	{
		if (strcmp(table,st1->table)==0)	/*如果找到了匹配的表名*/
			return("");
		if (st1->next_st==NULL)	
		{	
			return(ERROR0002);		/*使用了一个没有被选择的表*/
		}
		st1=st1->next_st;
	}while(1);
}


char *is_a_right_col_used(char *col,char *table,_selectedtables_type *st,_dic_type *dic)
{				/*用来判断一个列是否是属于已经被选择了的若干表中的*/
	_selectedtables_type *st1;
	char 	*error_var="";
	int	match_tab_num=0;
	st1=st;
	if (strcmp(table,"")!=0)	/*如果所选择的列给出了是属于哪个表的*/
	{			/*先判断是否用的表属于选择出的表组合*/
		error_var=is_a_table_selected(st1,table);
		if (strcmp(error_var,"")!=0)
		{	return(error_var);
		}
				/*再判断后面的字段名是不是属于前面的表中的*/
		error_var=is_the_col_in_this_table(col,table,table,dic);	
		if (strcmp(error_var,"")!=0)
		{	return(error_var);
		}
		return("");
	}
	else			/*如果并没有给出所选择的列是属于哪个表的*/
	{
		do		/*对于所选择的表组合中的每一个表进行判断*/
		{
			error_var=is_the_col_in_this_table(col,table,st1->table,dic);	
			if (strcmp(error_var,"")==0)
			{	match_tab_num++;
				if (match_tab_num>1)	/*多于一个表中含有此子段,归属不确定*/
				{
					return(ERROR0005);
				}
			}
			if  (st1->next_st==NULL) 
			{	if(strcmp(table,"")==0)
				{	return(error_var);		/*如果到了结束也没有找到*/
				}
				else break;
			}
			st1=st1->next_st;
		}while(1);
		return("");
	}

}

char get_type_of_col(_dic_type *dic,char *table,char *col)	/*取得列的类型*/
{
	int i=0;
	int tab_id;

	tab_id=get_tab_id(dic->tab,dic->tab_num,table);
	for (i=0;i<dic->col_num;i++)
	{
		if (tab_id==dic->col[i].tab_id  && strcmp(col,dic->col[i].col_name)==0) 
		{		/*如果字典表中有对应的列和选择的列一致*/
			return(dic->col[i].col_type+'0');
		}
	}
	return(0);
}

_col_dic_type *get_info_of_a_col(_dic_type *dic,char *table,char *col)
{
	int i=0;
	int tab_id;

	tab_id=get_tab_id(dic->tab,dic->tab_num,table);
	for (i=0;i<dic->col_num;i++)
	{
		if (tab_id==dic->col[i].tab_id  && strcmp(col,dic->col[i].col_name)==0) 
		{		/*如果字典表中有对应的列和选择的列一致*/
			return(&dic->col[i]);
		}
	}
	return(0);
}

char *one_select_con_check(_dic_type *dic,_selectedtables_type *st,_conditions_type *cons)
{						/*检查一个条件比较式的正确性*/
	char 		left_type,right_type;
	_conditions_type 	*left,*right;
	char 		*error_var;
	left=cons->left;
	right=cons->right;
						/*先判断左半边是否是正确的字段*/
	error_var=is_a_right_col_used(left->value,left->table,st,dic);
	if (strcmp(error_var,"")!=0)
	{	return(error_var);
	}
	left_type=get_type_of_col(dic,left->table,left->value);	/*获得字段的类型*/

	if (right->type=='2')			/*表示右节点也是字段*/
	{					/*判断右半边是否是正确的字段*/
		error_var=is_a_right_col_used(right->value,right->table,st,dic);
		if (strcmp(error_var,"")!=0)
		{	return(error_var);
		}
		right_type=get_type_of_col(dic,right->table,right->value);	/*获得字段的类型*/
	}
	else
	{	right_type=right->type;		/*如果不是字段,也要获得字段的类型*/
	}

//	if (left_type!=right_type) 		/*左右两边的类型不匹配*/
//	{	return(ERROR0006);
//	}
	
	if ((cons->comp_op=='>' || cons->comp_op=='<') && right_type=='1')	/*企图用<,>来判断字符串*/
	{	return(ERROR0007);
	}

	return("");
}



char *select_cons_check(_dic_type *dic,_selectstruct_type *ss)
{
	_conditions_type *stack[20];		/*堆栈,存放中间节点*/
	int	st_int[20];		/*辅助堆栈,用来标识对应stack堆栈中节点的左右节点的入栈情况*/
	int	p=0;
	char	*error_var;
	stack[p]=ss->cons;
	st_int[p]=0;
	do
	{
		switch (stack[p]->comp_op)
		{case	'a':
		case	'o':
			{
			switch  (st_int[p])
			{case 0 : /*表示没有子节点入栈了*/
				{p++;
				stack[p]=stack[p-1]->left;
				st_int[p]=0;
				break;
				}
			case 1 :  /*表示左节点入栈了*/
				{p++;		
				stack[p]=stack[p-1]->right;
				st_int[p]=0;
				break;
				}
			case 2 :  /*表示右节点入栈了*/
				{		
				p--;
				if (p>=0) st_int[p]++;
				break;
				}
			}

⌨️ 快捷键说明

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