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