📄 intepretor.cpp
字号:
#include "Intepretor.h"
#include "Glob_Var.h"
extern char CurLocation[256];
//<---存有当前正在使用的表的相对路径
extern char CurRelationName[33];
//<---存当前表的表名
char CurDB[33] = "";
//---用于抛出字串输入错误时输出错误提示使用
char* ppErr[] = {"Not an available command!",
"Common typing error!",
"Wrong type of the data ,you can only use \'char\',\'float\',\'int\' ",
"Please type the correct keyword!--like \'NotNull\',\'primary\'",
"Your Column name doesn\'t exist!",
"We does't support your operator typed",
"You must specify at least one Column for us to select it!"};
//<---用于抛出一般性错误时输出错误提示使用
char* ppGnlErr[] = {"The DB doesn\'t exist!",
"The Table doesn\'t exist!",
"You haven\'t choose a database!",
"This DB has already existed!",
"This Table has already existed!",
"You must have 2 \' to match each other!",
"No primary key exists!"};
ECMD_TYPE GetCommand(TB_Create_Info** ptrCreateInfo,TB_Select_Info** ptrSelectInfo,TB_Insert_Info** ptrInsertInfo,TB_Update_Info** ptrUpdateInfo,TB_Delete_Info** ptrDeleteInfo)
{
ECMD_TYPE CmdType = UNORMAL;//<---假设给出的命令是非正常的
try{
//--->打出提示信息
std::cout<<'\n';
std::cout<<"MiniSQL->";
Ch_csVstrBlk CommandInput;
//<---开始作解析命令的尝试
CmdType = CommandInput.ResolveCmd();
//<---开始对输入的是何命令作解析,由ResolveCmd()对第一个有意字串作判断
if(CmdType != USE && CmdType != HELP && CmdType != QUIT
&& CmdType != SHOWDB && CmdType != DROP&&CmdType != NEW)
//<---以下命令必须在选择数据库后才能执行
{if(CompStrEver(CurDB,""))
{ CmdType = UNORMAL;
GnlTrwErr(NODBUSED);}
}
switch(CmdType) //<---选择命令
{
case CREATE:
*ptrCreateInfo = CommandInput.CH_Create();
//<---对非该命令的指针赋0
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
return CREATE;
break;
case SELECT:
*ptrSelectInfo = CommandInput.CH_Select();
*ptrCreateInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
return SELECT;
break;
case INSERT:
*ptrInsertInfo = CommandInput.CH_Insert();
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
return INSERT;
break;
case DELETE:
*ptrDeleteInfo = CommandInput.CH_Delete();
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
return DELETE;
break;
case USE: //<---选择数据库
*ptrDeleteInfo = 0;
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
CommandInput.ChoseDatabase();
return USE;
break;
case DROP:
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
CommandInput.DropTB();
return DROP;
break;
case DROPDB:
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
CommandInput.DropDB();
return DROPDB;
break;
case NEW:
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
CommandInput.NewDB();
return NEW;
break;
case QUIT:
CommandInput.PassCommon(";");
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
QuitSQL();
return QUIT;
break;
case SHOWDB:
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
ShowDB();
break;
case SHOWTABLE:
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
if(CompStrEver(CurDB,""))
GnlTrwErr(NODBUSED);
ShowTable();
break;
case HELP:
CommandInput.PassCommon(";");
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
ShowHelp();
break;
default :
*ptrCreateInfo=0;
*ptrSelectInfo=0;
*ptrInsertInfo=0;
*ptrUpdateInfo=0;
*ptrDeleteInfo = 0;
break;
}
}
catch(ErrInfo a)
//字串输入错误,给出提示--->
{
std::cout<<"The Error near \'"<<a.pErrStr<<"\'"<<"in Line "<<a.iLineNo<<" may be: \n";
std::cout<< ppErr[a.iErrType]<<'\n';
CmdType = UNORMAL;
}
catch(GnlErrInfo a)
//一般性错误--->
{
std::cout<< ppGnlErr[a.iErrType]<<'\n';
std::cout<< "Please type \'help\' to get help!\n";
CmdType = UNORMAL;
}
return CmdType;
}
//构造函数,对输入进行处理,产生一个有以字串的集合--->
Ch_csVstrBlk::Ch_csVstrBlk()
{
InitialVar(); //<---初始化输入字串
MakeVstrBlkList(); //<---生成有意字串块的链表
}
void Ch_csVstrBlk::InitialVar()
{
//初始化某些参数--->
StrHead = 0;
StrNow = 0;
StrTail = 0;
iNumNowInVstr = 0;
iLineNum[0][0] = 0;
sta_i = 0;
strInputCharList = InitialInput();
}
//对输入进行处理,产生一个有意字串的集合--->
void Ch_csVstrBlk::MakeVstrBlkList()
{
int flag;
int iForLineNum = 0;
char* tempStr;
VSTR_BLK_PTR vbNewBlk;
do
{
flag = InString(&tempStr);
//<---可能在字符串拷贝时会出错,小心
if(flag == 0)
{
//<---返回有意字串
iNumNowInVstr++;
//<---有意字串个数加1
{vbNewBlk = new VSTR_BLK;
vbNewBlk->str = tempStr;
vbNewBlk->next = 0;
if(StrHead == 0)
StrHead = vbNewBlk;
else
StrTail->next = vbNewBlk;
StrTail = vbNewBlk;
}
//<---生成一个有意字串的结构体,并将它链成链表
}
else
{ //<--- 回车,说明行数加一
iLineNum[iForLineNum++][1] = iNumNowInVstr;
//<--- 原来末行的末地址
iLineNum[iForLineNum][0] = iNumNowInVstr + 1;
//<--- 新行的首地址
}
}
while(CompStrEver(tempStr,"\xff") != 1);
//<--- 得到的是"\xff"时,表示用户输入已经结束
iNumNowInVstr = 0;
//<--- 再次初始化iNumNowInVstr,用于正式输入处理时的位置计算
StrNow = StrHead;
//<--- 将StrNow指到StrHead上
}
bool Ch_csVstrBlk::InString(char** ObjectStr)
{
int i = 0;
char chTemp;
*ObjectStr = new char[NAMEMAXLEN];
if((chTemp = strInputCharList[sta_i++]) != '\0')
(*ObjectStr)[i++] = chTemp;
//<--- 第一个字符如果为空,则必须略过
do{
chTemp = strInputCharList[sta_i++];
(*ObjectStr)[i++] = chTemp;
}
while(chTemp != '\0');
if(CompStrEver(*ObjectStr, "\n"))
return 1;//<--- 回车
else
return 0;//<--- 有意字串
}
char* Ch_csVstrBlk::InitialInput()
{
//保留有效信息,只留下回车和其他字符,用'\xff'来表示字串的结束
char* strResult;
strResult = new char[INPUTMAX];
char tempIn;
int i = 0;
int DoGetcharFlag = 1;
int MaybeEnd = 0;
int EndFlag = 0;
do{
if(DoGetcharFlag)
{
tempIn = getchar();
}
else
DoGetcharFlag = 1;
switch(tempIn)
{
case ' ' : //<--- 过滤空格
{
if(strResult[i - 1] != 0)
strResult[i++] = 0;
do{
tempIn = getchar();
}while(tempIn == ' '); //<--- 过滤空格
DoGetcharFlag = 0; //<--- 则新的循环中无需再读入一个字符
}
break;
case ';' : //<--- 输入结束标志
SaveKeyChar(strResult,&i,tempIn);
MaybeEnd = 1; //<--- 表示可能是输入结束,MaybeEnd在下一次输入回车时会用到
break;
case ',' :
case '(' :
case ')' :
case '>' :
case '<' :
case '=' :
SaveKeyChar(strResult,&i,tempIn);
break;
case '\'' : //<--- 在回车之前必须得到另外一个 ' 以作匹配
strResult[i++] = tempIn;
while( (tempIn = getchar())!='\n' &&tempIn != ','&&tempIn!= '\''&&tempIn!= ';')
strResult[i++] = tempIn;
if(tempIn == '\'')
{strResult[i++] = tempIn;
strResult[i++] = '\0';}
else{
do{tempIn=getchar();}while(tempIn !='\n');
GnlTrwErr(WITHOUTMATCH);//<--- 单引号不匹配
}
break;
case '\n' :
if(MaybeEnd == 0)
{
// 回车后将呈现的提示符 --->
std::cout<<" ->";
SaveKeyChar(strResult,&i,tempIn);
}
else //<--- 这一次是整个命令的正式结束
{SaveKeyChar(strResult,&i,tempIn);
EndFlag = 1;}
break;
default : //<--- 一般的字符输入
strResult[i++] = tempIn;
break;
}
}
while(EndFlag == 0 && i < INPUTMAX);//<--- 检查何种原因退出循环
SaveKeyChar(strResult,&i,'\xff');
strResult[i] = '\0';
return strResult;
}
TB_Create_Info* Ch_csVstrBlk::CH_Create()
//表示一个完整的有关Create操作的参数类,负责Create命令的所有操作
{
// 命令输入应该如:create table tablename(columnname,type);
char* strTableName = 0;
TB_Create_Info* tbReturn;
pCreate_Column pTemp = 0,pHead = 0,pTail = 0;
int iColNum = 0;
bool NotEnd = 1;
bool bPriKeyExist = 0; //<--- 用于判断Primary key是否存在的标志
PassCommon("table");
strTableName = GetTBName(); //<--- 取得表名
if(CheckTB(strTableName))
GnlTrwErr(SUCHTBEXIST); //<--- 检验输入的该table是否存在,存在则给出错误
SetCurRelation(strTableName);
PassCommon("(");
do //<--- 取得各个列定义的名称和类型
{
if(CompStrEver(StrNow->str,"check"))
GetCheckInfo(&NotEnd,pHead); //<--- 该行是有关列的约束信息
else
{pTemp = GetColumnInfo(&NotEnd,bPriKeyExist);
iColNum++; //<--- 列的数量+1
if(pHead == 0)
{pHead = pTemp;
pTail = pTemp;
}
else{
pTail->next = pTemp;
pTail = pTemp;}
}
}while(NotEnd);
PassCommon(")");
PassCommon(";");
if(bPriKeyExist == 0) //<--- primary key不存在
GnlTrwErr(NOPRIMARYKEY);
tbReturn = new TB_Create_Info(iColNum,pHead,strTableName);
//<--- 生成该表
return tbReturn;
}
void Ch_csVstrBlk::GetCheckInfo(bool *NotEnd,pCreate_Column pHead)
{
//功能描述:得到有关一个列的约束信息
char* strColName = new char[NAMEMAXLEN];
EOPE_TYPE optype;
ECOL_TYPE coltype;
COLVAL tmin;
COLVAL tmax;
pCreate_Column pColtemp = 0;
PassCommon("check");
PassCommon("(");
pColtemp = GetColForCheck(StrNow->str,pHead); //<--- 得到check中列的各个信息
optype = GetOptype(); //<--- 得到所要check的列的操作类型
coltype = pColtemp->ColType; //<--- 赋所要check的列的数据类型(char,int,float)中的一种
if(optype == BETWEEN) //<--- BETWEEN AND 比较特殊,单独处理
{PassCommon("between");
switch(coltype) //<--- 根据数据类型给约束条件赋值
{
case I:
tmin.IntValue = atoi(StrNow->str);
NextStr();
PassCommon("and");
tmax.IntValue = atoi(StrNow->str);
NextStr();
pColtemp->SetColValint(optype,tmin.IntValue,tmax.IntValue);
break;
case F:
tmin.FloatValue = atof(StrNow->str);
NextStr();
PassCommon("and");
tmax.FloatValue = atof(StrNow->str);
NextStr();
pColtemp->SetColValfloat(optype,tmin.FloatValue,tmax.FloatValue);
break;
case C:
tmin.pCharValue = FilterQuota(StrNow->str);
NextStr();
PassCommon("and");
tmax.pCharValue = FilterQuota(StrNow->str);
pColtemp->SetColValstr(optype,tmin.pCharValue,tmax.pCharValue);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -