muParser API -  1.35
muParserToken.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_TOKEN_H
30 #define MU_PARSER_TOKEN_H
31 
32 #include <string>
33 #include <stack>
34 #include <vector>
35 #include <memory>
36 
37 #if defined(_MSC_VER)
38  #pragma warning(push)
39  #pragma warning(disable : 26812)
40 #endif
41 
42 #include "muParserError.h"
43 #include "muParserCallback.h"
44 
45 /** \file
46  \brief This file contains the parser token definition.
47 */
48 
49 namespace mu
50 {
51  /** \brief Encapsulation of the data for a single formula token.
52 
53  Formula token implementation. Part of the Math Parser Package.
54  Formula tokens can be either one of the following:
55  <ul>
56  <li>value</li>
57  <li>variable</li>
58  <li>function with numerical arguments</li>
59  <li>functions with a string as argument</li>
60  <li>prefix operators</li>
61  <li>infix operators</li>
62  <li>binary operator</li>
63  </ul>
64  */
65  template<typename TBase, typename TString>
66  class ParserToken final
67  {
68  private:
69 
70  ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode.
71  ETypeCode m_iType;
72  void* m_pTok; ///< Stores Token pointer; not applicable for all tokens
73  int m_iIdx; ///< An otional index to an external buffer storing the token data
74  TString m_strTok; ///< Token string
75  TString m_strVal; ///< Value for string variables
76  value_type m_fVal; ///< the value
77  std::unique_ptr<ParserCallback> m_pCallback;
78 
79  public:
80 
81  /** \brief Constructor (default).
82 
83  Sets token to an neutral state of type cmUNKNOWN.
84  \throw nothrow
85  \sa ECmdCode
86  */
88  :m_iCode(cmUNKNOWN)
89  , m_iType(tpVOID)
90  , m_pTok(0)
91  , m_iIdx(-1)
92  , m_strTok()
93  , m_strVal()
94  , m_fVal(0)
95  , m_pCallback()
96  {}
97 
98  //------------------------------------------------------------------------------
99  /** \brief Create token from another one.
100 
101  Implemented by calling Assign(...)
102  \throw nothrow
103  \post m_iType==cmUNKNOWN
104  \sa #Assign
105  */
106  ParserToken(const ParserToken& a_Tok)
107  {
108  Assign(a_Tok);
109  }
110 
111 
112  /** \brief Assignment operator.
113 
114  Copy token state from another token and return this.
115  Implemented by calling Assign(...).
116  \throw nothrow
117  */
119  {
120  Assign(a_Tok);
121  return *this;
122  }
123 
124 
125  /** \brief Copy token information from argument.
126 
127  \throw nothrow
128  */
129  void Assign(const ParserToken& a_Tok)
130  {
131  m_iCode = a_Tok.m_iCode;
132  m_pTok = a_Tok.m_pTok;
133  m_strTok = a_Tok.m_strTok;
134  m_iIdx = a_Tok.m_iIdx;
135  m_strVal = a_Tok.m_strVal;
136  m_iType = a_Tok.m_iType;
137  m_fVal = a_Tok.m_fVal;
138  // create new callback object if a_Tok has one
139  m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0);
140  }
141 
142  //------------------------------------------------------------------------------
143  /** \brief Assign a token type.
144 
145  Token may not be of type value, variable or function. Those have separate set functions.
146 
147  \pre [assert] a_iType!=cmVAR
148  \pre [assert] a_iType!=cmVAL
149  \pre [assert] a_iType!=cmFUNC
150  \post m_fVal = 0
151  \post m_pTok = 0
152  */
153  ParserToken& Set(ECmdCode a_iType, const TString& a_strTok = TString())
154  {
155  // The following types can't be set this way, they have special Set functions
156  MUP_ASSERT(a_iType != cmVAR);
157  MUP_ASSERT(a_iType != cmVAL);
158  MUP_ASSERT(a_iType != cmFUNC);
159 
160  m_iCode = a_iType;
161  m_iType = tpVOID;
162  m_pTok = 0;
163  m_strTok = a_strTok;
164  m_iIdx = -1;
165 
166  return *this;
167  }
168 
169  //------------------------------------------------------------------------------
170  /** \brief Set Callback type. */
171  ParserToken& Set(const ParserCallback& a_pCallback, const TString& a_sTok)
172  {
173  MUP_ASSERT(a_pCallback.GetAddr());
174 
175  m_iCode = a_pCallback.GetCode();
176  m_iType = tpVOID;
177  m_strTok = a_sTok;
178  m_pCallback.reset(new ParserCallback(a_pCallback));
179 
180  m_pTok = 0;
181  m_iIdx = -1;
182 
183  return *this;
184  }
185 
186  //------------------------------------------------------------------------------
187  /** \brief Make this token a value token.
188 
189  Member variables not necessary for value tokens will be invalidated.
190  \throw nothrow
191  */
192  ParserToken& SetVal(TBase a_fVal, const TString& a_strTok = TString())
193  {
194  m_iCode = cmVAL;
195  m_iType = tpDBL;
196  m_fVal = a_fVal;
197  m_strTok = a_strTok;
198  m_iIdx = -1;
199 
200  m_pTok = 0;
201  m_pCallback.reset(0);
202 
203  return *this;
204  }
205 
206  //------------------------------------------------------------------------------
207  /** \brief make this token a variable token.
208 
209  Member variables not necessary for variable tokens will be invalidated.
210  \throw nothrow
211  */
212  ParserToken& SetVar(TBase* a_pVar, const TString& a_strTok)
213  {
214  m_iCode = cmVAR;
215  m_iType = tpDBL;
216  m_strTok = a_strTok;
217  m_iIdx = -1;
218  m_pTok = (void*)a_pVar;
219  m_pCallback.reset(0);
220  return *this;
221  }
222 
223  //------------------------------------------------------------------------------
224  /** \brief Make this token a variable token.
225 
226  Member variables not necessary for variable tokens will be invalidated.
227  \throw nothrow
228  */
229  ParserToken& SetString(const TString& a_strTok, std::size_t a_iSize)
230  {
231  m_iCode = cmSTRING;
232  m_iType = tpSTR;
233  m_strTok = a_strTok;
234  m_iIdx = static_cast<int>(a_iSize);
235 
236  m_pTok = 0;
237  m_pCallback.reset(0);
238  return *this;
239  }
240 
241  //------------------------------------------------------------------------------
242  /** \brief Set an index associated with the token related data.
243 
244  In cmSTRFUNC - This is the index to a string table in the main parser.
245  \param a_iIdx The index the string function result will take in the bytecode parser.
246  \throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING
247  */
248  void SetIdx(int a_iIdx)
249  {
250  if (m_iCode != cmSTRING || a_iIdx < 0)
252 
253  m_iIdx = a_iIdx;
254  }
255 
256  //------------------------------------------------------------------------------
257  /** \brief Return Index associated with the token related data.
258 
259  In cmSTRFUNC - This is the index to a string table in the main parser.
260 
261  \throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING
262  \return The index the result will take in the Bytecode calculatin array (#m_iIdx).
263  */
264  int GetIdx() const
265  {
266  if (m_iIdx < 0 || m_iCode != cmSTRING)
268 
269  return m_iIdx;
270  }
271 
272  //------------------------------------------------------------------------------
273  /** \brief Return the token type.
274 
275  \return #m_iType
276  \throw nothrow
277  */
279  {
280  if (m_pCallback.get())
281  {
282  return m_pCallback->GetCode();
283  }
284  else
285  {
286  return m_iCode;
287  }
288  }
289 
290  //------------------------------------------------------------------------------
291  ETypeCode GetType() const
292  {
293  if (m_pCallback.get())
294  {
295  return m_pCallback->GetType();
296  }
297  else
298  {
299  return m_iType;
300  }
301  }
302 
303  //------------------------------------------------------------------------------
304  int GetPri() const
305  {
306  if (!m_pCallback.get())
307  throw ParserError(ecINTERNAL_ERROR);
308 
309  if (m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX)
310  throw ParserError(ecINTERNAL_ERROR);
311 
312  return m_pCallback->GetPri();
313  }
314 
315  //------------------------------------------------------------------------------
316  EOprtAssociativity GetAssociativity() const
317  {
318  if (m_pCallback.get() == nullptr || m_pCallback->GetCode() != cmOPRT_BIN)
319  throw ParserError(ecINTERNAL_ERROR);
320 
321  return m_pCallback->GetAssociativity();
322  }
323 
324  //------------------------------------------------------------------------------
325  /** \brief Return the address of the callback function assoziated with
326  function and operator tokens.
327 
328  \return The pointer stored in #m_pTok.
329  \throw exception_type if token type is non of:
330  <ul>
331  <li>cmFUNC</li>
332  <li>cmSTRFUNC</li>
333  <li>cmPOSTOP</li>
334  <li>cmINFIXOP</li>
335  <li>cmOPRT_BIN</li>
336  </ul>
337  \sa ECmdCode
338  */
340  {
341  return (m_pCallback.get()) ? (generic_fun_type)m_pCallback->GetAddr() : 0;
342  }
343 
344  //------------------------------------------------------------------------------
345  /** \biref Get value of the token.
346 
347  Only applicable to variable and value tokens.
348  \throw exception_type if token is no value/variable token.
349  */
350  TBase GetVal() const
351  {
352  switch (m_iCode)
353  {
354  case cmVAL: return m_fVal;
355  case cmVAR: return *((TBase*)m_pTok);
356  default: throw ParserError(ecVAL_EXPECTED);
357  }
358  }
359 
360  //------------------------------------------------------------------------------
361  /** \brief Get address of a variable token.
362 
363  Valid only if m_iType==CmdVar.
364  \throw exception_type if token is no variable token.
365  */
366  TBase* GetVar() const
367  {
368  if (m_iCode != cmVAR)
370 
371  return (TBase*)m_pTok;
372  }
373 
374  //------------------------------------------------------------------------------
375  /** \brief Return the number of function arguments.
376 
377  Valid only if m_iType==CmdFUNC.
378  */
379  int GetArgCount() const
380  {
381  MUP_ASSERT(m_pCallback.get());
382 
383  if (!m_pCallback->GetAddr())
385 
386  return m_pCallback->GetArgc();
387  }
388 
389  //------------------------------------------------------------------------------
390  /** \brief Return the token identifier.
391 
392  If #m_iType is cmSTRING the token identifier is the value of the string argument
393  for a string function.
394  \return #m_strTok
395  \throw nothrow
396  \sa m_strTok
397  */
398  const TString& GetAsString() const
399  {
400  return m_strTok;
401  }
402  };
403 } // namespace mu
404 
405 #if defined(_MSC_VER)
406  #pragma warning(pop)
407 #endif
408 
409 #endif
code for infix operators
Definition: muParserDef.h:176
user defined binary operator
Definition: muParserDef.h:174
ParserToken & SetVar(TBase *a_pVar, const TString &a_strTok)
make this token a variable token.
int GetArgCount() const
Return the number of function arguments.
TBase * GetVar() const
Get address of a variable token.
Internal error of any kind.
Definition: muParserDef.h:279
ParserToken & SetVal(TBase a_fVal, const TString &a_strTok=TString())
Make this token a value token.
void Assign(const ParserToken &a_Tok)
Copy token information from argument.
ParserToken & operator=(const ParserToken &a_Tok)
Assignment operator.
ECmdCode GetCode() const
Return the callback code.
ParserToken & SetString(const TString &a_strTok, std::size_t a_iSize)
Make this token a variable token.
Code for a generic function item.
Definition: muParserDef.h:170
EOprtAssociativity
Parser operator precedence values.
Definition: muParserDef.h:199
int GetIdx() const
Return Index associated with the token related data.
ETypeCode
Types internally used by the parser.
Definition: muParserDef.h:183
ParserToken()
Constructor (default).
Definition: muParserToken.h:87
Error class of the parser.
Definition: muParserError.h:68
ECmdCode
Bytecode values.
Definition: muParserDef.h:135
#define MUP_ASSERT(COND)
An assertion that does not kill the program.
Definition: muParserDef.h:77
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:294
String type (Function arguments and constants only, no string variables)
Definition: muParserDef.h:185
A numerical function has been called with a non value type of argument.
Definition: muParserDef.h:239
ECmdCode GetCode() const
Return the token type.
Namespace for mathematical applications.
Definition: muParser.cpp:46
TBase GetVal() const
ParserToken & Set(ECmdCode a_iType, const TString &a_strTok=TString())
Assign a token type.
value item
Definition: muParserDef.h:161
value_type(* generic_fun_type)()
Callback type used for functions without arguments.
Definition: muParserDef.h:325
Undefined type.
Definition: muParserDef.h:187
Definition of the parser callback class.
void * GetAddr() const
Get the callback address for the parser function.
void SetIdx(int a_iIdx)
Set an index associated with the token related data.
uninitialized item
Definition: muParserDef.h:178
Code for a string token.
Definition: muParserDef.h:173
variable item
Definition: muParserDef.h:160
Encapsulation of the data for a single formula token.
Definition: muParserToken.h:66
const TString & GetAsString() const
Return the token identifier.
generic_fun_type GetFuncAddr() const
Return the address of the callback function assoziated with function and operator tokens...
Floating point variables.
Definition: muParserDef.h:186
ParserToken(const ParserToken &a_Tok)
Create token from another one.
Encapsulation of prototypes for a numerical parser function.
ParserToken & Set(const ParserCallback &a_pCallback, const TString &a_sTok)
Set Callback type.
This file defines the error class used by the parser.