2010-06-24 19:12:10 +00:00
|
|
|
|
#include <DB/Parsers/IAST.h>
|
|
|
|
|
#include <DB/Parsers/ASTExpressionList.h>
|
|
|
|
|
#include <DB/Parsers/ASTFunction.h>
|
|
|
|
|
|
|
|
|
|
#include <DB/Parsers/CommonParsers.h>
|
|
|
|
|
#include <DB/Parsers/ExpressionElementParsers.h>
|
|
|
|
|
|
|
|
|
|
#include <DB/Parsers/ExpressionListParsers.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
2011-08-18 18:48:00 +00:00
|
|
|
|
|
|
|
|
|
bool ParserList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
|
|
|
{
|
|
|
|
|
bool first = true;
|
|
|
|
|
ParserWhiteSpaceOrComments ws;
|
|
|
|
|
|
|
|
|
|
ASTExpressionList * list = new ASTExpressionList;
|
|
|
|
|
node = list;
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
if (first)
|
|
|
|
|
{
|
|
|
|
|
ASTPtr elem;
|
|
|
|
|
if (!elem_parser->parse(pos, end, elem, expected))
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
list->children.push_back(elem);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
if (!separator_parser->ignore(pos, end, expected))
|
|
|
|
|
break;
|
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
|
|
|
|
|
ASTPtr elem;
|
|
|
|
|
if (!elem_parser->parse(pos, end, elem, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
list->children.push_back(elem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
first = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!allow_empty && first)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
|
|
|
{
|
|
|
|
|
bool first = true;
|
|
|
|
|
ParserWhiteSpaceOrComments ws;
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
if (first)
|
|
|
|
|
{
|
|
|
|
|
ASTPtr elem;
|
|
|
|
|
if (!elem_parser->parse(pos, end, elem, expected))
|
2010-06-25 19:55:19 +00:00
|
|
|
|
return false;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
|
|
|
|
node = elem;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
|
|
|
|
|
/// пробуем найти какой-нибудь из допустимых операторов
|
|
|
|
|
Pos begin = pos;
|
|
|
|
|
Operators_t::const_iterator it;
|
|
|
|
|
for (it = operators.begin(); it != operators.end(); ++it)
|
|
|
|
|
{
|
2011-10-17 08:28:39 +00:00
|
|
|
|
ParserString op(it->first, true, true);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
if (op.ignore(pos, end, expected))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it == operators.end())
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
|
|
|
|
|
/// функция, соответствующая оператору
|
2010-06-25 16:36:13 +00:00
|
|
|
|
ASTFunction * p_function = new ASTFunction;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
ASTFunction & function = *p_function;
|
|
|
|
|
ASTPtr function_node = p_function;
|
|
|
|
|
|
|
|
|
|
/// аргументы функции
|
2010-06-25 16:36:13 +00:00
|
|
|
|
ASTExpressionList * p_exp_list = new ASTExpressionList;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
ASTExpressionList & exp_list = *p_exp_list;
|
|
|
|
|
ASTPtr exp_list_node = p_exp_list;
|
|
|
|
|
|
|
|
|
|
ASTPtr elem;
|
|
|
|
|
if (!elem_parser->parse(pos, end, elem, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
/// первым аргументом функции будет предыдущий элемент, вторым - следующий
|
|
|
|
|
function.range.first = begin;
|
|
|
|
|
function.range.second = pos;
|
|
|
|
|
function.name = it->second;
|
|
|
|
|
function.arguments = exp_list_node;
|
2011-08-13 21:05:18 +00:00
|
|
|
|
function.children.push_back(exp_list_node);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
|
|
|
|
exp_list.children.push_back(node);
|
|
|
|
|
exp_list.children.push_back(elem);
|
2012-09-23 06:16:42 +00:00
|
|
|
|
exp_list.range.first = begin;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
exp_list.range.second = pos;
|
|
|
|
|
|
|
|
|
|
/** специальное исключение для оператора доступа к элементу массива x[y], который
|
|
|
|
|
* содержит инфиксную часть '[' и суффиксную ']' (задаётся в виде '[')
|
|
|
|
|
*/
|
|
|
|
|
if (it->first == "[")
|
|
|
|
|
{
|
|
|
|
|
ParserString rest_p("]");
|
|
|
|
|
|
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
if (!rest_p.ignore(pos, end, expected))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
node = function_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
first = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-09-23 06:16:42 +00:00
|
|
|
|
bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
|
|
|
{
|
|
|
|
|
ParserWhiteSpaceOrComments ws;
|
|
|
|
|
ParserString symbol1("?");
|
|
|
|
|
ParserString symbol2(":");
|
|
|
|
|
|
|
|
|
|
ASTPtr elem_cond;
|
|
|
|
|
ASTPtr elem_then;
|
|
|
|
|
ASTPtr elem_else;
|
|
|
|
|
|
|
|
|
|
Pos begin = pos;
|
|
|
|
|
|
|
|
|
|
if (!elem_parser->parse(pos, end, elem_cond, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
|
|
|
|
|
if (!symbol1.ignore(pos, end, expected))
|
|
|
|
|
node = elem_cond;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
|
|
|
|
|
if (!elem_parser->parse(pos, end, elem_then, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
|
|
|
|
|
if (!symbol2.ignore(pos, end, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
|
|
|
|
|
if (!elem_parser->parse(pos, end, elem_else, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
/// функция, соответствующая оператору
|
|
|
|
|
ASTFunction * p_function = new ASTFunction;
|
|
|
|
|
ASTFunction & function = *p_function;
|
|
|
|
|
ASTPtr function_node = p_function;
|
|
|
|
|
|
|
|
|
|
/// аргументы функции
|
|
|
|
|
ASTExpressionList * p_exp_list = new ASTExpressionList;
|
|
|
|
|
ASTExpressionList & exp_list = *p_exp_list;
|
|
|
|
|
ASTPtr exp_list_node = p_exp_list;
|
|
|
|
|
|
|
|
|
|
function.range.first = begin;
|
|
|
|
|
function.range.second = pos;
|
|
|
|
|
function.name = "if";
|
|
|
|
|
function.arguments = exp_list_node;
|
|
|
|
|
function.children.push_back(exp_list_node);
|
|
|
|
|
|
|
|
|
|
exp_list.children.push_back(elem_cond);
|
|
|
|
|
exp_list.children.push_back(elem_then);
|
|
|
|
|
exp_list.children.push_back(elem_else);
|
|
|
|
|
exp_list.range.first = begin;
|
|
|
|
|
exp_list.range.second = pos;
|
|
|
|
|
|
|
|
|
|
node = function_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-05-08 09:52:02 +00:00
|
|
|
|
bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
|
|
|
{
|
|
|
|
|
ParserWhiteSpaceOrComments ws;
|
|
|
|
|
ParserString arrow("->");
|
|
|
|
|
ParserString open("(");
|
|
|
|
|
ParserString close(")");
|
|
|
|
|
|
|
|
|
|
Pos begin = pos;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
ASTPtr inner_arguments;
|
|
|
|
|
ASTPtr expression;
|
|
|
|
|
|
|
|
|
|
if (!open.ignore(pos, end, expected))
|
|
|
|
|
break;
|
|
|
|
|
ws.ignore(pos, end, expected);
|
|
|
|
|
|
|
|
|
|
if (!ParserList(new ParserIdentifier, new ParserString(",")).parse(pos, end, inner_arguments, expected))
|
|
|
|
|
break;
|
|
|
|
|
ws.ignore(pos, end, expected);
|
|
|
|
|
|
|
|
|
|
if (!close.ignore(pos, end, expected))
|
|
|
|
|
break;
|
|
|
|
|
ws.ignore(pos, end, expected);
|
|
|
|
|
|
|
|
|
|
if (!arrow.ignore(pos, end, expected))
|
|
|
|
|
break;
|
|
|
|
|
ws.ignore(pos, end, expected);
|
|
|
|
|
|
|
|
|
|
if (!elem_parser->parse(pos, end, expression, expected))
|
|
|
|
|
{
|
|
|
|
|
pos = begin;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// lambda(tuple(inner_arguments), expression)
|
|
|
|
|
|
|
|
|
|
ASTFunction * lambda = new ASTFunction;
|
|
|
|
|
node = lambda;
|
|
|
|
|
lambda->name = "lambda";
|
|
|
|
|
|
|
|
|
|
ASTExpressionList * outer_arguments = new ASTExpressionList;
|
|
|
|
|
lambda->arguments = outer_arguments;
|
|
|
|
|
lambda->children.push_back(outer_arguments);
|
|
|
|
|
|
|
|
|
|
ASTFunction * tuple = new ASTFunction;
|
|
|
|
|
outer_arguments->children.push_back(tuple);
|
|
|
|
|
tuple->name = "tuple";
|
|
|
|
|
tuple->arguments = inner_arguments;
|
|
|
|
|
tuple->children.push_back(inner_arguments);
|
|
|
|
|
|
|
|
|
|
outer_arguments->children.push_back(expression);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
while (false);
|
|
|
|
|
|
|
|
|
|
pos = begin;
|
|
|
|
|
return elem_parser->parse(pos, end, node, expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
|
|
|
{
|
|
|
|
|
ParserWhiteSpaceOrComments ws;
|
|
|
|
|
|
|
|
|
|
/// пробуем найти какой-нибудь из допустимых операторов
|
|
|
|
|
Pos begin = pos;
|
|
|
|
|
Operators_t::const_iterator it;
|
|
|
|
|
for (it = operators.begin(); it != operators.end(); ++it)
|
|
|
|
|
{
|
2011-10-17 08:28:39 +00:00
|
|
|
|
ParserString op(it->first, true, true);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
if (op.ignore(pos, end, expected))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-25 19:55:19 +00:00
|
|
|
|
ws.ignore(pos, end);
|
|
|
|
|
|
2010-06-24 19:37:23 +00:00
|
|
|
|
ASTPtr elem;
|
|
|
|
|
if (!elem_parser->parse(pos, end, elem, expected))
|
2010-06-24 19:12:10 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2010-06-24 19:37:23 +00:00
|
|
|
|
if (it == operators.end())
|
|
|
|
|
node = elem;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/// функция, соответствующая оператору
|
2010-06-25 16:36:13 +00:00
|
|
|
|
ASTFunction * p_function = new ASTFunction;
|
2010-06-24 19:37:23 +00:00
|
|
|
|
ASTFunction & function = *p_function;
|
|
|
|
|
ASTPtr function_node = p_function;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2010-06-24 19:37:23 +00:00
|
|
|
|
/// аргументы функции
|
2010-06-25 16:36:13 +00:00
|
|
|
|
ASTExpressionList * p_exp_list = new ASTExpressionList;
|
2010-06-24 19:37:23 +00:00
|
|
|
|
ASTExpressionList & exp_list = *p_exp_list;
|
|
|
|
|
ASTPtr exp_list_node = p_exp_list;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2010-06-24 19:37:23 +00:00
|
|
|
|
function.range.first = begin;
|
|
|
|
|
function.range.second = pos;
|
|
|
|
|
function.name = it->second;
|
|
|
|
|
function.arguments = exp_list_node;
|
2011-08-13 21:05:18 +00:00
|
|
|
|
function.children.push_back(exp_list_node);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2010-06-24 19:37:23 +00:00
|
|
|
|
exp_list.children.push_back(elem);
|
2012-09-23 06:16:42 +00:00
|
|
|
|
exp_list.range.first = begin;
|
2010-06-24 19:37:23 +00:00
|
|
|
|
exp_list.range.second = pos;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2010-06-24 19:37:23 +00:00
|
|
|
|
node = function_node;
|
|
|
|
|
}
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-11-20 22:48:38 +00:00
|
|
|
|
bool ParserUnaryMinusExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
|
|
|
{
|
|
|
|
|
/// В качестве исключения, отрицательные числа должны парситься, как литералы, а не как применение оператора.
|
|
|
|
|
|
|
|
|
|
if (pos < end && *pos == '-')
|
|
|
|
|
{
|
|
|
|
|
ParserLiteral lit_p;
|
|
|
|
|
Pos begin = pos;
|
|
|
|
|
|
|
|
|
|
if (lit_p.parse(pos, end, node, expected))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
pos = begin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return operator_parser.parse(pos, end, node, expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
ParserAccessExpression::ParserAccessExpression()
|
2011-11-06 20:47:07 +00:00
|
|
|
|
: elem_parser(new ParserExpressionElement),
|
2010-06-24 19:12:10 +00:00
|
|
|
|
operator_parser(boost::assign::map_list_of
|
|
|
|
|
(".", "tupleElement")
|
|
|
|
|
("[", "arrayElement"),
|
|
|
|
|
elem_parser)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-11-06 20:47:07 +00:00
|
|
|
|
ParserExpressionWithOptionalAlias::ParserExpressionWithOptionalAlias()
|
2012-09-23 06:16:42 +00:00
|
|
|
|
: impl(new ParserWithOptionalAlias(new ParserTernaryOperatorExpression))
|
2011-11-06 20:47:07 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
bool ParserExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
|
|
|
{
|
2011-11-06 20:47:07 +00:00
|
|
|
|
return ParserList(new ParserExpressionWithOptionalAlias, new ParserString(",")).parse(pos, end, node, expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ParserNotEmptyExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
|
|
|
{
|
|
|
|
|
return nested_parser.parse(pos, end, node, expected)
|
|
|
|
|
&& !dynamic_cast<ASTExpressionList &>(*node).children.empty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-09-04 05:14:52 +00:00
|
|
|
|
bool ParserOrderByExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
|
|
|
{
|
|
|
|
|
return ParserList(new ParserOrderByElement, new ParserString(",")).parse(pos, end, node, expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|