📄 xksqlparser.cpp
字号:
// xkSQLParser.cpp: implementation of the xkSQLParser class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "xkDBMS.h"
#include "xkSQLParser.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//extern xkExecEngine* pEngine_;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static enum xkTokenTable
{
select_tkn_,
all_tkn_, //'*'
dot_tkn_, //'.'
from_tkn_,
where_tkn_,
update_tkn_,
set_tkn_,
assign_tkn_, //'='
delete_tkn_,
create_tkn_,
table_tkn_,
drop_tkn_,
lpair_tkn_, //'('
rpair_tkn_, //')'
insert_tkn_,
into_tkn_,
values_tkn_,
comma_tkn_, //','
tint_tkn_,
tfloat_tkn_,
tstring_tkn_,
tchar_tkn_,
identifier_tkn_,
error_tkn_,
};
const int TOKENCOUNT = error_tkn_ + 1;
static struct
{
char *key_;
int token_;
}xkKeywordsTable[] =
{
{"select", select_tkn_},
{"from", from_tkn_},
{"where", where_tkn_},
{"update", update_tkn_},
{"set", set_tkn_},
{"delete", delete_tkn_},
{"create", create_tkn_},
{"table", table_tkn_},
{"drop", drop_tkn_},
{"insert", insert_tkn_},
{"into", into_tkn_},
{"values", values_tkn_},
{"t_int", tint_tkn_},
{"t_float", tfloat_tkn_},
{"t_string", tstring_tkn_},
{"t_char", tchar_tkn_},
};
const int KEYWORDCOUNT = sizeof(xkKeywordsTable)/sizeof(xkKeywordsTable[0]);
xkSQLParser::xkSQLParser()
{
}
xkSQLParser::~xkSQLParser()
{
for(size_t i = 0; i < identifier_vec_.size(); i++)
if(identifier_vec_[i])
delete[] identifier_vec_[i];
}
/*
* 词法分析
*/
Token xkSQLParser::GetToken()
{
char ch_ = 0;
ch_ = getch();
while(isspace(ch_))
{
ch_ = getch();
}
switch(ch_)
{
case '*':
return all_tkn_;
case '.':
return dot_tkn_;
case '=':
return assign_tkn_;
case '(':
return lpair_tkn_;
case ')':
return rpair_tkn_;
case ',':
return comma_tkn_;
case '0':case '1':case '2':case '3':case '4':
case '5':case '6':case '7':case '8':case '9':
{
bool flag_ = false;
char_vec_.clear();
do
{
if(ch_ == '.')
flag_ = true;
char_vec_.push_back(ch_);
ch_ = getch();
} while(isdigit(ch_) || ch_ == '.');
if(ch_ != '\0' && ch_ != EOF)
ch_ = ungetch();
char* tmp_ = new char[char_vec_.size() + 1];
for(size_t iter_ = 0; iter_ < char_vec_.size(); iter_++)
tmp_[iter_] = char_vec_[iter_];
tmp_[char_vec_.size()] = '\0';
identifier_vec_.push_back(tmp_);
if(flag_)
return tfloat_tkn_;
else
return tint_tkn_;
}
default:
if(isalpha(ch_))
{
char_vec_.clear();
do
{
char_vec_.push_back(ch_);
ch_ = getch();
} while(isalpha(ch_) || isdigit(ch_));
if(ch_ != '\0' && ch_ != EOF)
ch_ = ungetch();
char* chr_ = new char[char_vec_.size() + 1];
for(size_t j = 0; j < char_vec_.size(); j++)
chr_[j] = char_vec_[j];
chr_[char_vec_.size()] = '\0';
for(size_t k = 0; k < KEYWORDCOUNT; k++)
{
if(strcmp(chr_, xkKeywordsTable[k].key_) == 0)
{
delete[] chr_;
return xkKeywordsTable[k].token_;
}
}
//delete[] chr_;
// tablename_ = chr_;
identifier_vec_.push_back(chr_);
return identifier_tkn_;
}
else if(ch_ == '\0' || ch_ == EOF)
return error_tkn_;
}
return 0;
}
/*
* 语法分析
*/
bool xkSQLParser::Parse()
{
Token tkn_ = GetToken();
switch(tkn_)
{
case select_tkn_:
return SelectFunc();
case update_tkn_:
return UpdateFunc();
case delete_tkn_:
return DeleteFunc();
case insert_tkn_:
return InsertFunc();
case create_tkn_:
return CreatetableFunc();
case drop_tkn_:
return DroptableFunc();
default:
return 0;
}
}
/*
* parse select statement
*/
bool xkSQLParser::SelectFunc()
{
Token tkn_ = GetToken();
if(tkn_ == all_tkn_)
{
tkn_ = GetToken();
if(tkn_ != from_tkn_)
{
return false;
}
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
{
AfxMessageBox("不是表名");
return false;
}
size_t rid_ = 0;
if((rid_ = FindTable(identifier_vec_[0])) == -1)
{
AfxMessageBox("此表不存在");
return false;
}
// pEngine_->DisplayTable(tablename_);
tkn_ = GetToken();
if( tkn_ == where_tkn_)
{
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
return false;
char* keyword_ = identifier_vec_[identifier_vec_.size()-1];
tkn_ = GetToken();
if(tkn_ != assign_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_ && tkn_ != tfloat_tkn_ && tkn_ != tint_tkn_)
{
AfxMessageBox("关键字值不对");
return false;
}
char* keyval_ = identifier_vec_[identifier_vec_.size()-1];
engine_->GetSelectedTuple(identifier_vec_[0], keyword_, keyval_);
}
else if(tkn_ == error_tkn_)
{
engine_->DisplayTable(identifier_vec_[0]);
return true;
}
}
else if(tkn_ == identifier_tkn_)
{
size_t fcount_ = 0;
Vector<char*> fieldlist_;
fieldlist_.push_back(identifier_vec_[fcount_++]);
tkn_ = GetToken();
while(tkn_ == comma_tkn_)
{
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
return false;
fieldlist_.push_back(identifier_vec_[fcount_++]);
tkn_ = GetToken();
}
if(tkn_ != from_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
{
AfxMessageBox("不是表名");
return false;
}
size_t rid_ = 0;
if((rid_ = FindTable(identifier_vec_[fcount_])) == -1) //only select from one table!!!
{
AfxMessageBox("此表不存在");
return false;
}
// pEngine_->DisplayTable(tablename_);
tkn_ = GetToken();
if( tkn_ == where_tkn_)
{
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
return false;
char* keyword_ = identifier_vec_[identifier_vec_.size()-1];
tkn_ = GetToken();
if(tkn_ != assign_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_ && tkn_ != tfloat_tkn_ && tkn_ != tint_tkn_)
{
AfxMessageBox("关键字值不对");
return false;
}
char* keyval_ = identifier_vec_[identifier_vec_.size()-1];
engine_->GetSelectedTuple(identifier_vec_[fcount_], keyword_, keyval_, &fieldlist_);
}
else if(tkn_ == error_tkn_)
{
engine_->DisplayTable(identifier_vec_[fcount_], &fieldlist_);
return true;
}
}
return 0;
}
bool xkSQLParser::UpdateFunc()
{
Token tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
return false;
tablename_ = identifier_vec_[0];
tkn_ = GetToken();
if(tkn_ != set_tkn_)
return false;
Vector<char*> fieldlist_, valuelist_;
tkn_ = GetToken();
while(1)
{
if(tkn_ != identifier_tkn_)
return false;
fieldlist_.push_back(identifier_vec_[identifier_vec_.size() - 1]);
tkn_ = GetToken();
if(tkn_ != assign_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_ && tkn_ != tfloat_tkn_ && tkn_ != tint_tkn_)
return false;
valuelist_.push_back(identifier_vec_[identifier_vec_.size() - 1]);
tkn_ = GetToken();
if(tkn_ == comma_tkn_)
tkn_ = GetToken();
else
break;
}
if(tkn_ == where_tkn_)
{
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
return false;
char* keyword_ = identifier_vec_[identifier_vec_.size()-1];
tkn_ = GetToken();
if(tkn_ != assign_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_ && tkn_ != tfloat_tkn_ && tkn_ != tint_tkn_)
{
AfxMessageBox("关键字值不对");
return false;
}
char* keyval_ = identifier_vec_[identifier_vec_.size()-1];
if(fieldlist_.size() != valuelist_.size())
{
AfxMessageBox("字段个数与数值个数不等!");
return false;
}
tkn_ = GetToken();
if(tkn_ != error_tkn_)
return false;
engine_->UpdateTuple(tablename_,fieldlist_, valuelist_, keyword_, keyval_);
return true;
}
else
return false;
}
/*
* 只删除记录,不删除字段
*/
bool xkSQLParser::DeleteFunc()
{
Token tkn_ = GetToken();
if(tkn_ == from_tkn_)
{
// tkn_ = GetToken();
// if(tkn_ != from_tkn_)
// return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
{
AfxMessageBox("不是表名");
return false;
}
size_t rid_ = 0;
if((rid_ = FindTable(identifier_vec_[0])) == -1)
{
AfxMessageBox("此表不存在");
return false;
}
// pEngine_->DisplayTable(tablename_);
tkn_ = GetToken();
if( tkn_ == where_tkn_)
{
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
return false;
char* keyword_ = identifier_vec_[identifier_vec_.size()-1];
tkn_ = GetToken();
if(tkn_ != assign_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_ && tkn_ != tfloat_tkn_ && tkn_ != tint_tkn_)
{
AfxMessageBox("关键字值不对");
return false;
}
char* keyval_ = identifier_vec_[identifier_vec_.size()-1];
tkn_ =GetToken();
if(tkn_ != error_tkn_)
return false;
// pEngine_->GetSelectedTuple(identifier_vec_[0], keyword_, keyval_);
engine_->DeleteTuple(identifier_vec_[0], keyword_, keyval_);
return true;
}
else if(tkn_ == error_tkn_)
{
// pEngine_->DisplayTable(identifier_vec_[0]);
engine_->DeleteTuple(identifier_vec_[0], 0 ,0);
return true;
}
}
return 0;
}
/*
* 只解析完整字段名且插入完整数值的INSERT语句
*/
bool xkSQLParser::InsertFunc()
{
Token tkn_ = GetToken();
if(tkn_ != into_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
return false;
tablename_ = identifier_vec_[0];
Vector<char*> fieldlist_, valuelist_;
tkn_ = GetToken();
if(tkn_ != lpair_tkn_)
return false;
tkn_ = GetToken();
while(1)
{
if(tkn_ != identifier_tkn_)
return false;
fieldlist_.push_back(identifier_vec_[identifier_vec_.size() - 1]);
tkn_ = GetToken();
if(tkn_ == comma_tkn_)
tkn_ = GetToken();
else
break;
}
if(tkn_ != rpair_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != values_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != lpair_tkn_)
return false;
tkn_ = GetToken();
while(1)
{
if(tkn_ != tint_tkn_ && tkn_ != tfloat_tkn_ && tkn_ != identifier_tkn_)
return false;
valuelist_.push_back(identifier_vec_[identifier_vec_.size() - 1]);
tkn_ = GetToken();
if(tkn_ == comma_tkn_)
tkn_ = GetToken();
else
break;
}
if(tkn_ != rpair_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != error_tkn_)
return false;
//parse
if(fieldlist_.size() != valuelist_.size())
{
AfxMessageBox("输入字段个数与数值个数不等!");
return false;
}
if(engine_->InsertTuple(tablename_, fieldlist_, valuelist_))
{
// engine_->SaveTable(tablename_);//将数据保存到外存
return true;
}
return 0;
}
bool xkSQLParser::CreatetableFunc()
{
Token tkn_ = GetToken();
if(tkn_ != table_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
return false;
tablename_ = identifier_vec_[0];
tkn_ = GetToken();
if(tkn_ != lpair_tkn_)
return false;
tkn_ = GetToken();
Vector<char*> fieldlist_;
Vector<int> typelist_;
while(1)
{
if(tkn_ != identifier_tkn_)
return false;
fieldlist_.push_back(identifier_vec_[identifier_vec_.size() - 1]);
tkn_ = GetToken();
if(tkn_ != tint_tkn_ && tkn_ != tfloat_tkn_ && tkn_ != identifier_tkn_)
return false;
char* tmp_ = identifier_vec_[identifier_vec_.size() - 1];
if(strlen(tmp_) == strlen("int") && strcmp(tmp_, "int") == 0)
typelist_.push_back(0);
else if(strlen(tmp_) == strlen("float") && strcmp(tmp_, "float") == 0)
typelist_.push_back(1);
else if(strlen(tmp_) == strlen("string") && strcmp(tmp_, "string") == 0)
typelist_.push_back(2);
else if(strlen(tmp_) == strlen("char") && strcmp(tmp_, "char") == 0)
typelist_.push_back(3);
tkn_ = GetToken();
if(tkn_ == comma_tkn_)
tkn_ = GetToken();
else
break;
}
if(tkn_ != rpair_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != error_tkn_)
return false;
if(fieldlist_.size() != typelist_.size())
return false;
Vector<bool> keylist_;//第一个属性为关键字
for(size_t i = 0; i < fieldlist_.size(); i++)
{
if(i == 0)
keylist_.push_back(true);
else
keylist_.push_back(false);
}
if(engine_->CreateRelation(tablename_, fieldlist_, typelist_, keylist_,fieldlist_.size()))
return true;
return 0;
}
bool xkSQLParser::DroptableFunc()
{
Token tkn_ = GetToken();
if(tkn_ != table_tkn_)
return false;
tkn_ = GetToken();
if(tkn_ != identifier_tkn_)
return false;
tablename_ = identifier_vec_[0];
tkn_ = GetToken();
if(tkn_ != error_tkn_)
return false;
//processing...
if(engine_->DropRelation(tablename_))
return true;
return 0;
}
int xkSQLParser::FindTable(const char* tname_)
{
return engine_->FindTable(tname_);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -