Using lexer (development) [#CLICKHOUSE-2].

This commit is contained in:
Alexey Milovidov 2017-07-12 23:45:27 +03:00 committed by alexey-milovidov
parent 4562785c2a
commit 57d2f5d0e6
2 changed files with 28 additions and 8 deletions

View File

@ -40,6 +40,13 @@ public:
data.emplace_back(token); data.emplace_back(token);
} }
} }
const Token & max()
{
if (data.empty())
return (*this)[0];
return data.back();
}
}; };
@ -64,6 +71,8 @@ public:
bool operator== (const TokenIterator & rhs) const { return index == rhs.index; } bool operator== (const TokenIterator & rhs) const { return index == rhs.index; }
bool isValid() { return get().type < TokenType::EndOfStream; } bool isValid() { return get().type < TokenType::EndOfStream; }
const Token & max() { return tokens->max(); }
}; };
} }

View File

@ -134,30 +134,40 @@ ASTPtr tryParseQuery(
ASTPtr res; ASTPtr res;
bool parse_res = parser.parse(token_iterator, res, expected); bool parse_res = parser.parse(token_iterator, res, expected);
const char * max_parsed_pos = token_iterator.max().begin;
/// Lexical error /// Lexical error
if (!parse_res && token_iterator->type > TokenType::EndOfStream) if (!parse_res && token_iterator->type > TokenType::EndOfStream)
{ {
expected = "any valid token"; expected = "any valid token";
out_error_message = getSyntaxErrorMessage(begin, end, token_iterator->begin, expected, hilite, description); out_error_message = getSyntaxErrorMessage(begin, end, max_parsed_pos, expected, hilite, description);
return nullptr; return nullptr;
} }
/// Excessive input after query. Parsed query must end with end of data or semicolon. /// Excessive input after query. Parsed query must end with end of data or semicolon or data for INSERT.
if (parse_res && token_iterator->type != TokenType::EndOfStream && token_iterator->type != TokenType::Semicolon) ASTInsertQuery * insert = nullptr;
if (parse_res)
insert = typeid_cast<ASTInsertQuery *>(res.get());
if (parse_res
&& token_iterator->type != TokenType::EndOfStream
&& token_iterator->type != TokenType::Semicolon
&& !(insert && insert->data))
{ {
expected = "end of query"; expected = "end of query";
out_error_message = getSyntaxErrorMessage(begin, end, token_iterator->begin, expected, hilite, description); out_error_message = getSyntaxErrorMessage(begin, end, max_parsed_pos, expected, hilite, description);
return nullptr; return nullptr;
} }
/// If multi-statements are not allowed, then after semicolon, there must be no non-space characters.
while (token_iterator->type == TokenType::Semicolon) while (token_iterator->type == TokenType::Semicolon)
++token_iterator; ++token_iterator;
if (parse_res && !allow_multi_statements && token_iterator->type != TokenType::EndOfStream) /// If multi-statements are not allowed, then after semicolon, there must be no non-space characters.
if (parse_res && !allow_multi_statements
&& token_iterator->type != TokenType::EndOfStream
&& !(insert && insert->data))
{ {
out_error_message = getSyntaxErrorMessage(begin, end, token_iterator->begin, nullptr, hilite, out_error_message = getSyntaxErrorMessage(begin, end, max_parsed_pos, nullptr, hilite,
(description.empty() ? std::string() : std::string(". ")) + "Multi-statements are not allowed"); (description.empty() ? std::string() : std::string(". ")) + "Multi-statements are not allowed");
return nullptr; return nullptr;
} }
@ -165,10 +175,11 @@ ASTPtr tryParseQuery(
/// Parse error. /// Parse error.
if (!parse_res) if (!parse_res)
{ {
out_error_message = getSyntaxErrorMessage(begin, end, token_iterator->begin, expected, hilite, description); out_error_message = getSyntaxErrorMessage(begin, end, max_parsed_pos, expected, hilite, description);
return nullptr; return nullptr;
} }
pos = token_iterator->begin;
return res; return res;
} }