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 - 2022 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 #if defined(_MSC_VER)
48  #pragma warning(push)
49  #pragma warning(disable : 4251) // ...needs to have dll-interface to be used by clients of class ...
50 #endif
51 
52 
53 namespace mu
54 {
55  /** \file
56  \brief This file contains the class definition of the muparser engine.
57  */
58 
59  /** \brief Mathematical expressions parser (base parser engine).
60 
61  This is the implementation of a bytecode based mathematical expressions parser.
62  The formula will be parsed from string and converted into a bytecode.
63  Future calculations will be done with the bytecode instead the formula string
64  resulting in a significant performance increase.
65  Complementary to a set of internally implemented functions the parser is able to handle
66  user defined functions and variables.
67  */
68  class API_EXPORT_CXX ParserBase
69  {
70  friend class ParserTokenReader;
71 
72  private:
73 
74  /** \brief Typedef for the parse functions.
75 
76  The parse function do the actual work. The parser exchanges
77  the function pointer to the parser function depending on
78  which state it is in. (i.e. bytecode parser vs. string parser)
79  */
80  typedef value_type(ParserBase::* ParseFunction)() const;
81 
82  /** \brief Type used for storing an array of values. */
83  typedef std::vector<value_type> valbuf_type;
84 
85  /** \brief Type for a vector of strings. */
86  typedef std::vector<string_type> stringbuf_type;
87 
88  /** \brief Typedef for the token reader. */
90 
91  /** \brief Type used for parser tokens. */
93 
94  /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */
95  static const int s_MaxNumOpenMPThreads;
96 
97  public:
98 
99  /** \brief Type of the error class.
100 
101  Included for backwards compatibility.
102  */
104 
105  static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
106 
107  ParserBase();
108  ParserBase(const ParserBase& a_Parser);
109  ParserBase& operator=(const ParserBase& a_Parser);
110 
111  virtual ~ParserBase();
112 
113  value_type Eval() const;
114  value_type* Eval(int& nStackSize) const;
115  void Eval(value_type* results, int nBulkSize);
116 
117  int GetNumResults() const;
118 
119  void SetExpr(const string_type& a_sExpr);
120  void SetVarFactory(facfun_type a_pFactory, void* pUserData = nullptr);
121 
122  void SetDecSep(char_type cDecSep);
123  void SetThousandsSep(char_type cThousandsSep = 0);
124  void ResetLocale();
125 
126  void EnableOptimizer(bool a_bIsOn = true);
127  void EnableBuiltInOprt(bool a_bIsOn = true);
128 
129  bool HasBuiltInOprt() const;
130  void AddValIdent(identfun_type a_pCallback);
131 
132  /** \fn void mu::ParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true)
133  \brief Define a parser function without arguments.
134  \param a_strName Name of the function
135  \param a_pFun Pointer to the callback function
136  \param a_bAllowOpt A flag indicating this function may be optimized
137  */
138  template<typename T>
139  void DefineFun(const string_type& a_strName, T a_pFun, bool a_bAllowOpt = true)
140  {
141  AddCallback(a_strName, ParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars());
142  }
143 
144  /** \fn void mu::ParserBase::DefineFunUserData
145  \brief Define a parser function with user data (not null).
146  \param a_strName Name of the function
147  \param a_pFun Pointer to the callback function
148  \param a_pUserData Pointer that will be passed back to callback (shall not be nullptr)
149  \param a_bAllowOpt A flag indicating this function may be optimized
150  */
151  template<typename T>
152  void DefineFunUserData(const string_type& a_strName, T a_pFun, void* a_pUserData, bool a_bAllowOpt = true)
153  {
154  AddCallback(a_strName, ParserCallback(a_pFun, a_pUserData, a_bAllowOpt), m_FunDef, ValidNameChars());
155  }
156 
157  void DefineOprt(const string_type& a_strName, fun_type2 a_pFun, unsigned a_iPri = 0, EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
158  void DefineConst(const string_type& a_sName, value_type a_fVal);
159  void DefineStrConst(const string_type& a_sName, const string_type& a_strVal);
160  void DefineVar(const string_type& a_sName, value_type* a_fVar);
161  void DefinePostfixOprt(const string_type& a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt = true);
162  void DefineInfixOprt(const string_type& a_strName, fun_type1 a_pOprt, int a_iPrec = prINFIX, bool a_bAllowOpt = true);
163 
164  // Clear user defined variables, constants or functions
165  void ClearVar();
166  void ClearFun();
167  void ClearConst();
168  void ClearInfixOprt();
169  void ClearPostfixOprt();
170  void ClearOprt();
171 
172  void RemoveVar(const string_type& a_strVarName);
173  const varmap_type& GetUsedVar() const;
174  const varmap_type& GetVar() const;
175  const valmap_type& GetConst() const;
176  const string_type& GetExpr() const;
177  const funmap_type& GetFunDef() const;
178  string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const;
179  const ParserByteCode& GetByteCode() const;
180 
181  const char_type** GetOprtDef() const;
182  void DefineNameChars(const char_type* a_szCharset);
183  void DefineOprtChars(const char_type* a_szCharset);
184  void DefineInfixOprtChars(const char_type* a_szCharset);
185 
186  const char_type* ValidNameChars() const;
187  const char_type* ValidOprtChars() const;
188  const char_type* ValidInfixOprtChars() const;
189 
190  void SetArgSep(char_type cArgSep);
191  void SetByteCode(const ParserByteCode& a_ByteCode);
192 
193  char_type GetArgSep() const;
194 
195  protected:
196 
197  void Init();
198  void Error(EErrorCodes a_iErrc, int a_iPos = static_cast<int>(mu::string_type::npos), const string_type& a_strTok = string_type()) const;
199 
200  virtual void InitCharSets() = 0;
201  virtual void InitFun() = 0;
202  virtual void InitConst() = 0;
203  virtual void InitOprt() = 0;
204 
205  virtual void OnDetectVar(string_type* pExpr, int& nStart, int& nEnd);
206 
207  static const char_type* c_DefaultOprt[];
208  static std::locale s_locale; ///< The locale used by the parser
209  static bool g_DbgDumpCmdCode;
210  static bool g_DbgDumpStack;
211 
212  /** \brief A facet class used to change decimal and thousands separator. */
213  template<class TChar>
214  class change_dec_sep : public std::numpunct<TChar>
215  {
216  public:
217 
218  explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
219  :std::numpunct<TChar>()
220  ,m_nGroup(nGroup)
221  ,m_cDecPoint(cDecSep)
222  ,m_cThousandsSep(cThousandsSep)
223  {}
224 
225  protected:
226 
227  char_type do_decimal_point() const override
228  {
229  return m_cDecPoint;
230  }
231 
232  char_type do_thousands_sep() const override
233  {
234  return m_cThousandsSep;
235  }
236 
237  std::string do_grouping() const override
238  {
239  // fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4
240  // courtesy of Jens Bartsch
241  // original code:
242  // return std::string(1, (char)m_nGroup);
243  // new code:
244  return std::string(1, (char)(m_cThousandsSep > 0 ? m_nGroup : CHAR_MAX));
245  }
246 
247  private:
248 
249  int m_nGroup;
250  char_type m_cDecPoint;
251  char_type m_cThousandsSep;
252  };
253 
254  private:
255 
256  void Assign(const ParserBase& a_Parser);
257  void InitTokenReader();
258  void ReInit() const;
259 
260  void AddCallback(const string_type& a_strName, const ParserCallback& a_Callback, funmap_type& a_Storage, const char_type* a_szCharSet);
261  void ApplyRemainingOprt(std::stack<token_type>& a_stOpt, std::stack<token_type>& a_stVal) const;
262  void ApplyBinOprt(std::stack<token_type>& a_stOpt, std::stack<token_type>& a_stVal) const;
263  void ApplyIfElse(std::stack<token_type>& a_stOpt, std::stack<token_type>& a_stVal) const;
264  void ApplyFunc(std::stack<token_type>& a_stOpt, std::stack<token_type>& a_stVal, int iArgCount) const;
265 
266  token_type ApplyStrFunc(const token_type& a_FunTok, const std::vector<token_type>& a_vArg) const;
267 
268  int GetOprtPrecedence(const token_type& a_Tok) const;
269  EOprtAssociativity GetOprtAssociativity(const token_type& a_Tok) const;
270 
271  void CreateRPN() const;
272 
273  value_type ParseString() const;
274  value_type ParseCmdCode() const;
275  value_type ParseCmdCodeShort() const;
276  value_type ParseCmdCodeBulk(int nOffset, int nThreadID) const;
277 
278  void CheckName(const string_type& a_strName, const string_type& a_CharSet) const;
279  void CheckOprt(const string_type& a_sName, const ParserCallback& a_Callback, const string_type& a_szCharSet) const;
280 
281  void StackDump(const std::stack<token_type >& a_stVal, const std::stack<token_type >& a_stOprt) const;
282 
283  /** \brief Pointer to the parser function.
284 
285  Eval() calls the function whose address is stored there.
286  */
287  mutable ParseFunction m_pParseFormula;
288  mutable ParserByteCode m_vRPN; ///< The Bytecode class.
289  mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
290  stringbuf_type m_vStringVarBuf;
291 
292  std::unique_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
293 
294  funmap_type m_FunDef; ///< Map of function names and pointers.
295  funmap_type m_PostOprtDef; ///< Postfix operator callbacks
296  funmap_type m_InfixOprtDef; ///< unary infix operator.
297  funmap_type m_OprtDef; ///< Binary operator callbacks
298  valmap_type m_ConstDef; ///< user constants.
299  strmap_type m_StrVarDef; ///< user defined string constants
300  varmap_type m_VarDef; ///< user defind variables.
301 
302  bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
303 
304  string_type m_sNameChars; ///< Charset for names
305  string_type m_sOprtChars; ///< Charset for postfix/ binary operator tokens
306  string_type m_sInfixOprtChars; ///< Charset for infix operator tokens
307 
308  // items merely used for caching state information
309  mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
310  mutable int m_nFinalResultIdx;
311  };
312 
313 } // namespace mu
314 
315 #if defined(_MSC_VER)
316  #pragma warning(pop)
317 #endif
318 
319 #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:507
static std::locale s_locale
The locale used by the parser.
Definition: muParserBase.h:208
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:322
std::map< string_type, value_type * > varmap_type
Type used for storing variables.
Definition: muParserDef.h:316
void DefineFunUserData(const string_type &a_strName, T a_pFun, void *a_pUserData, bool a_bAllowOpt=true)
Define a parser function with user data (not null).
Definition: muParserBase.h:152
value_type(* fun_type1)(value_type)
Callback type used for functions with a single arguments.
Definition: muParserDef.h:333
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:319
void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt=true)
Define a parser function without arguments.
Definition: muParserBase.h:139
value_type(* fun_type2)(value_type, value_type)
Callback type used for functions with two arguments.
Definition: muParserDef.h:336
Error class of the parser.
Definition: muParserError.h:74
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:296
A facet class used to change decimal and thousands separator.
Definition: muParserBase.h:214
Namespace for mathematical applications.
Definition: muParser.cpp:48
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:504
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:308
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:302
ParserError exception_type
Type of the error class.
Definition: muParserBase.h:103
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:68
This file defines the error class used by the parser.
This file contains standard definitions used by the parser.