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

📄 sqlparse.cpp

📁 表达式分析, 支持算术运算,括号,关系运算,逻辑运算,字符串的like运算等。采用了有限自动机做词法分析, 语法分析用算符优先分析方法
💻 CPP
字号:
#include "sqlparse.h"
#include <stack>
using namespace std;

cSQLParse::cSQLParse()
{
	m_tl=NULL; 
	strcpy(m_error_msg, "No error occurred!");
}

unsigned char cSQLParse::CheckIdentifierType(char* name, std::vector<FieldInfo>& fieldTable)
{
	std::vector<FieldInfo>::iterator iter;
	int a = fieldTable.size();
	for(iter = fieldTable.begin(); iter != fieldTable.end(); iter ++)
	{
		FieldInfo fi = *iter;
		if( strcmp(fi.fieldName, name) == 0 )
		{
			if(fi.fieldType == 1 || fi.fieldType == 2)
				return 1;
			else
				return 2;
		}
	}
	return 0;
}

bool cSQLParse::CheckExpressLogic(std::vector<FieldInfo>& fieldInfoTable)
{
	stack<Token> st;
	Token t1, t2;
	unsigned char type;
	list<Token>::iterator iter;
	FieldInfo fi;
	m_idTypeTable.clear();
	for(iter = m_tl->begin(); iter != m_tl->end(); iter++)
	{
		Token token = *iter;
		switch(token.type)
		{
		case IDENTIFIER:
			strcpy(fi.fieldName, token.str_val);
			type = CheckIdentifierType(token.str_val, fieldInfoTable);
			if(type == 0)
			{
				sprintf(m_error_msg, "Unknown variable name: %s", token.str_val);
				return false;
			}
			else if(type == 1)
			{
				fi.fieldType = 1;
				m_idTypeTable.push_back(fi);
				int a = m_idTypeTable.size();
				token.type = CONSTANT;
				st.push(token);
			}
			else
			{
				fi.fieldType = 3;
				m_idTypeTable.push_back(fi);
				int a = m_idTypeTable.size();
				token.type = STRING;
				st.push(token);
			}
			break;
		case CONSTANT:
			st.push(token);
			break;
		case STRING:
			st.push(token);
			break;
		case PERIOD:
			strcpy(m_error_msg, "Period is not supported now!");
			return false;
			break;
		case POSTIVE:
			t1 = st.top();
			st.pop();
			if(t1.type == STRING)
			{
				strcpy(m_error_msg, "Postive operator cannot operate on String!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case NEGTIVE:
			t1 = st.top();
			st.pop();
			if(t1.type == STRING)
			{
				strcpy(m_error_msg, "Negative operator cannot operate on String!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case NOT:
			t1 = st.top();
			st.pop();
			if(t1.type == STRING)
			{
				strcpy(m_error_msg, "Not operator cannot oprate on String!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case MULTI:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Multi operator cannot oprate on String!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case DIV:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Div operator cannot oprate on String!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case REMAINDER:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Remainder operator cannot oprate on String!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case PLUS:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Plus operator cannot oprate on String!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case MINUS:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Minus operator cannot oprate on String!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case GREAT:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Greate operator cannot match!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case LESS:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Less operator cannot match!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case GREATEQ:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Ge operator cannot match!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case LESSEQ:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Le operator cannot match!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case LIKE:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type != STRING || t2.type != STRING)
			{
				strcpy(m_error_msg, "Operands of LIKE operator cannot use here!");
				return false;
			}
			t1.type = CONSTANT;;
			st.push(t1);
			break;
		case EQ:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Eq operator cannot match!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case NOTEQ:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Eq operator cannot match!");
				return false;
			}
			t1.type = CONSTANT;
			st.push(t1);
			break;
		case AND:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Operands of And operator cannot match!");
				return false;
			}
			st.push(t1);
			break;
		case OR:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Operands of Or operator cannot match!");
				return false;
			}
			st.push(t1);
			break;
		default:
			strcpy(m_error_msg, "Unknown fatal error occured!");
			return false;
			break;
		}
	}
	return true;
}

bool cSQLParse::SQLPreCompile(char* str, std::vector<FieldInfo>& fieldInfoTable)
{
	if(m_tl = m_ga.GrammerAnalysis(str))
	{
		return CheckExpressLogic(fieldInfoTable);
	}
	strcpy(m_error_msg, m_ga.GetLastErrer());
	m_tl = NULL;
	return false;
}

bool cSQLParse::GetIdentifierValue(char* name, std::vector<FieldValueInfo>& valueInfoTable, 
									Token & token)
{
	char type = CheckIdentifierType(name, m_idTypeTable);
	vector<FieldValueInfo>::iterator iter;
	for(iter = valueInfoTable.begin(); iter != valueInfoTable.end(); iter++)
	{
		FieldValueInfo fvi = *iter;
		if( strcmp(fvi.fieldName, name) == 0 )
		{
			if(type == 1)
			{
				token.type = 1;
				token.num_val = fvi.numberValue;
			}
			else if(type == 2)
			{
				token.type = 2;
				strcpy(token.str_val, fvi.stringvalue);
			}
			else
				return false;
			return true;
		}
	}
	return false;
}

bool cSQLParse::SQLInputValue(std::vector<FieldValueInfo>& valueInfoTable, Token& t)
{
	stack<Token> st;
	Token t1, t2;
	unsigned char type;
	list<Token>::iterator iter;
	FieldInfo fi;
	for(iter = m_tl->begin(); iter != m_tl->end(); iter++)
	{
		Token token = *iter;
		switch(token.type)
		{
		case IDENTIFIER:
			if(GetIdentifierValue(token.str_val, valueInfoTable, token))
			{
				st.push(token);
			}
			else
			{
				sprintf(m_error_msg, "No value of name: %s", token.str_val);
				return false;
			}
			break;
		case CONSTANT:
			token.type = 1;
			st.push(token);
			break;
		case STRING:
			token.type = 2;
			st.push(token);
			break;
		case PERIOD:
			strcpy(m_error_msg, "Period is not supported now!");
			return false;
			break;
		case POSTIVE:
			t1 = st.top();
			st.pop();
			if(t1.type == STRING)
			{
				strcpy(m_error_msg, "Postive operator cannot operate on String!");
				return false;
			}
			t1.type = 1;
			st.push(t1);
			break;
		case NEGTIVE:
			t1 = st.top();
			st.pop();
			if(t1.type == STRING)
			{
				strcpy(m_error_msg, "Negative operator cannot operate on String!");
				return false;
			}
			t1.type = 1;
			t1.num_val = -t1.num_val;
			st.push(t1);
			break;
		case NOT:
			t1 = st.top();
			st.pop();
			if(t1.type == STRING)
			{
				strcpy(m_error_msg, "Not operator cannot oprate on String!");
				return false;
			}
			t1.type = 1;
			t1.num_val = !t1.num_val;
			st.push(t1);
			break;
		case MULTI:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Multi operator cannot oprate on String!");
				return false;
			}
			t1.type = 1;
			t1.num_val *= t2.num_val;
			st.push(t1);
			break;
		case DIV:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Div operator cannot oprate on String!");
				return false;
			}
			if(t2.num_val == 0)
			{
				strcpy(m_error_msg, "Divide by zero ocurred!");
				return false;
			}
			t1.type = 1;
			t1.num_val /= t2.num_val;
			st.push(t1);
			break;
		case REMAINDER:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Remainder operator cannot oprate on String!");
				return false;
			}
			if(t2.num_val == 0)
			{
				strcpy(m_error_msg, "Divide by zero ocurred!");
				return false;
			}
			t1.type = 1;
			t1.num_val = (int)((int)t1.num_val % (int)t2.num_val);
			st.push(t1);
			break;
		case PLUS:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Plus operator cannot oprate on String!");
				return false;
			}
			t1.type = 1;
			t1.num_val += t2.num_val;
			st.push(t1);
			break;
		case MINUS:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Minus operator cannot oprate on String!");
				return false;
			}
			t1.type = 1;
			t1.num_val -= t2.num_val;
			st.push(t1);
			break;
		case GREAT:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Greate operator cannot match!");
				return false;
			}
			if(t1.type == 1)
				t1.num_val = (t1.num_val > t2.num_val) ? 1 : 0;
			else if(t1.type == 2)
				t1.num_val = (strcmp(t1.str_val, t2.str_val) > 0) ? 1 : 0;
			else
			{
				strcpy(m_error_msg, "Unknown fatal error ocurred!");
				return false;
			}
			t1.type = 1;
			st.push(t1);
			break;
		case LESS:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Less operator cannot match!");
				return false;
			}
			if(t1.type == 1)
				t1.num_val = (t1.num_val < t2.num_val) ? 1 : 0;
			else if(t1.type == 2)
				t1.num_val = (strcmp(t1.str_val, t2.str_val) < 0) ? 1 : 0;
			else
			{
				strcpy(m_error_msg, "Unknown fatal error ocurred!");
				return false;
			}
			t1.type = 1;
			st.push(t1);
			break;
		case GREATEQ:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Ge operator cannot match!");
				return false;
			}
			if(t1.type == 1)
				t1.num_val = (t1.num_val >= t2.num_val) ? 1 : 0;
			else if(t1.type == 2)
				t1.num_val = (strcmp(t1.str_val, t2.str_val) >= 0) ? 1 : 0;
			else
			{
				strcpy(m_error_msg, "Unknown fatal error ocurred!");
				return false;
			}
			t1.type = 1;
			st.push(t1);
			break;
		case LESSEQ:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Le operator cannot match!");
				return false;
			}
			if(t1.type == 1)
				t1.num_val = (t1.num_val <= t2.num_val) ? 1 : 0;
			else if(t1.type == 2)
				t1.num_val = (strcmp(t1.str_val, t2.str_val) <= 0) ? 1 : 0;
			else
			{
				strcpy(m_error_msg, "Unknown fatal error ocurred!");
				return false;
			}
			t1.type = 1;
			st.push(t1);
			break;
		case LIKE:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type != STRING || t2.type != STRING)
			{
				strcpy(m_error_msg, "Operands of LIKE operator cannot use here!");
				return false;
			}
			t1.num_val = (strstr(t2.str_val, t1.str_val) != 0) ? 1 : 0;
			t1.type = 1;
			st.push(t1);
			break;
		case EQ:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Eq operator cannot match!");
				return false;
			}
			if(t1.type == 1)
				t1.num_val = (t1.num_val == t2.num_val) ? 1 : 0;
			else if(t1.type == 2)
				t1.num_val = (strcmp(t1.str_val, t2.str_val) == 0) ? 1 : 0;
			else
			{
				strcpy(m_error_msg, "Unknown fatal error ocurred!");
				return false;
			}
			t1.type = 1;
			st.push(t1);
			break;
		case NOTEQ:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type != t2.type)
			{
				strcpy(m_error_msg, "Operands of Eq operator cannot match!");
				return false;
			}
			if(t1.type == 1)
				t1.num_val = (t1.num_val != t2.num_val) ? 1 : 0;
			else if(t1.type == 2)
				t1.num_val = (strcmp(t1.str_val, t2.str_val) != 0) ? 1 : 0;
			else
			{
				strcpy(m_error_msg, "Unknown fatal error ocurred!");
				return false;
			}
			t1.type = 1;
			st.push(t1);
			break;
		case AND:
			t2 = st.top();
			st.pop();
			t1 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Operands of And operator cannot match!");
				return false;
			}
			t1.num_val = t1.num_val && t2.num_val;
			t1.type = 1;
			st.push(t1);
			break;
		case OR:
			t1 = st.top();
			st.pop();
			t2 = st.top();
			st.pop();
			if(t1.type == STRING || t2.type == STRING)
			{
				strcpy(m_error_msg, "Operands of Or operator cannot match!");
				return false;
			}
			t1.num_val = t1.num_val || t2.num_val;
			t1.type = 1;
			st.push(t1);
			break;
		default:
			strcpy(m_error_msg, "Unknown fatal error occured!");
			return false;
			break;
		}
	}
	t = st.top();
	return true;
}

char* cSQLParse::GetLastError()
{
	return m_error_msg;
}

⌨️ 快捷键说明

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