/* 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 #include #include #include #include #include #include #include #include "exp_templates.h" #include "treenode.h" #include "parsetree.h" #include "operator.h" namespace execplan { /** * type define */ typedef std::stack OperandStack; typedef std::stack 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 operandStack, std::stack 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