NCBI C++ ToolKit
expr.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CORELIB___EXPR__HPP
2 #define CORELIB___EXPR__HPP
3 
4 
5 /* $Id: expr.hpp 99041 2023-02-07 13:59:13Z ivanov $
6  * ===========================================================================
7  *
8  * PUBLIC DOMAIN NOTICE
9  * National Center for Biotechnology Information
10  *
11  * This software/database is a "United States Government Work" under the
12  * terms of the United States Copyright Act. It was written as part of
13  * the author's official duties as a United States Government employee and
14  * thus cannot be copyrighted. This software/database is freely available
15  * to the public for use. The National Library of Medicine and the U.S.
16  * Government have not placed any restriction on its use or reproduction.
17  *
18  * Although all reasonable efforts have been taken to ensure the accuracy
19  * and reliability of the software and data, the NLM and the U.S.
20  * Government do not and cannot warrant the performance or results that
21  * may be obtained by using this software or data. The NLM and the U.S.
22  * Government disclaim all warranties, express or implied, including
23  * warranties of performance, merchantability or fitness for any particular
24  * purpose.
25  *
26  * Please cite the author in any work or product based on this material.
27  *
28  * ===========================================================================
29  *
30  * Author: Sergey Sikorskiy, Mikhail Zakharov
31  *
32  * File Description:
33  * Expression parsing and evaluation.
34  *
35  * ===========================================================================
36  */
37 
38 #include <corelib/ncbistd.hpp>
39 
41 
42 
43 
44 ////////////////////////////////////////////////////////////////////////////////
45 class CExprSymbol;
46 
48 {
49 public:
50  CExprValue(void);
51  template <typename VT> CExprValue(VT* value)
52  {
53  // If you got here, you are using wrong data type.
54  value->please_use_Int8_double_bool_instead();
55  }
60  CExprValue(double value);
61  CExprValue(bool value);
62  CExprValue(string value);
63  CExprValue(const CExprValue& value);
64 
65 public:
66  /// Value type.
67  enum EValue {
71  eSTRING
72  };
73 
74 public:
75  EValue GetType(void) const
76  {
77  return m_Tag;
78  }
80  {
81  m_Tag = type;
82  }
83 
84  string GetString(void) const
85  {
86  string str;
87 
88  switch (m_Tag) {
89  case eINT:
91  return str;
92  case eBOOL:
93  return bval ? "true" : "false";
94  case eSTRING:
95  return m_sval;
96  default:
97  break;
98  }
99 
100  return NStr::DoubleToString(fval);
101  }
102 
103  double GetDouble(void) const
104  {
105  switch (m_Tag) {
106  case eINT:
107  return static_cast<double>(ival);
108  case eBOOL:
109  return bval ? 1.0 : 0.0;
110  case eSTRING:
111  return 0;
112  default:
113  break;
114  }
115 
116  return fval;
117  }
118 
119  Int8 GetInt(void) const
120  {
121  switch (m_Tag) {
122  case eFLOAT:
123  return static_cast<Int8>(fval);
124  case eBOOL:
125  return bval ? 1 : 0;
126  case eSTRING:
127  return 0;
128  default:
129  break;
130  }
131 
132  return ival;
133  }
134 
135  bool GetBool(void) const
136  {
137  switch (m_Tag) {
138  case eINT:
139  return ival != 0;
140  case eFLOAT:
141  return fval != 0.0;
142  case eSTRING:
143  return false;
144  default:
145  break;
146  }
147 
148  return bval;
149  }
150 
151 public:
152  union {
154  double fval;
155  bool bval;
156  };
157  string m_sval;
158 
160  int m_Pos;
161 
162 private:
164 };
165 
166 ////////////////////////////////////////////////////////////////////////////////
168 {
169 public:
170  typedef Int8 (*FIntFunc1) (Int8);
171  typedef Int8 (*FIntFunc2) (Int8,Int8);
172  typedef double (*FFloatFunc1) (double);
173  typedef double (*FFloatFunc2) (double, double);
174  typedef bool (*FBoolFunc1) (bool);
175  typedef bool (*FBoolFunc2) (bool, bool);
176  typedef bool (*FStringFunc1) (const string&);
177 
178  CExprSymbol(void);
179  template <typename VT> CExprSymbol(const char* name, VT* value)
180  {
181  // If you got here, you are using wrong data type.
182  value->please_use_Int8_double_bool_instead();
183  }
184  CExprSymbol(const char* name, Uint4 value);
185  CExprSymbol(const char* name, Int4 value);
186  CExprSymbol(const char* name, Uint8 value);
187  CExprSymbol(const char* name, Int8 value);
188  CExprSymbol(const char* name, bool value);
189  CExprSymbol(const char* name, double value);
190  CExprSymbol(const char* name, string value);
191  CExprSymbol(const char* name, FIntFunc1 value);
192  CExprSymbol(const char* name, FIntFunc2 value);
193  CExprSymbol(const char* name, FFloatFunc1 value);
194  CExprSymbol(const char* name, FFloatFunc2 value);
195  CExprSymbol(const char* name, FBoolFunc1 value);
196  CExprSymbol(const char* name, FBoolFunc2 value);
197  CExprSymbol(const char* name, FStringFunc1 value);
198 
199  ~CExprSymbol(void);
200 
201 
202 public:
203  enum ESymbol {
211  eSFUNC1
212  };
213 
214 public:
216  union {
217  FIntFunc1 m_IntFunc1;
218  FIntFunc2 m_IntFunc2;
219  FFloatFunc1 m_FloatFunc1;
220  FFloatFunc2 m_FloatFunc2;
221  FBoolFunc1 m_BoolFunc1;
222  FBoolFunc2 m_BoolFunc2;
223  FStringFunc1 m_StringFunc1;
224  };
226  string m_Name;
228 };
229 
230 ////////////////////////////////////////////////////////////////////////////////
232 {
233 public:
234  enum EErrCode {
236  eTypeConversionError
237  };
238 
239 
241  const CDiagCompileInfo& info,
242  const CException* prev_exception, EErrCode err_code,
243  const string& message, int pos,
244  EDiagSev severity = eDiag_Error)
245  : CException(info, prev_exception, message, severity)
246  , m_Pos(pos)
248 
249  virtual const char* GetErrCodeString(void) const override;
250 
251  virtual void ReportExtra(ostream& out) const override;
252 
253 public:
254  int GetPos(void) const
255  {
256  return m_Pos;
257  }
258 
259 protected:
260  virtual void x_Assign(const CException& src) override;
261 
262 private:
263  int m_Pos;
264 };
265 
266 ////////////////////////////////////////////////////////////////////////////////
268 {
269 public:
270  /// Parser flags
271  enum EAutoVar {
272  fAllowAutoVar = 0, //< create variables without previous declaration
273  fDenyAutoVar = (1 << 0), //< call AddSymbol() to register a variable
274  fLogicalOnly = (1 << 1), //< '/','.','[0-9]' is interpreted as a part of a symbol (to allow directories)
275 
276  // Legacy
277  eAllowAutoVar = fAllowAutoVar,
278  eDenyAutoVar = fDenyAutoVar
279  };
280 
281  typedef int TParserFlags;
282 
283  CExprParser(TParserFlags auto_var = 0);
284  ~CExprParser(void);
285 
286 public:
287  void Parse(const char* str);
288 
289  const CExprValue& GetResult(void) const
290  {
291  if (m_v_sp != 1) {
292  ReportError("Result is not available");
293  }
294 
295  return m_VStack[0];
296  }
297 
298  template <typename VT>
299  CExprSymbol* AddSymbol(const char* name, VT value);
300 
301 private:
302  enum EOperator {
303  eBEGIN, eOPERAND, eERROR, eEND,
304  eLPAR, eRPAR, eFUNC, ePOSTINC, ePOSTDEC,
305  ePREINC, ePREDEC, ePLUS, eMINUS, eNOT, eCOM,
307  eMUL, eDIV, eMOD,
308  eADD, eSUB,
309  eASL, eASR, eLSR,
310  eGT, eGE, eLT, eLE,
311  eEQ, eNE,
315  eSET, eSETADD, eSETSUB, eSETMUL, eSETDIV, eSETMOD, eSETASL, eSETASR, eSETLSR,
316  eSETAND, eSETXOR, eSETOR, eSETPOW,
318  eTERMINALS
319  };
320 
321 private:
322  EOperator Scan(bool operand);
323  bool Assign(void);
324  CExprSymbol* GetSymbol(const char* name) const;
325 
326  static void ReportError(int pos, const string& msg)
327  {
328  NCBI_THROW2(CExprParserException, eParseError, msg, pos);
329  }
330  void ReportError(const string& msg) const { ReportError(m_Pos - 1, msg); }
331 
332  EOperator IfChar(
333  char c, EOperator val,
334  EOperator val_def);
335  EOperator IfElseChar(
336  char c1, EOperator val1,
337  char c2, EOperator val2,
338  EOperator val_def);
339  EOperator IfLongest2ElseChar(
340  char c1, char c2,
341  EOperator val_true_longest,
342  EOperator val_true,
343  EOperator val_false,
344  EOperator val_def);
345 
347  {
348  return m_ParserFlags & fDenyAutoVar;
349  }
350 
351  bool LogicalOnly(void) const { return (m_ParserFlags & fLogicalOnly) != 0;}
352 
353 private:
354  enum {hash_table_size = 1013};
355  CExprSymbol* hash_table[hash_table_size];
356 
357  enum {max_stack_size = 256};
358  enum {max_expression_length = 1024};
359 
360  static int sm_lpr[eTERMINALS];
361  static int sm_rpr[eTERMINALS];
362 
363  CExprValue m_VStack[max_stack_size];
364  int m_v_sp;
365  EOperator m_OStack[max_stack_size];
366  int m_o_sp;
367  const char* m_Buf;
368  int m_Pos;
370 };
371 
372 
373 ////////////////////////////////////////////////////////////////////////////////
374 // Inline methods.
375 //
376 
378 unsigned string_hash_function(const char* p);
379 
380 template <typename VT>
381 inline
383 {
384  CExprSymbol* sp = GetSymbol(name);
385 
386  if (!sp) {
387  // Add ...
388  sp = new CExprSymbol(name, value);
389 
390  unsigned h = string_hash_function(name) % hash_table_size;
391  sp->m_Next = hash_table[h];
392  hash_table[h] = sp;
393  }
394 
395  return sp;
396 }
397 
398 inline
401  char c, EOperator val,
402  EOperator val_def)
403 {
404  if (m_Buf[m_Pos] == c) {
405  m_Pos += 1;
406  return val;
407  }
408 
409  return val_def;
410 }
411 
412 inline
415  char c1, EOperator val1,
416  char c2, EOperator val2,
417  EOperator val_def)
418 {
419  if (m_Buf[m_Pos] == c1) {
420  m_Pos += 1;
421  return val1;
422  } else if (m_Buf[m_Pos] == c2) {
423  m_Pos += 1;
424  return val2;
425  }
426 
427  return val_def;
428 }
429 
430 inline
433  char c1, char c2,
434  EOperator val_true_longest,
435  EOperator val_true,
436  EOperator val_false,
437  EOperator val_def)
438 {
439  if (m_Buf[m_Pos] == c1) {
440  m_Pos += 1;
441  return IfChar(c2, val_true_longest, val_true);
442  } else if (m_Buf[m_Pos] == c2) {
443  m_Pos += 1;
444  return val_false;
445  }
446 
447  return val_def;
448 }
449 
451 
452 #endif /* CORELIB___EXPR__HPP */
453 
void x_Assign(CObject_id &dst, const CObject_id &src)
Definition: Seq_id.cpp:203
Incapsulate compile time information such as __FILE__, __LINE__, NCBI_MODULE, current function.
Definition: ncbidiag.hpp:65
int GetPos(void) const
Definition: expr.hpp:254
virtual CExprParserException(const CDiagCompileInfo &info, const CException *prev_exception, EErrCode err_code, const string &message, int pos, EDiagSev severity=eDiag_Error) const char GetErrCodeString)(void) const override
Definition: expr.hpp:249
@ hash_table_size
Definition: expr.hpp:354
int m_Pos
Definition: expr.hpp:368
EOperator IfElseChar(char c1, EOperator val1, char c2, EOperator val2, EOperator val_def)
Definition: expr.hpp:414
CExprSymbol * hash_table[hash_table_size]
Definition: expr.hpp:355
int TParserFlags
Definition: expr.hpp:281
CExprSymbol * AddSymbol(const char *name, VT value)
Definition: expr.hpp:382
TParserFlags m_ParserFlags
Definition: expr.hpp:369
TParserFlags AutoCreateVariable(void) const
Definition: expr.hpp:346
int m_v_sp
Definition: expr.hpp:364
EOperator IfChar(char c, EOperator val, EOperator val_def)
Definition: expr.hpp:400
bool LogicalOnly(void) const
Definition: expr.hpp:351
@ eOPERAND
Definition: expr.hpp:303
static void ReportError(int pos, const string &msg)
Definition: expr.hpp:326
const CExprValue & GetResult(void) const
Definition: expr.hpp:289
EOperator IfLongest2ElseChar(char c1, char c2, EOperator val_true_longest, EOperator val_true, EOperator val_false, EOperator val_def)
Definition: expr.hpp:432
EAutoVar
Parser flags.
Definition: expr.hpp:271
const char * m_Buf
Definition: expr.hpp:367
void ReportError(const string &msg) const
Definition: expr.hpp:330
int m_o_sp
Definition: expr.hpp:366
CExprSymbol * GetSymbol(const char *name) const
Definition: expr.cpp:496
FIntFunc1 m_IntFunc1
Definition: expr.hpp:217
FStringFunc1 m_StringFunc1
Definition: expr.hpp:223
ESymbol m_Tag
Definition: expr.hpp:215
CExprSymbol * m_Next
Definition: expr.hpp:227
FBoolFunc1 m_BoolFunc1
Definition: expr.hpp:221
FFloatFunc1 m_FloatFunc1
Definition: expr.hpp:219
string m_Name
Definition: expr.hpp:226
CExprValue m_Val
Definition: expr.hpp:225
CExprSymbol(const char *name, VT *value)
Definition: expr.hpp:179
FIntFunc2 m_IntFunc2
Definition: expr.hpp:218
FFloatFunc2 m_FloatFunc2
Definition: expr.hpp:220
@ eVARIABLE
Definition: expr.hpp:204
FBoolFunc2 m_BoolFunc2
Definition: expr.hpp:222
Int8 GetInt(void) const
Definition: expr.hpp:119
CExprValue(VT *value)
Definition: expr.hpp:51
bool GetBool(void) const
Definition: expr.hpp:135
void SetType(EValue type)
Definition: expr.hpp:79
EValue GetType(void) const
Definition: expr.hpp:75
CExprSymbol * m_Var
Definition: expr.hpp:159
double GetDouble(void) const
Definition: expr.hpp:103
Int8 ival
Definition: expr.hpp:153
bool bval
Definition: expr.hpp:155
string m_sval
Definition: expr.hpp:157
double fval
Definition: expr.hpp:154
string GetString(void) const
Definition: expr.hpp:84
EValue
Value type.
Definition: expr.hpp:67
@ eBOOL
Definition: expr.hpp:70
@ eINT
Definition: expr.hpp:68
@ eFLOAT
Definition: expr.hpp:69
int m_Pos
Definition: expr.hpp:160
EValue m_Tag
Definition: expr.hpp:163
Include a standard set of the NCBI C++ Toolkit most basic headers.
std::ofstream out("events_result.xml")
main entry point for tests
unsigned string_hash_function(const char *p)
Definition: expr.cpp:376
#define bool
Definition: bool.h:34
static int type
Definition: getdata.c:31
static const char * str(char *buf, int n)
Definition: stats.c:84
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
@ eDiag_Error
Error message.
Definition: ncbidiag.hpp:653
#define NCBI_THROW2(exception_class, err_code, message, extra)
Throw exception with extra parameter.
Definition: ncbiexpt.hpp:1754
#define NCBI_EXCEPTION_DEFAULT_IMPLEMENTATION(exception_class, base_class)
Helper macro for default exception implementation.
Definition: ncbiexpt.hpp:1300
#define EXCEPTION_VIRTUAL_BASE
Do not use virtual base classes in exception declaration at all, because in this case derived class s...
Definition: ncbiexpt.hpp:1388
int32_t Int4
4-byte (32-bit) signed integer
Definition: ncbitype.h:102
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static string DoubleToString(double value, int precision=-1, TNumToStringFlags flags=0)
Convert double to string.
Definition: ncbistr.hpp:5187
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
#define NCBI_XNCBI_EXPORT
Definition: ncbi_export.h:1283
@ eGT
Definition: intron.hpp:414
static MDB_envinfo info
Definition: mdb_load.c:37
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
@ eEND
Definition: type.c:6
Modified on Sat Apr 20 12:22:27 2024 by modify_doxy.py rev. 669887