1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-04-18 21:44:02 +03:00
2025-02-21 20:02:38 +04:00

159 lines
4.5 KiB
C++

/* Copyright (C) 2014 InfiniDB, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/***********************************************************************
* $Id: expressionparser.h 9633 2013-06-19 13:36:01Z rdempsey $
*
*
***********************************************************************/
/** @file */
#pragma once
#include <iostream>
#include <cassert>
#include <vector>
#include <stack>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <string>
#include "exp_templates.h"
#include "treenode.h"
#include "parsetree.h"
#include "operator.h"
namespace execplan
{
/**
* type define
*/
typedef std::stack<ParseTree*> OperandStack;
typedef std::stack<TreeNode*> OperatorStack;
/**@brief a structure to respent a token accepted by the parser
*
* token structure
*/
struct Token
{
TreeNode* value;
bool is_operator() const
{
if (value == nullptr)
return false;
return (typeid(*value) == typeid(Operator));
}
Token() : value(nullptr)
{
}
Token(TreeNode* v) : value(v)
{
}
private:
// technically, these should be defined since Token is used in a
// std::vector, but it appears to work okay...ownership of the
// value ptr is dubious
// Token(const Token& rhs);
// Token& operator=(const Token& rhs);
};
/**
* @brief this class builds an expression tree
*
* This struct parse the incomming tokens from an expression and
* build a expression tree according to the pre-defined precedence
* rules. The operators handled are: +, -, *, /, ||, (, ), func (,
* func ), and, or.
*/
class ExpressionParser : public expression::default_expression_parser_error_policy
{
public:
/**
* Constructors/Destructors
*/
ExpressionParser();
virtual ~ExpressionParser();
/**
* Operations
*/
/*
* Error handling
*/
static void invalid_operator_position(TreeNode* oper);
static void invalid_operator_position(const Token& oper);
static void invalid_operand_position(ParseTree* operand);
static void unbalanced_confix(TreeNode* oper);
static void missing_operand(const Token& oper);
/**
* Syntax and precedence rules
*/
static int positions(Token t);
static int position(TreeNode* op);
inline static bool is_operator(const Token& t)
{
return t.is_operator();
}
static ParseTree* as_operand(Token t);
static TreeNode* as_operator(Token t, int pos);
static expression::precedence precedence(TreeNode* op1, TreeNode* op2);
static expression::associativity associativity(TreeNode* op1, TreeNode* op2);
/**
* Build an expression tree with the tokens
*/
static ParseTree* reduce(TreeNode* op, ParseTree* value);
static ParseTree* reduce(TreeNode* op, ParseTree* lhs, ParseTree* rhs);
// parenthesis
static ParseTree* reduce(TreeNode* a, TreeNode* b, ParseTree* value);
// function call
static ParseTree* reduce(ParseTree* a, TreeNode* b, ParseTree* value, TreeNode* d);
/**
* to clean up operator and operand stack when exception throws.
* this is to be used by Calpont execplan project, where the operator
* and operand are pointers. added by Zhixuan Zhu 06/30/06
*/
static void cleanup(std::stack<ParseTree*> operandStack, std::stack<TreeNode*> operatorStack);
private:
static int precnum(TreeNode* op);
static expression::associativity assoc(TreeNode* op);
};
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
*
* Do a deep, strict (as opposed to semantic) equivalence test.
* @return true iff every member of t1 is a duplicate copy of every member of t2; false otherwise
*/
bool operator==(const ParseTree& t1, const ParseTree& t2);
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
*
* Do a deep, strict (as opposed to semantic) equivalence test.
* @return false iff every member of t1 is a duplicate copy of every member of t2; true otherwise
*/
bool operator!=(const ParseTree& t1, const ParseTree& t2);
} // namespace execplan