?? check.c
字號:
#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 + -