muParser API -  1.35
muParserBase.h
Go to the documentation of this file.
1 /*
2 
3  _____ __ _____________ _______ ______ ___________
4  / \| | \____ \__ \\_ __ \/ ___// __ \_ __ \
5  | Y Y \ | / |_> > __ \| | \/\___ \\ ___/| | \/
6  |__|_| /____/| __(____ /__| /____ >\___ >__|
7  \/ |__| \/ \/ \/
8  Copyright (C) 2004 - 2020 Ingo Berg
9 
10  Redistribution and use in source and binary forms, with or without modification, are permitted
11  provided that the following conditions are met:
12 
13  * Redistributions of source code must retain the above copyright notice, this list of
14  conditions and the following disclaimer.
15  * Redistributions in binary form must reproduce the above copyright notice, this list of
16  conditions and the following disclaimer in the documentation and/or other materials provided
17  with the distribution.
18 
19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #ifndef MU_PARSER_BASE_H
30 #define MU_PARSER_BASE_H
31 
32 //--- Standard includes ------------------------------------------------------------------------
33 #include <cmath>
34 #include <string>
35 #include <iostream>
36 #include <map>
37 #include <memory>
38 #include <locale>
39 #include <limits.h>
40 
41 //--- Parser includes --------------------------------------------------------------------------
42 #include "muParserDef.h"
43 #include "muParserTokenReader.h"
44 #include "muParserBytecode.h"
45 #include "muParserError.h"
46 
47 
48 namespace mu
49 {
50  /** \file
51  \brief This file contains the class definition of the muparser engine.
52  */
53 
54  /** \brief Mathematical expressions parser (base parser engine).
55 
56  This is the implementation of a bytecode based mathematical expressions parser.
57  The formula will be parsed from string and converted into a bytecode.
58  Future calculations will be done with the bytecode instead the formula string
59  resulting in a significant performance increase.
60  Complementary to a set of internally implemented functions the parser is able to handle
61  user defined functions and variables.
62  */
63  class API_EXPORT_CXX 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 used for storing an array of values. */
78  typedef std::vector<value_type> valbuf_type;
79 
80  /** \brief Type for a vector of strings. */
81  typedef std::vector<string_type> stringbuf_type;
82 
83  /** \brief Typedef for the token reader. */
85 
86  /** \brief Type used for parser tokens. */
88 
89  /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */
90  static const int s_MaxNumOpenMPThreads;
91 
92  public:
93 
94  /** \brief Type of the error class.
95 
96  Included for backwards compatibility.
97  */
99 
100  static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
101 
102  ParserBase();
103  ParserBase(const ParserBase& a_Parser);
104  ParserBase& operator=(const ParserBase& a_Parser);
105 
106  virtual ~ParserBase();
107 
108  value_type Eval() const;
109  value_type* Eval(int& nStackSize) const;
110  void Eval(value_type* results, int nBulkSize);
111 
112  int GetNumResults() const;
113 
114  void SetExpr(const string_type& a_sExpr);
115  void SetVarFactory(facfun_type a_pFactory, void* pUserData = nullptr);
116 
117  void SetDecSep(char_type cDecSep);
118  void SetThousandsSep(char_type cThousandsSep = 0);
119  void ResetLocale();
120 
121  void EnableOptimizer(bool a_bIsOn = true);
122  void EnableBuiltInOprt(bool a_bIsOn = true);
123 
124  bool HasBuiltInOprt() const;
125  void AddValIdent(identfun_type a_pCallback);
126 
127  /** \fn void mu::ParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true)
128  \brief Define a parser function without arguments.
129  \param a_strName Name of the function
130  \param a_pFun Pointer to the callback function
131  \param a_bAllowOpt A flag indicating this function may be optimized
132  */
133  template<typename T>
134  void DefineFun(const string_type& a_strName, T a_pFun, bool a_bAllowOpt = true)
135  {
136  AddCallback(a_strName, ParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars());
137  }
138 
139  void DefineOprt(const string_type& a_strName, fun_type2 a_pFun, unsigned a_iPri = 0, EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
140  void DefineConst(const string_type& a_sName, value_type a_fVal);
141  void DefineStrConst(const string_type& a_sName, const string_type& a_strVal);
142  void DefineVar(const string_type& a_sName, value_type* a_fVar);
143  void DefinePostfixOprt(const string_type& a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt = true);
144  void DefineInfixOprt(const string_type& a_strName, fun_type1 a_pOprt, int a_iPrec = prINFIX, bool a_bAllowOpt = true);
145 
146  // Clear user defined variables, constants or functions
147  void ClearVar();
148  void ClearFun();
149  void ClearConst();
150  void ClearInfixOprt();
151  void ClearPostfixOprt();
152  void ClearOprt();
153 
154  void RemoveVar(const string_type& a_strVarName);
155  const varmap_type& GetUsedVar() const;
156  const varmap_type& GetVar() const;
157  const valmap_type& GetConst() const;
158  const string_type& GetExpr() const;
159  const funmap_type& GetFunDef() const;
160  string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const;
161 
162  const char_type** GetOprtDef() const;
163  void DefineNameChars(const char_type* a_szCharset);
164  void DefineOprtChars(const char_type* a_szCharset);
165  void DefineInfixOprtChars(const char_type* a_szCharset);
166 
167  const char_type* ValidNameChars() const;
168  const char_type* ValidOprtChars() const;
169  const char_type* ValidInfixOprtChars() const;
170 
171  void SetArgSep(char_type cArgSep);
172  char_type GetArgSep() const;
173 
174  protected:
175 
176  void Init();
177  void Error(EErrorCodes a_iErrc, int a_iPos = (int)mu::string_type::npos, const string_type& a_strTok = string_type()) const;
178 
179  virtual void InitCharSets() = 0;
180  virtual void InitFun() = 0;
181  virtual void InitConst() = 0;
182  virtual void InitOprt() = 0;
183 
184  virtual void OnDetectVar(string_type* pExpr, int& nStart, int& nEnd);
185 
186  static const char_type* c_DefaultOprt[];
187  static std::locale s_locale; ///< The locale used by the parser
188  static bool g_DbgDumpCmdCode;
189  static bool g_DbgDumpStack;
190 
191  /** \brief A facet class used to change decimal and thousands separator. */
192  template<class TChar>
193  class change_dec_sep : public std::numpunct<TChar>
194  {
195  public:
196 
197  explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
198  :std::numpunct<TChar>()
199  , m_nGroup(nGroup)
200  , m_cDecPoint(cDecSep)
201  , m_cThousandsSep(cThousandsSep)
202  {}
203 
204  protected:
205 
206  virtual char_type do_decimal_point() const
207  {
208  return m_cDecPoint;
209  }
210 
211  virtual char_type do_thousands_sep() const
212  {
213  return m_cThousandsSep;
214  }
215 
216  virtual std::string do_grouping() const
217  {
218  // fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4
219  // courtesy of Jens Bartsch
220  // original code:
221  // return std::string(1, (char)m_nGroup);
222  // new code:
223  return std::string(1, (char)(m_cThousandsSep > 0 ? m_nGroup : CHAR_MAX));
224  }
225 
226  private:
227 
228  int m_nGroup;
229  char_type m_cDecPoint;
230  char_type m_cThousandsSep;
231  };
232 
233  private:
234 
235  void Assign(const ParserBase& a_Parser);
236  void InitTokenReader();
237  void ReInit() const;
238 
239  void AddCallback(const string_type& a_strName, const ParserCallback& a_Callback, funmap_type& a_Storage, const char_type* a_szCharSet);
240  void ApplyRemainingOprt(std::stack<token_type>& a_stOpt, std::stack<token_type>& a_stVal) const;
241  void ApplyBinOprt(std::stack<token_type>& a_stOpt, std::stack<token_type>& a_stVal) const;
242  void ApplyIfElse(std::stack<token_type>& a_stOpt, std::stack<token_type>& a_stVal) const;
243  void ApplyFunc(std::stack<token_type>& a_stOpt, std::stack<token_type>& a_stVal, int iArgCount) const;
244 
245  token_type ApplyStrFunc(const token_type& a_FunTok, const std::vector<token_type>& a_vArg) const;
246 
247  int GetOprtPrecedence(const token_type& a_Tok) const;
248  EOprtAssociativity GetOprtAssociativity(const token_type& a_Tok) const;
249 
250  void CreateRPN() const;
251 
252  value_type ParseString() const;
253  value_type ParseCmdCode() const;
254  value_type ParseCmdCodeShort() const;
255  value_type ParseCmdCodeBulk(int nOffset, int nThreadID) const;
256 
257  void CheckName(const string_type& a_strName, const string_type& a_CharSet) const;
258  void CheckOprt(const string_type& a_sName, const ParserCallback& a_Callback, const string_type& a_szCharSet) const;
259 
260  void StackDump(const std::stack<token_type >& a_stVal, const std::stack<token_type >& a_stOprt) const;
261 
262  /** \brief Pointer to the parser function.
263 
264  Eval() calls the function whose address is stored there.
265  */
266  mutable ParseFunction m_pParseFormula;
267  mutable ParserByteCode m_vRPN; ///< The Bytecode class.
268  mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
269  stringbuf_type m_vStringVarBuf;
270 
271  std::unique_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
272 
273  funmap_type m_FunDef; ///< Map of function names and pointers.
274  funmap_type m_PostOprtDef; ///< Postfix operator callbacks
275  funmap_type m_InfixOprtDef; ///< unary infix operator.
276  funmap_type m_OprtDef; ///< Binary operator callbacks
277  valmap_type m_ConstDef; ///< user constants.
278  strmap_type m_StrVarDef; ///< user defined string constants
279  varmap_type m_VarDef; ///< user defind variables.
280 
281  bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
282 
283  string_type m_sNameChars; ///< Charset for names
284  string_type m_sOprtChars; ///< Charset for postfix/ binary operator tokens
285  string_type m_sInfixOprtChars; ///< Charset for infix operator tokens
286 
287  // items merely used for caching state information
288  mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
289  mutable int m_nFinalResultIdx;
290  };
291 
292 } // namespace mu
293 
294 #endif
Definition of the parser bytecode class.
value_type *(* facfun_type)(const char_type *, void *)
Callback used for variable creation factory functions.
Definition: muParserDef.h:415
static std::locale s_locale
The locale used by the parser.
Definition: muParserBase.h:187
std::map< string_type, std::size_t > strmap_type
Type for assigning a string name to an index in the internal string table.
Definition: muParserDef.h:320
std::map< string_type, value_type * > varmap_type
Type used for storing variables.
Definition: muParserDef.h:314
value_type(* fun_type1)(value_type)
Callback type used for functions with a single arguments.
Definition: muParserDef.h:331
std::map< string_type, ParserCallback > funmap_type
Container for Callback objects.
EOprtAssociativity
Parser operator precedence values.
Definition: muParserDef.h:199
This file contains the parser token reader definition.
std::map< string_type, value_type > valmap_type
Type used for storing constants.
Definition: muParserDef.h:317
void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt=true)
Define a parser function without arguments.
Definition: muParserBase.h:134
value_type(* fun_type2)(value_type, value_type)
Callback type used for functions with two arguments.
Definition: muParserDef.h:334
Error class of the parser.
Definition: muParserError.h:68
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:294
A facet class used to change decimal and thousands separator.
Definition: muParserBase.h:193
Namespace for mathematical applications.
Definition: muParser.cpp:46
int(* identfun_type)(const char_type *sExpr, int *nPos, value_type *fVal)
Callback used for functions that identify values in a string.
Definition: muParserDef.h:412
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:306
Token reader for the ParserBase class.
Bytecode implementation of the Math Parser.
MUP_STRING_TYPE string_type
The stringtype used by the parser.
Definition: muParserDef.h:300
ParserError exception_type
Type of the error class.
Definition: muParserBase.h:98
EErrorCodes
Error codes.
Definition: muParserDef.h:226
Encapsulation of prototypes for a numerical parser function.
Signs have a higher priority than ADD_SUB, but lower than power operator.
Definition: muParserDef.h:220
Mathematical expressions parser (base parser engine).
Definition: muParserBase.h:63
This file defines the error class used by the parser.
This file contains standard definitions used by the parser.