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

📄 dbms.y

📁 一个c语言开发的小型的dbms系统
💻 Y
字号:
%{
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "struct.h"
#include "error.h"



char	sql[256];		/*用于读输入行的*/
int	sqlnum=0;		/*用于表示读到了第几个字符*/
char	*error_var;	/*用来接收各个程序返回的错误提示*/
int 	finish_flag;	/*用来控制主程序的循环,当用户输入"QUIT"时,它的值为1,表示应用结束*/

_dic_type		dic;	/*用来存放数据字典*/

_selectedfields_type	*sf_var1,*sf_end;
_selectedtables_type	*st_var1,*st_end;
_createfieldsdef_type	*cfdef_end;
_insertvalues_type		*iv_var1,*iv_end;
_insertfields_type		*if_var1,*if_end;

%}

%union			/*定义yylval的格式*/
{	char			char_var;
	char			*yych;
	/*---------------------------------属于select语法树的类型*/
	_selectedfields_type	*sf_var;
	_selectedtables_type	*st_var;
	_selectstruct_type		*ss_var;
	/*---------------------------------属于create语法树的类型*/
	_createfieldsdef_type	*cfdef_var;
	_createstruct_type		*cs_var;
	/*---------------------------------属于insert语法树的类型*/
	_insertfields_type		*if_var;
	_insertvalues_type		*iv_var;
	_insertstruct_type		*is_var;
	/*---------------------------------属于delete语法树的类型*/
	_deletestruct_type		*ds_var;
	_conditions_type		*cons_var;

}
%start statement
			/*select语句中涉及的符*/
%token	SELECT	FROM	WHERE	
%token	<yych>	IDENTIFIER	NUMBER	
%type	<ss_var>	selectsql		
%type	<sf_var>	fields_star	table_fields	table_field
%type	<st_var>	tables
%type	<yych>	table	field	express	

			/*create语句中涉及的符*/
%token	CREATE	TABLE	CHAR	INT	DATE
%type	<yych>	type
%type	<cfdef_var>	fieldsdefinition		field_type
%type	<cs_var>	createsql

			/*insert语句中涉及的符*/
%token	INSERT	INTO	VALUES
%type	<if_var>	fields	fields_choosed
%type	<iv_var>	values	avalue
%type	<is_var>	insertsql

			/*delete语句中涉及的符*/
%token	DELETE	
%type	<ds_var>	deletesql

%token	AND	OR
%type	<cons_var>	condition		comp_left		comp_right
%type	<cons_var>	table_field_	conditions
%type	<char_var>	comp_op

%token	QUIT	
%token	SHOW	TABLES	TABLE_DIC		OF	COLS

%%
statement:	selectsql
		{/*调用select对应的函数*/
		error_var=select_errorcheck(&dic,$1);
		if (strcmp(error_var,"")!=0) 
			{yyerror(error_var);
			return(1);
			}
		selectpro($1,&dic);
		/*selectexe($1);*/
		}
	|createsql
		{/*调用createexe对应的函数*/
		error_var=create_errorcheck(&dic,$1);
		if (strcmp(error_var,"")!=0) 
			{yyerror(error_var);
			return(1);
			}
		createpro($1,&dic);
		/*createexe($1);*/
		}
	|insertsql
		{/*调用insertexe对应的函数*/
		error_var=insert_errorcheck(&dic,$1);
		if (strcmp(error_var,"")!=0) 
			{yyerror(error_var);
			return(1);
			}
		insertpro($1,&dic);
		/*insertexe($1);*/
		}
	|deletesql
		{/*调用deleteexe对应的函数*/
		error_var=delete_errorcheck(&dic,$1);
		if (strcmp(error_var,"")!=0) 
			{yyerror(error_var);
			return(1);
			}
		deletepro($1,&dic);
		/*deleteexe($1);*/
		}
	|conditions ';'
		{
		/*conditionsexe($1);*/
		}
	|QUIT ';'
		{
		finish_flag=1;	/*表示应当退出了*/
		}
	|show ';'
	;

	/*------------------------------------------------------下面是select语句的定义--------*/
selectsql:	SELECT fields_star FROM tables ';'	
		{
		$$=(_selectstruct_type *)malloc(sizeof(_selectstruct_type));
		$$->sf=$2;
		$$->st=$4;
		$$->cons=NULL;
		}
	|SELECT fields_star FROM tables WHERE conditions ';'	
		{
		$$=(_selectstruct_type *)malloc(sizeof(_selectstruct_type));
		$$->sf=$2;
		$$->st=$4;
		$$->cons=$6;
		}
	;
fields_star:	table_fields	/*如果输入了具体的字段名称*/
		{
		$$=$1;
		}
	|'*'			/*如果输入了星号*/
		{
		$$=(_selectedfields_type *)malloc(sizeof(_selectedfields_type));
		$$->table=NULL;
		$$->field="*";
		$$->next_sf=NULL;
		}
	;
tables:	table			/*第一个表*/
		{
		$$=(_selectedtables_type *)malloc(sizeof(_selectedtables_type));
		$$->table=$1;
		$$->next_st=NULL;
		st_end=$$;
		}
	|tables ',' table	/*后面的表*/
		{
		$$=$1;
		st_var1=(_selectedtables_type *)malloc(sizeof(_selectedtables_type));
		st_var1->table=$3;
		st_var1->next_st=NULL;
		st_end->next_st=st_var1;	/*建立表名的连接*/
		st_end=st_var1;
		}
	;
table_fields:	table_field
		{
		$$=$1;
		sf_end=$$;		/*第一个字段名称*/
		}
	|table_fields ',' table_field	/*后面的字段*/
		{
		$$=$1;
		sf_end->next_sf=$3;	/*建立字段名的连接*/
		sf_end=$3;
		}
	;
table_field:	field
		{
		$$=(_selectedfields_type *)malloc(sizeof(_selectedfields_type));
		$$->table=(char *)malloc(sizeof(10));	/*为以后填上表名预留空间*/
		$$->table[0]='\0';
		$$->field=$1;
		$$->next_sf=NULL;
		}
	|table '.' field
		{
		$$=(_selectedfields_type *)malloc(sizeof(_selectedfields_type));		
		$$->table=$1;
		$$->field=$3;
		$$->next_sf=NULL;
		}
	;
field:	IDENTIFIER	
	;
table:	IDENTIFIER
	;
express:	IDENTIFIER
	|NUMBER	
	;

	/*-----------------------------------------------------下面是create语句的定义--------*/
createsql:	CREATE TABLE table '(' fieldsdefinition ')' ';'
		{
		$$=(_createstruct_type *)malloc(sizeof(_createstruct_type));
		$$->table=$3;
		$$->fdef=$5;
		}
	;
fieldsdefinition:	field_type
		{
		$$=$1;
		cfdef_end=$1;
		}	
	|fieldsdefinition ',' field_type
		{
		$$=$1;
		cfdef_end->next_fdef=$3;
		cfdef_end=$3;
		}
	;
field_type:	field  type
		{
		$$=(_createfieldsdef_type *)malloc(sizeof(_createfieldsdef_type));
		$$->field=$1;
		if (strlen($2)==0) 	/*表示类型为int的时候,用0表示类型,长度定为4*/
			{$$->type="0";
			$$->length="4";
			$$->next_fdef=NULL;
			}
		else	if(strcmp($2,"d")==0)
			{
			$$->type="3";
			$$->length="8";
			$$->next_fdef=NULL;
			}

		else	/*表示类型为char的时候,用1表示类型,长度定为$2*/
			{$$->type="1";
			$$->length="8";
			$$->next_fdef=NULL;
			}
		}
	;
type:	CHAR '(' NUMBER ')'
		{$$=$3;}
	|INT
		{$$="\0";}
	|DATE
		{$$="d";}
	;

	/*------------------------------------------------------下面是insert语句的定义--------*/
insertsql:	INSERT	INTO  table fields_choosed  VALUES '('  values ')'  ';'
		{
		$$=(_insertstruct_type *)malloc(sizeof(_insertstruct_type));
		$$->table=$3;
		$$->ifs=$4;
		$$->iv=$7;
		}
	;
fields_choosed:	/*empty*/
		{
		$$=(_insertfields_type *)malloc(sizeof(_insertfields_type));
		$$->field=(char *)malloc(sizeof(10));
		$$->field="";
		$$->next_if=(_insertfields_type *)malloc(sizeof(_insertfields_type));
		$$->next_if=NULL;
		}
	|'(' fields ')'
		{
		$$=$2;
		}
	;
fields:	field
		{
		$$=(_insertfields_type *)malloc(sizeof(_insertfields_type));
		$$->field=$1;
		$$->next_if=NULL;
		if_end=$$;
		}
	|fields ',' field
		{
		$$=$1;
		if_var1=(_insertfields_type *)malloc(sizeof(_insertfields_type));
		if_var1->field=$3;
		if_var1->next_if=NULL;
		if_end->next_if=if_var1;
		if_end=if_var1;
		}
	;
values:	avalue
		{
		$$=$1;
		$$->next_iv=NULL;
		iv_end=$$;
		}
	|values ',' avalue		
		{
		$$=$1;
		iv_end->next_iv=$3;
		iv_end=$3;
		}
	;
avalue:	'\'' IDENTIFIER '\''
		{
		$$=(_insertvalues_type *)malloc(sizeof(_insertvalues_type));
		$$->value=$2;
		$$->type='1';
		$$->next_iv=NULL;
		}
	|'\'' NUMBER '\''
		{
		$$=(_insertvalues_type *)malloc(sizeof(_insertvalues_type));
		$$->value=$2;
		$$->type='1';
		$$->next_iv=NULL;
		}
	|NUMBER
		{
		$$=(_insertvalues_type *)malloc(sizeof(_insertvalues_type));
		$$->value=$1;
		$$->type='0';
		$$->next_iv=NULL;
		}
;

	/*------------------------------------------------------下面是delete语句的定义--------*/
deletesql:	DELETE FROM table WHERE conditions ';'
		{
		$$=(_deletestruct_type *)malloc(sizeof(_deletestruct_type));
		$$->table=$3;
		$$->cons=$5;
		}
	|DELETE FROM table ';'
		{
		$$=(_deletestruct_type *)malloc(sizeof(_deletestruct_type));
		$$->table=$3;
		$$->cons=NULL;
		}
	;
	/*------------------------------------------------------下面是conditions语句的定义--------*/

conditions:	condition
		{
		$$=$1;
		}
	|'(' conditions ')' AND '(' conditions ')'
		{
		$$=(_conditions_type *)malloc(sizeof(_conditions_type));
		$$->left=$2;
		$$->right=$6;
		$$->comp_op='a';
		}
	|'(' conditions ')' OR '(' conditions ')'
		{
		$$=(_conditions_type *)malloc(sizeof(_conditions_type));
		$$->left=$2;
		$$->right=$6;
		$$->comp_op='o';
		}
	;
condition:	comp_left comp_op comp_right
		{
		$$=(_conditions_type *)malloc(sizeof(_conditions_type));
		$$->left=$1;
		$$->comp_op=$2;
		$$->right=$3;
		}
	;
comp_left:	table_field_
		{$$=$1;
		$$->comp_op='\0';
		$$->type='2';	
		$$->left=NULL;
		$$->right=NULL;
		} 
	;
comp_right:	table_field_
		{
		$$=$1;
		$$->comp_op='\0';
		$$->type='2';	
		$$->left=NULL;
		$$->right=NULL;
		}
	|'\'' IDENTIFIER '\''
		{
		$$=(_conditions_type *)malloc(sizeof(_conditions_type));
		$$->left=NULL;
		$$->right=NULL;
		$$->comp_op='\0';
		$$->type='1';
		$$->value=$2;
		}
	|'\'' NUMBER '\''
		{
		$$=(_conditions_type *)malloc(sizeof(_conditions_type));
		$$->left=NULL;
		$$->right=NULL;
		$$->comp_op='\0';
		$$->type='1';
		$$->value=$2;
		}
	|NUMBER
		{
		$$=(_conditions_type *)malloc(sizeof(_conditions_type));
		$$->left=NULL;
		$$->right=NULL;
		$$->type='0';
		$$->value=$1;
		$$->intval=atoi($1);
		}
	;
table_field_:	field
		{
		$$=(_conditions_type *)malloc(sizeof(_conditions_type));
		$$->table=(char *)malloc(sizeof(10));	/*为以后填上表名预留空间*/
		$$->table[0]='\0';
		$$->value=$1;
		}
	|table '.' field
		{
		$$=(_conditions_type *)malloc(sizeof(_conditions_type));
		$$->table=$1;
		$$->value=$3;
		}
	;

comp_op:		'<'
		{$$='<';
		}
	|'>'
		{$$='>';
		}
	|'='
		{$$='=';
		}
	;

show:	SHOW TABLES
		{
		show_tables(dic.tab,dic.tab_num);		/*显示已经有的表名*/
		}
	|SHOW TABLE_DIC
		{
		show_tab_dic(dic.tab,dic.tab_num);		/*显示表数据字典*/
		}
	|SHOW COLS OF table
		{
		show_col_dic(dic.tab,dic.tab_num,dic.col,dic.col_num,$4);	/*显示相应表的列信息*/
		}
	;

%%

typedef	struct	tokentype{
	char 	*name; 
	int 	value; 
	}tokentype;

tokentype tokens[] =	/*这里只列出了没有定义类型的终结符*/
{	"SELECT",		SELECT,
	"FROM",		FROM,
	"WHERE",		WHERE,
	"CREATE",		CREATE,
	"TABLE",		TABLE,
	"CHAR",		CHAR,
	"INT",		INT,
	"DATE",		DATE,
	"INSERT",		INSERT,
	"INTO",		INTO,
	"VALUES",		VALUES,
	"DELETE",		DELETE,
	"AND",		AND,
	"OR",		OR,
	"QUIT",		QUIT,
	"SHOW",		SHOW,
	"TABLES",		TABLES,
	"TABLE_DIC",	TABLE_DIC,
	"COLS",		COLS,
	"OF",		OF,
	"\0",		'\0'	
};

int is_number(char *s)	/*用来判断一个字符串是不是数字*/
{
	char *ss;
	ss=s;
	while (*ss!='\0')
	{	if (*ss<'0' || *ss>'9')  
			return(0);
		ss++;
	}
	return(1);
}

void low_to_up(char *s)	/*把一个字符串变为大写的*/
{	unsigned	int i;
	for(i=0;i<strlen(s);i++)
	{	s[i]=toupper(s[i]);
	}
}
int is_token(char *s)	/*用来判断一个字符串是不是一个无类型定义的token*/
{
	char *str;
	int	i=0;
	str=strdup(s);
	low_to_up(str);
	while(1)
	{
		if (strlen(tokens[i].name)==0)	break;	
		if (strcmp(tokens[i].name,str)==0)
		{	free(str);
			return(tokens[i].value);	/*是token,返回对应的值*/
		}
		i++;
	}
	free(str);
	return(0);		/*不是,则返回0*/
}

int is_legal(char s)	/*用来判断一个字符是不是字符串中的合法字符*/
{	int flag=0;
	if(s>='a' && s<='z')	flag=1;
	if(s>='A' && s<='Z')  	flag=1;
	if(s=='_') 	    	flag=1;
	if(s>='0' && s<='9')  	flag=1;
	if(flag==0)  return(0);	/*不是*/
	return(1);		/*是*/
}
		
int is_identifier(char *s)	/*用来判断一个字符串是不是合格的标识符*/
{
	char *ss;
	ss=s;
	while(*ss!='\0')
	{	if(is_legal(*ss)==0)  return(0);
		ss++;
	}
	return(1);
}

void readaword(char *aword)	/*将下一个词读入aword中*/
{
	char ss;
	int  awordnum=0;
	ss=sql[sqlnum];
	while( is_legal(ss))
	{	aword[awordnum]=ss;
		awordnum++;
		sqlnum++;
		ss=sql[sqlnum];
	}
	aword[awordnum]='\0';
}



yylex()
{
	char	ss;
	int	is_a_token;
	char	theword[256];	/*用于分解出输入行的一个单词*/
	while (sql[sqlnum]==' ')
		sqlnum++;
	ss=sql[sqlnum];
	if (ss=='\0') return(0);
	if (is_legal(ss)==0)	
	{	/*主要识别标点和运算符*/		
		sqlnum++;
		return(ss);
	}
	else	
	{	readaword(theword);
		 	/*主要识别保留字*/
		if (is_a_token=is_token(theword))	return(is_a_token);
			/*识别数字和标识符*/
		yylval.yych=(char *)malloc(strlen(theword)+1); 
		strcpy(yylval.yych,theword); 		
		if (is_number(theword)) 		return(NUMBER);
		if (is_identifier(theword))  	return(IDENTIFIER);
	}/*else*/	
	return(0);
}

void yyerror(char *s)
{
	printf("%s\n",s);
}

void check_sql()
{	
	int length=strlen(sql);
	if  (sql[length-1]!=';') 	/*如果用户没有在最后以';'结束,就给他们加上一个';'*/
		{		/*这样才可以把QUIT也加入词法分析中*/
		sql[length]=';';	/*这样可以使用户不用在QUIT后面也加入';'就能被接受。*/
		sql[length+1]='\0';
		}
}


main()

{	extern	int yyparse();
	FILE	*fp;
	char    buf[256];
	int		seek_beg=0;
	char	*result;
	while(1)

	{

		read_dic(dic.tab, &(dic.tab_num), dic.col, &(dic.col_num));	/*读出字典表信息*/

		printf("\nSQL>");

		sqlnum=0;		/*每次将指向sql的指针返回到起点*/

		finish_flag=0;	/*将结束控制变量初始化*/

		gets(sql);	/*获取输入行*/

		if(sql[0]=='@')
		{
			strncpy(buf,sql+1,strlen(sql)-1);
			buf[strlen(sql)-1]='\0';
			fp=fopen(buf,"rb");
			if(fp==NULL)
			{
				printf("Can't open file %s\n",buf);
				continue;
			}
			while(!feof(fp))
			{
//				result=fseek(fp,';',seek_beg);
//				seek_beg=result;
				fgets(sql,1024,fp);
				
				result=strchr(sql,';');
				strncpy(buf,sql,result-sql);
				buf[result-sql]='\0';
				strcpy(sql,buf);
				printf("sql=%sA\n",sql);
				check_sql(sql);	/*对输入行后面的';'做处理*/
				if (yyparse()==0)
					printf("Your command has been done successfully.\n");
				if (finish_flag==1)	break;		/*如果用户输入了quit那么将结束程序*/
						read_dic(dic.tab, &(dic.tab_num), dic.col, &(dic.col_num));	/*读出字典表信息*/
				printf("\nSQL>");
				sqlnum=0;		/*每次将指向sql的指针返回到起点*/
				finish_flag=0;	/*将结束控制变量初始化*/
			}

		}
		else
		{
			check_sql(sql);	/*对输入行后面的';'做处理*/
			if (yyparse()==0)
				printf("Your command has been done successfully.\n");
			if (finish_flag==1)	break;		/*如果用户输入了quit那么将结束程序*/
		}
	}			
}

⌨️ 快捷键说明

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