ClickHouse/dbms/src/Parsers/ExpressionListParsers.cpp

423 lines
9.7 KiB
C++
Raw Normal View History

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);
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;
}
bool ParserVariableArityOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
{
ParserWhiteSpaceOrComments ws;
Pos begin = pos;
ASTPtr arguments;
if (!elem_parser->parse(pos, end, node, expected))
return false;
while (true)
{
ws.ignore(pos, end);
if (!infix_parser.ignore(pos, end, expected))
break;
ws.ignore(pos, end);
if (!arguments)
{
ASTFunction * function = new ASTFunction;
ASTPtr function_node = function;
arguments = new ASTExpressionList;
function->arguments = arguments;
function->children.push_back(arguments);
function->name = function_name;
arguments->children.push_back(node);
node = function_node;
}
ASTPtr elem;
if (!elem_parser->parse(pos, end, elem, expected))
return false;
arguments->children.push_back(elem);
}
if (arguments)
arguments->range = node->range = StringRange(begin, pos);
return true;
}
2010-06-24 19:12:10 +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;
}
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;
bool was_open = false;
if (open.ignore(pos, end, expected))
{
ws.ignore(pos, end, expected);
was_open = true;
}
if (!ParserList(new ParserIdentifier, new ParserString(",")).parse(pos, end, inner_arguments, expected))
break;
ws.ignore(pos, end, expected);
if (was_open)
{
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(lambda->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);
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()
: impl(new ParserWithOptionalAlias(new ParserLambdaExpression))
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)
{
2013-05-29 11:33:55 +00:00
return ParserList(new ParserOrderByElement, new ParserString(","), false).parse(pos, end, node, expected);
2011-09-04 05:14:52 +00:00
}
2010-06-24 19:12:10 +00:00
}