NCBI C++ ToolKit
muParserToken.h
Go to the documentation of this file.

Go to the SVN repository for this file.

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