📄 analysewords.cpp
字号:
////////////////////////////////////////////////////////////
//
//
//
//
////////////////////////////////////////////////////////////
#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 + -