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

This commit is contained in:
Alexey Milovidov 2017-07-12 22:20:57 +03:00 committed by alexey-milovidov
parent 65955d50e7
commit 4255b81f3f
12 changed files with 62 additions and 43 deletions

View File

@ -156,8 +156,7 @@ AggregateFunctionPtr AggregateFunctionFactory::getImpl(const String & name, cons
if (argument_types.empty())
throw Exception{
"Incorrect number of arguments for aggregate function " + name,
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH
};
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
/// For aggregate functions of the form `aggIf`, where `agg` is the name of another aggregate function.
DataTypes nested_dt = argument_types;

View File

@ -22,8 +22,7 @@ AggregateFunctionPtr createAggregateFunctionQuantileDeterministic(const std::str
throw Exception{
"Illegal type " + determinator_type->getName() + " of second argument for aggregate function " + name +
", Int32, UInt32, Int64 or UInt64 required",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT
};
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
}
const IDataType & argument_type = *argument_types[0];
@ -59,8 +58,7 @@ AggregateFunctionPtr createAggregateFunctionQuantilesDeterministic(const std::st
throw Exception{
"Illegal type " + determinator_type->getName() + " of second argument for aggregate function " + name +
", Int32, UInt32, Int64 or UInt64 required",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT
};
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
}
const IDataType & argument_type = *argument_types[0];

View File

@ -62,8 +62,7 @@ public:
throw Exception{
"Invalid type of second argument to function " + getName() +
", got " + arguments[1]->getName() + ", expected numeric",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT
};
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
}
void setParameters(const Array & params) override
@ -142,8 +141,7 @@ public:
throw Exception{
"Invalid type of second argument to function " + getName() +
", got " + arguments[1]->getName() + ", expected numeric",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT
};
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
}
void setParameters(const Array & params) override

View File

@ -147,8 +147,7 @@ public:
if (params.size() != 1)
throw Exception{
"Aggregate function " + getName() + " requires exactly one parameter.",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH
};
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
pattern = params.front().safeGet<std::string>();
}

View File

@ -88,8 +88,7 @@ inline DataTypePtr parseEnum(const String & name, const String & base_name, cons
if (value > std::numeric_limits<FieldType>::max() || value < std::numeric_limits<FieldType>::min())
throw Exception{
"Value " + applyVisitor(FieldVisitorToString{}, e.value) + " for element '" + e.name + "' exceeds range of " + base_name,
ErrorCodes::ARGUMENT_OUT_OF_BOUND
};
ErrorCodes::ARGUMENT_OUT_OF_BOUND};
values.emplace_back(e.name, value);
}

View File

@ -41,7 +41,7 @@ bool ParserKeyword::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
const char * next_whitespace = find_first_symbols<' ', '\0'>(current_word, s_end);
size_t word_length = next_whitespace - current_word;
if (static_cast<ptrdiff_t>(word_length) != pos->size())
if (word_length != pos->size())
return false;
if (strncasecmp(pos->begin, current_word, word_length))

View File

@ -396,6 +396,14 @@ bool ParserNull::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
bool ParserNumber::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
bool negative = false;
if (pos->type == TokenType::Minus)
{
++pos;
negative = true;
}
Field res;
Pos begin = pos;
@ -427,23 +435,25 @@ bool ParserNumber::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
return false;
}
if (float_value < 0)
throw Exception("Logical error: token number cannot begin with minus, but parsed float number is less than zero.", ErrorCodes::LOGICAL_ERROR);
if (negative)
float_value = -float_value;
res = float_value;
/// try to use more exact type: UInt64 or Int64
/// try to use more exact type: UInt64
char * pos_integer = buf;
if (float_value < 0)
errno = 0;
UInt64 uint_value = std::strtoull(buf, &pos_integer, 0);
if (pos_integer == pos_double && errno != ERANGE && (!negative || uint_value < static_cast<UInt64>(std::numeric_limits<Int64>::max())))
{
errno = 0;
Int64 int_value = std::strtoll(buf, &pos_integer, 0);
if (pos_integer == pos_double && errno != ERANGE)
res = int_value;
}
else
{
errno = 0;
UInt64 uint_value = std::strtoull(buf, &pos_integer, 0);
if (pos_integer == pos_double && errno != ERANGE)
if (negative)
res = -static_cast<Int64>(uint_value);
else
res = uint_value;
}

View File

@ -1,5 +1,7 @@
#pragma once
#include <stddef.h>
namespace DB
{
@ -65,7 +67,7 @@ struct Token
const char * begin;
const char * end;
auto size() const { return end - begin; }
size_t size() const { return end - begin; }
Token() = default;
Token(TokenType type, const char * begin, const char * end) : type(type), begin(begin), end(end) {}
@ -82,8 +84,6 @@ private:
const char * const begin;
const char * pos;
const char * const end;
void skipWhitespacesAndComments();
};
}

View File

@ -1,7 +1,7 @@
#include <Parsers/ParserEnumElement.h>
#include <Parsers/ASTEnumElement.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/ExpressionElementParsers.h>
namespace DB
@ -9,7 +9,10 @@ namespace DB
bool ParserEnumElement::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserStringLiteral name_parser;
ParserNumber value_parser;
ParserToken equality_sign_parser(TokenType::Equals);
const auto begin = pos;
ASTPtr name;

View File

@ -1,18 +1,14 @@
#pragma once
#include <Parsers/IParserBase.h>
#include <Parsers/ExpressionElementParsers.h>
namespace DB
{
class ParserEnumElement : public IParserBase
{
ParserStringLiteral name_parser;
ParserNumber value_parser;
protected:
const char * getName() const override { return "enum element"; }
const char * getName() const override { return "Enum element"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};

View File

@ -16,8 +16,23 @@ struct StringRange
StringRange() {}
StringRange(const char * begin, const char * end) : first(begin), second(end) {}
StringRange(TokenIterator token_begin, TokenIterator token_end) : first(token_begin->begin), second(token_end->begin) {}
StringRange(TokenIterator token) : first(token->begin), second(token->end) {}
StringRange(TokenIterator token_begin, TokenIterator token_end)
{
/// Empty range.
if (token_begin == token_end)
{
first = token_begin->begin;
second = token_begin->begin;
}
TokenIterator token_last = token_end;
--token_last;
first = token_begin->begin;
second = token_last->end;
}
};
using StringPtr = std::shared_ptr<String>;

View File

@ -11,7 +11,9 @@ namespace DB
* It could do lookaheads of any depth.
*/
/// Used as an input for parsers.
/** Used as an input for parsers.
* All whitespace and comment tokens are transparently skipped.
*/
class Tokens
{
private:
@ -55,11 +57,11 @@ public:
const Token & operator*() { return get(); }
const Token * operator->() { return &get(); }
TokenIterator & operator++()
{
++index;
return *this;
}
TokenIterator & operator++() { ++index; return *this; }
TokenIterator & operator--() { --index; return *this; }
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; }
};