80 lines
1.6 KiB
C++
80 lines
1.6 KiB
C++
#include "SqlParser.h"
|
|
#include "SqlAstSelect.h"
|
|
#include <unordered_map>
|
|
|
|
using namespace SqlAst;
|
|
|
|
Keyword isKeyword(const QString &symbol)
|
|
{
|
|
static std::unordered_map<std::string, Keyword> lookup_map = {
|
|
{ "as", Keyword::As },
|
|
{ "by", Keyword::By },
|
|
{ "delete", Keyword::Delete },
|
|
{ "from", Keyword::From },
|
|
{ "group", Keyword::Group },
|
|
{ "insert", Keyword::Insert },
|
|
{ "order", Keyword::Order },
|
|
{ "select", Keyword::Select },
|
|
{ "update", Keyword::Update },
|
|
{ "where", Keyword::Where }
|
|
};
|
|
|
|
auto res = lookup_map.find(symbol.toLower().toUtf8().data());
|
|
if (res != lookup_map.end())
|
|
return res->second;
|
|
|
|
return Keyword::NotAKeyword;
|
|
}
|
|
|
|
|
|
SqlParser::SqlParser(SqlLexer &lexer)
|
|
: lexer(lexer)
|
|
{
|
|
|
|
}
|
|
|
|
std::shared_ptr<SqlAst::Node> SqlParser::parse()
|
|
{
|
|
// Basic algo:
|
|
// LOOP
|
|
// GET token
|
|
// IF NOT try_reduce(token)
|
|
// THEN SHIFT
|
|
// END LOOP
|
|
std::shared_ptr<SqlAst::Node> result;
|
|
while (true) {
|
|
SqlToken token = lexer.nextBasicToken();
|
|
if (token.ok) {
|
|
if (token.tokenType == BasicTokenType::Symbol) {
|
|
Keyword kw = isKeyword(token.out);
|
|
switch (kw) {
|
|
case Keyword::Select:
|
|
parseSelect(*this);
|
|
break;
|
|
|
|
case Keyword::NotAKeyword:
|
|
default:
|
|
// unexpected
|
|
break;
|
|
}
|
|
}
|
|
else if (token.tokenType == BasicTokenType::End) {
|
|
// Are we at the top level?
|
|
return result;
|
|
}
|
|
}
|
|
else {
|
|
// error during lexical analysis, need to recover
|
|
throw std::runtime_error("Unrecognized input");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//bool try_reduce(SqkToken token)
|
|
//{
|
|
// // what state are we in? what are we expecting
|
|
|
|
//}
|