1 /* 2 __________ 3 _____ __ __\______ \_____ _______ ______ ____ _______ 4 / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \ 5 | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/ 6 |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__| 7 \/ \/ \/ \/ 8 Copyright (C) 2004-2008 Ingo Berg 9 10 Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 software and associated documentation files (the "Software"), to deal in the Software 12 without restriction, including without limitation the rights to use, copy, modify, 13 merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 permit persons to whom the Software is furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in all copies or 17 substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 20 NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 #ifndef MU_PARSER_BASE_H 26 #define MU_PARSER_BASE_H 27 28 //--- Standard includes ------------------------------------------------------------------------ 29 #include <cmath> 30 #include <string> 31 #include <iostream> 32 #include <map> 33 #include <memory> 34 35 //--- Parser includes -------------------------------------------------------------------------- 36 #include "muParserDef.h" 37 #include "muParserStack.h" 38 #include "muParserTokenReader.h" 39 #include "muParserBytecode.h" 40 #include "muParserError.h" 41 42 43 namespace mu 44 { 45 /** \file 46 \brief This file contains the class definition of the muparser engine. 47 */ 48 49 //-------------------------------------------------------------------------------------------------- 50 /** \brief Mathematical expressions parser (base parser engine). 51 52 Version 1.30 (20080413) 53 54 This is the implementation of a bytecode based mathematical expressions parser. 55 The formula will be parsed from string and converted into a bytecode. 56 Future calculations will be done with the bytecode instead the formula string 57 resulting in a significant performance increase. 58 Complementary to a set of internally implemented functions the parser is able to handle 59 user defined functions and variables. 60 61 \author (C) 2004-2008 Ingo Berg 62 */ 63 class ParserBase 64 { 65 friend class ParserTokenReader; 66 67 private: 68 69 /** \brief Typedef for the parse functions. 70 71 The parse function do the actual work. The parser exchanges 72 the function pointer to the parser function depending on 73 which state it is in. (i.e. bytecode parser vs. string parser) 74 */ 75 typedef value_type (ParserBase::*ParseFunction)() const; 76 77 /** \brief Type for a vector of strings. */ 78 typedef std::vector<string_type> stringbuf_type; 79 80 /** \brief Typedef for the token reader. */ 81 typedef ParserTokenReader token_reader_type; 82 83 /** \brief Type used for parser tokens. */ 84 typedef ParserToken<value_type, string_type> token_type; 85 86 public: 87 88 /** \brief Type of the error class. 89 90 Included for backwards compatibility. 91 */ 92 typedef ParserError exception_type; 93 94 ParserBase(); 95 ParserBase(const ParserBase &a_Parser); 96 ParserBase& operator=(const ParserBase &a_Parser); 97 98 virtual ~ParserBase(); 99 100 //--------------------------------------------------------------------------- 101 /** \brief Calculate the result. 102 103 A note on const correctness: 104 I consider it important that Calc is a const function. 105 Due to caching operations Calc changes only the state of internal variables with one exception 106 m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making 107 Calc non const GetUsedVar is non const because it explicitely calls Eval() forcing this update. 108 109 \pre A formula must be set. 110 \pre Variables must have been set (if needed) 111 112 \sa #m_pParseFormula 113 \return The evaluation result 114 \throw ParseException if no Formula is set or in case of any other error related to the formula. 115 */ Eval()116 inline value_type Eval() const 117 { 118 return (this->*m_pParseFormula)(); 119 } 120 121 void SetExpr(const string_type &a_sExpr); 122 void SetVarFactory(facfun_type a_pFactory, void *pUserData = nullptr); 123 124 void EnableOptimizer(bool a_bIsOn=true); 125 void EnableByteCode(bool a_bIsOn=true); 126 void EnableBuiltInOprt(bool a_bIsOn=true); 127 128 bool HasBuiltInOprt() const; 129 void AddValIdent(identfun_type a_pCallback); 130 131 #define MUP_DEFINE_FUNC(TYPE) \ 132 inline void DefineFun(const string_type &a_strName, TYPE a_pFun, bool a_bAllowOpt = true) \ 133 { \ 134 AddCallback( a_strName, ParserCallback(a_pFun, a_bAllowOpt), \ 135 m_FunDef, ValidNameChars() ); \ 136 } 137 138 MUP_DEFINE_FUNC(fun_type0) 139 MUP_DEFINE_FUNC(fun_type1) 140 MUP_DEFINE_FUNC(fun_type2) 141 MUP_DEFINE_FUNC(fun_type3) 142 MUP_DEFINE_FUNC(fun_type4) 143 MUP_DEFINE_FUNC(fun_type5) 144 MUP_DEFINE_FUNC(multfun_type) 145 MUP_DEFINE_FUNC(strfun_type1) 146 MUP_DEFINE_FUNC(strfun_type2) 147 MUP_DEFINE_FUNC(strfun_type3) 148 #undef MUP_DEFINE_FUNC 149 150 void DefineOprt(const string_type &a_strName, fun_type2 a_pFun, unsigned a_iPri=0, bool a_bAllowOpt = false); 151 void DefineConst(const string_type &a_sName, value_type a_fVal); 152 void DefineStrConst(const string_type &a_sName, const string_type &a_strVal); 153 void DefineVar(const string_type &a_sName, value_type *a_fVar); 154 void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); 155 void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); 156 157 // Clear user defined variables, constants or functions 158 void ClearVar(); 159 void ClearFun(); 160 void ClearConst(); 161 void ClearInfixOprt(); 162 void ClearPostfixOprt(); 163 void ClearOprt(); 164 165 void RemoveVar(const string_type &a_strVarName); 166 const varmap_type& GetUsedVar() const; 167 const varmap_type& GetVar() const; 168 const valmap_type& GetConst() const; 169 const string_type& GetExpr() const; 170 const funmap_type& GetFunDef() const; 171 172 const char_type ** GetOprtDef() const; 173 void DefineNameChars(const char_type *a_szCharset); 174 void DefineOprtChars(const char_type *a_szCharset); 175 void DefineInfixOprtChars(const char_type *a_szCharset); 176 177 const char_type* ValidNameChars() const; 178 const char_type* ValidOprtChars() const; 179 const char_type* ValidInfixOprtChars() const; 180 181 void SetArgSep(char_type cArgSep); 182 char_type GetArgSep() const; 183 184 void Error(EErrorCodes a_iErrc, 185 int a_iPos = (int)mu::string_type::npos, 186 const string_type &a_strTok = string_type() ) const; 187 188 protected: 189 190 void Init(); 191 192 virtual void InitCharSets() = 0; 193 virtual void InitFun() = 0; 194 virtual void InitConst() = 0; 195 virtual void InitOprt() = 0; 196 197 static const char_type *c_DefaultOprt[]; 198 199 private: 200 201 void Assign(const ParserBase &a_Parser); 202 void InitTokenReader(); 203 void ReInit() const; 204 205 void AddCallback( const string_type &a_strName, 206 const ParserCallback &a_Callback, 207 funmap_type &a_Storage, 208 const char_type *a_szCharSet ); 209 210 void ApplyBinOprt(ParserStack<token_type> &a_stOpt, 211 ParserStack<token_type> &a_stVal) const; 212 213 void ApplyFunc(ParserStack<token_type> &a_stOpt, 214 ParserStack<token_type> &a_stVal, 215 int iArgCount) const; 216 217 token_type ApplyNumFunc(const token_type &a_FunTok, 218 const std::vector<token_type> &a_vArg) const; 219 220 token_type ApplyStrFunc(const token_type &a_FunTok, 221 const std::vector<token_type> &a_vArg) const; 222 223 int GetOprtPri(const token_type &a_Tok) const; 224 225 value_type ParseString() const; 226 value_type ParseCmdCode() const; 227 value_type ParseValue() const; 228 229 void ClearFormula(); 230 void CheckName(const string_type &a_strName, const string_type &a_CharSet) const; 231 232 #if defined(MUP_DUMP_STACK) | defined(MUP_DUMP_CMDCODE) 233 void StackDump(const ParserStack<token_type > &a_stVal, 234 const ParserStack<token_type > &a_stOprt) const; 235 #endif 236 237 /** \brief Pointer to the parser function. 238 239 Eval() calls the function whose address is stored there. 240 */ 241 mutable ParseFunction m_pParseFormula; 242 mutable const ParserByteCode::map_type *m_pCmdCode; ///< Formula converted to bytecode, points to the data of the bytecode class. 243 mutable ParserByteCode m_vByteCode; ///< The Bytecode class. 244 mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments 245 stringbuf_type m_vStringVarBuf; 246 247 std::auto_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object. 248 249 funmap_type m_FunDef; ///< Map of function names and pointers. 250 funmap_type m_PostOprtDef; ///< Postfix operator callbacks 251 funmap_type m_InfixOprtDef; ///< unary infix operator. 252 funmap_type m_OprtDef; ///< Binary operator callbacks 253 valmap_type m_ConstDef; ///< user constants. 254 strmap_type m_StrVarDef; ///< user defined string constants 255 varmap_type m_VarDef; ///< user defind variables. 256 257 bool m_bOptimize; ///< Flag that indicates if the optimizer is on or off. 258 bool m_bUseByteCode; ///< Flag that indicates if bytecode parsing is on or off. 259 bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off 260 261 string_type m_sNameChars; ///< Charset for names 262 string_type m_sOprtChars; ///< Charset for postfix/ binary operator tokens 263 string_type m_sInfixOprtChars; ///< Charset for infix operator tokens 264 }; 265 266 } // namespace mu 267 268 #endif 269 270