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

📄 analysewords.cpp

📁 our homework big project
💻 CPP
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////
//													
//
//
//
////////////////////////////////////////////////////////////

#include "AnalyseWords.h"
#include "Exception.h"

const int namesize=16;					//列名与表名的最大长度
const int sizemax=255;					//char(n)中n的最大值
const int attrmax=32;					//属性数量的最大值


//关键字的常量定义
const char* keyword[]=
{
	"create", "drop",
	"insert", "delete", "select",
	"table", "index", "unique",
	"primary", "key",
	"from", "where",
	"on", "into", "values", "and",
	"int", "char", "float",
	"=", "!=", "<=", ">=", "<", ">",
	"(", ")",
	"*", ",",
	";"
};


//初始化关键字与符号映射表
map<string,TokenValue> TokenMap;

void AnalyseWords::InitToken()
{
	TokenMap.clear();
	for(int i=0; i<(sizeof(keyword)/sizeof(*keyword)); i++)
		TokenMap[keyword[i]]=TokenValue(i);
}



//获得单词对应的符号
TokenValue AnalyseWords::GetToken(int position)
{
	if(TokenMap.find(m_word[position]) != TokenMap.end())
		return TokenMap[m_word[position]];
	else if(m_word[position].find('\'') == 0 &&
		    m_word[position].rfind('\'') == m_word[position].size()-1)
		return _CONSTSTRING;
	else if(m_word[position].find('\'') == 0 &&
		    m_word[position].rfind('\'') != m_word[position].size()-1)
		throw ErrorPos(ID_ERROR_QUOTE,-1);
	else
		return _STRING;
}


//预分析命令,确定属于SQL中的哪一条命令
int AnalyseWords::PreAnalyseSQL(int position,int line)
{
	switch(GetToken(position))
	{
	
	case _CREATE:
		switch(GetToken(position+1))
		{
		case TABLE :
			return 1;
		case INDEX :
			return 2;
		default :
			throw ErrorPos(ID_ERROR_CREATE,line);						//语句中与关键字create不匹配
		}
	
	case _DROP:
		switch(GetToken(position+1))
		{
		case TABLE :
			return 3;
		case INDEX :
			return 4;
		default :
			throw ErrorPos(ID_ERROR_DROP,line);						//语句中与关键字drop不匹配
		}
		
	case _INSERT:
		return 5;

	case _DELETE:
		return 6;

	case _SELECT:
		return 7;

	default : 
		throw ErrorPos(ID_ERROR_NOKEYWORD,line);						//语句第一个为非关键字

	}
}

//分析字符串中是否含有非法字符
bool AnalyseWords::AnIllegalChars(const string &ss)
{
	for(int i=0; i<ss.size(); i++)
	{
		if(ss[i] == '\\' && ss[i] == '/' &&
			ss[i] == '?' && ss[i] == ':' &&
			ss[i] == '\"' && ss[i] == '|' )
		{
			return false;
		}
	}
	return true;
}
			


/////////////////////////////////////////////////////////////////
//        AnCreatTable类的成员函数定义                         //
/////////////////////////////////////////////////////////////////

// 分析create table命令大体框架
void AnCreateTable::AnalyseSQL(int position,int line)
{
	if(GetToken(position) != _STRING)
	{
		throw ErrorPos(ID_ERROR_TNAME,line);
	}
	else
	{
		if(!AnIllegalChars(m_word[position]))
		{
			throw ErrorPos(ID_ERROR_CHARS,line);									//表名中含有非法字符
		}
		if(m_word[position].size() > namesize)
		{
			throw ErrorPos(ID_ERROR_OVERNAMESIZE,line);							//表名太长
		}
		 strncpy(m_catahead.tname,m_word[position].c_str(),16);
	}
	
	if(GetToken(position+1) != LP)
	{
		throw ErrorPos(ID_ERROR_LP,line);
	}

	else
	{
		vector<int> v_comma;
		v_comma.push_back(position+1);

		for(int i=position+2; GetToken(i) != END; i++)
		{
			if(GetToken(i) == COMMA)
			{
				v_comma.push_back(i);
			}
		}

		if(GetToken(i-1) != RP)
		{
			throw ErrorPos(ID_ERROR_RP,line);												//缺少右括号
		}
		else 
		{
			v_comma.push_back(i-1);
		}

		if(v_comma.size() > attrmax)
		{
			throw ErrorPos(ID_ERROR_TOOMANYATTR,line);										//属性定义过多
		}
		
		m_catahead.number=v_comma.size()-1;
		char findPK=0;
		for(int j=0; j<v_comma.size()-1; j++)
			AnalyseAttr(v_comma[j]+1,v_comma[j+1]-1,line,findPK);
	}
}

//分析命令中的各属性含主键定义
void AnCreateTable::AnalyseAttr(int b_pos, int e_pos, int line,char &FoundCount)
{
	if(GetToken(b_pos) == _STRING)
	{
		if(!AnIllegalChars(m_word[b_pos]))
		{
			throw ErrorPos(ID_ERROR_CHARS,line);									//列名中含有非法字符
		}
		if(m_word[b_pos].size() > namesize)
		{
			throw ErrorPos(ID_ERROR_OVERNAMESIZE,line);								//列名长度过长
		}
		
		CatalogFile catatmp;
		
		switch(GetToken(b_pos+1))
		{
		case _CHAR:
			if(GetToken(b_pos+2) == LP &&
				GetToken(b_pos+3) == _STRING &&
				GetToken(b_pos+4) == RP)
			{
				string sizetmp=m_word[b_pos+3];
				for(int i=0; i<sizetmp.length(); i++)
				{
					if(!isdigit(sizetmp[i]))
						throw ErrorPos(ID_ERROR_SIZE,line);
				}
				if(atoi(sizetmp.c_str()) > sizemax)
					throw ErrorPos(ID_ERROR_OVERSIZE,line);
				else
				{
					
					if(b_pos+4 == e_pos)
					{
						catatmp.uniqueFlag = 0;
					}
					else if(GetToken(b_pos+5) == UNIQUE && b_pos+5 == e_pos)
					{
						catatmp.uniqueFlag=1;
					}
					else
					{
						throw ErrorPos(ID_ERROR_ATTR,line);
					}
					strncpy(catatmp.attrName,m_word[b_pos].c_str(),16);
					catatmp.primaryFlag = 0;
					catatmp.size = atoi(sizetmp.c_str())+3;
					catatmp.typeFlag=0;
					m_cata.push_back(catatmp);
				}
			}
			else 
			{
				throw ErrorPos(ID_ERROR_ATTR,line);
			}
			break;
					
		case _INT:
			if(b_pos+1 == e_pos)
			{
				catatmp.uniqueFlag=0;
			}
			else if(GetToken(b_pos+2) ==UNIQUE && b_pos+2 == e_pos)
			{
				catatmp.uniqueFlag=1;
			}
			else
			{
				throw ErrorPos(ID_ERROR_ATTR,line);
			}
			strncpy(catatmp.attrName,m_word[b_pos].c_str(),16);
			catatmp.primaryFlag = 0;
			catatmp.size=sizeof(int);
			catatmp.typeFlag=1;
			m_cata.push_back(catatmp);
			break;
		
		case _FLOAT:
			if(b_pos+1 == e_pos)
			{
				catatmp.uniqueFlag=0;
			}
			else if(GetToken(b_pos+2) ==UNIQUE && b_pos+2 == e_pos)
			{
				catatmp.uniqueFlag=1;
			}
			else
			{
				throw ErrorPos(ID_ERROR_ATTR,line);
			}
			strncpy(catatmp.attrName,m_word[b_pos].c_str(),16);
			catatmp.primaryFlag = 0;
			catatmp.size=sizeof(float);
			catatmp.typeFlag=2;
			m_cata.push_back(catatmp);
			break;
		
		default:
			throw ErrorPos(ID_ERROR_TYPE,line);
		}
	}
		
	else if(GetToken(b_pos) == PRIMARY &&
		    GetToken(b_pos+1) == KEY  &&
			GetToken(b_pos+2) == LP   &&
			GetToken(b_pos+3) == _STRING &&
			GetToken(b_pos+4) == RP && 
			e_pos-b_pos == 4)
	{
		
		for(int j=0; j<m_cata.size(); j++)
		{
			if(m_cata[j].attrName == m_word[b_pos+3])
			{
				m_cata[j].primaryFlag=1;
				m_cata[j].uniqueFlag=1;
				FoundCount++;
				m_catahead.number--;
			}
			
		}
		if(!FoundCount)
		{
			throw ErrorPos(ID_ERROR_NOATTR,line);								//找不到定义为主键的属性
		}
		if(FoundCount>1)
		{
			throw ErrorPos(ID_ERROR_REPETEKEY,line);
		}
		
	}
	else 
	{
		throw ErrorPos(ID_ERROR_PRIMARYKEY,line);							
	}
		
}


////////////////////////////////////////////////////////////////////
//        AnCreateIndex类的成员函数的定义                          //
////////////////////////////////////////////////////////////////////

void AnCreateIndex::AnalyseSQL(int position,int line)
{
	if(GetToken(position) == _STRING)
	{
		
		if(!AnIllegalChars(m_word[position]))

⌨️ 快捷键说明

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