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

📄 xksqlparser.cpp

📁 简单数据库管理系统
💻 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 + -