NCBI C++ ToolKit
muParserInt.cpp
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 #include <ncbi_pch.hpp>
27 
28 #include <cmath>
29 #include <algorithm>
30 #include <numeric>
31 
32 #define wxT(x) MUP_T(x)
33 
34 using namespace std;
35 
36 /** \file
37  \brief Implementation of a parser using integer value.
38 */
39 
40 /** \brief Namespace for mathematical applications. */
41 namespace mu
42 {
43 
44 value_type ParserInt::Abs(value_type v) { return Round(fabs(v)); }
45 value_type ParserInt::Sign(value_type v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; }
46 value_type ParserInt::Ite(value_type v1,
47  value_type v2,
48  value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); }
49 value_type ParserInt::Add(value_type v1, value_type v2) { return Round(v1) + Round(v2); }
50 value_type ParserInt::Sub(value_type v1, value_type v2) { return Round(v1) - Round(v2); }
51 value_type ParserInt::Mul(value_type v1, value_type v2) { return Round(v1) * Round(v2); }
52 value_type ParserInt::Div(value_type v1, value_type v2) { return Round(v1) / Round(v2); }
53 value_type ParserInt::Mod(value_type v1, value_type v2) { return Round(v1) % Round(v2); }
54 value_type ParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); }
55 value_type ParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); }
56 value_type ParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); }
57 value_type ParserInt::LogOr(value_type v1, value_type v2) { return Round(v1) | Round(v2); }
58 value_type ParserInt::LogXor(value_type v1, value_type v2) { return Round(v1) ^ Round(v2); }
59 value_type ParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); }
60 value_type ParserInt::Or(value_type v1, value_type v2) { return Round(v1) || Round(v2); }
61 value_type ParserInt::Less(value_type v1, value_type v2) { return Round(v1) < Round(v2); }
62 value_type ParserInt::Greater(value_type v1, value_type v2) { return Round(v1) > Round(v2); }
63 value_type ParserInt::LessEq(value_type v1, value_type v2) { return Round(v1) <= Round(v2); }
64 value_type ParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); }
68 
69 //---------------------------------------------------------------------------
70 // Unary operator Callbacks: Infix operators
71 value_type ParserInt::UnaryMinus(value_type v)
72 {
73  return -Round(v);
74 }
75 
76 //---------------------------------------------------------------------------
77 value_type ParserInt::Sum(const value_type* a_afArg, int a_iArgc)
78 {
79  if (!a_iArgc)
80  throw ParserError(wxT("too few arguments for function sum."));
81 
82  value_type fRes=0;
83  for (int i=0; i<a_iArgc; ++i)
84  fRes += a_afArg[i];
85 
86  return fRes;
87 }
88 
89 //---------------------------------------------------------------------------
90 value_type ParserInt::Min(const value_type* a_afArg, int a_iArgc)
91 {
92  if (!a_iArgc)
93  throw ParserError( wxT("too few arguments for function min.") );
94 
95  value_type fRes=a_afArg[0];
96  for (int i=0; i<a_iArgc; ++i)
97  fRes = std::min(fRes, a_afArg[i]);
98 
99  return fRes;
100 }
101 
102 //---------------------------------------------------------------------------
103 value_type ParserInt::Max(const value_type* a_afArg, int a_iArgc)
104 {
105  if (!a_iArgc)
106  throw ParserError(wxT("too few arguments for function min."));
107 
108  value_type fRes=a_afArg[0];
109  for (int i=0; i<a_iArgc; ++i)
110  fRes = std::max(fRes, a_afArg[i]);
111 
112  return fRes;
113 }
114 
115 //---------------------------------------------------------------------------
116 // Default value recognition callback
117 int ParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
118 {
119  string_type buf(a_szExpr);
120  std::size_t pos = buf.find_first_not_of(wxT("0123456789"));
121  if (pos==std::string::npos)
122  return 0;
123 
124  stringstream_type stream( buf.substr(0, pos ) );
125  int iVal(0);
126 
127  stream >> iVal;
128  auto iEnd = stream.tellg(); // Position after reading
129 
130  if (iEnd==-1)
131  return 0;
132 
133  *a_iPos += iEnd;
134  *a_fVal = (value_type)iVal;
135  return 1;
136 }
137 
138 //---------------------------------------------------------------------------
139 int ParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
140 {
141  if (a_szExpr[0]!='$')
142  return 0;
143 
144  unsigned iVal(0);
145 
146 // New code based on streams for UNICODE compliance:
148  stringstream_type ss(a_szExpr+1);
149  ss >> std::hex >> iVal;
150  nPos = ss.tellg();
151 
152  if (nPos==(stringstream_type::pos_type)0)
153  return 1;
154 
155  *a_iPos += 1 + nPos;
156  *a_fVal = iVal;
157  return true;
158 }
159 
160 //---------------------------------------------------------------------------
161 int ParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
162 {
163  if (a_szExpr[0]!='#')
164  return 0;
165 
166  unsigned iVal(0),
167  iBits(sizeof(iVal)*8),
168  i(0);
169 
170  for (i=0; (a_szExpr[i+1]=='0' || a_szExpr[i+1]=='1') && i<iBits; ++i)
171  iVal |= (int)(a_szExpr[i+1]=='1') << ((iBits-1)-i);
172 
173  if (i==0)
174  return 0;
175 
176  if (i==iBits)
177  throw exception_type(wxT("Binary to integer conversion error (overflow)."));
178 
179  *a_fVal = (unsigned)(iVal >> (iBits-i) );
180  *a_iPos += i+1;
181 
182  return 1;
183 }
184 
185 //---------------------------------------------------------------------------
186 /** \brief Constructor.
187 
188  Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
189 */
190 ParserInt::ParserInt()
191  :ParserBase()
192 {
196 
197  InitCharSets();
198  InitFun();
199  InitOprt();
200 }
201 
202 //---------------------------------------------------------------------------
204 {
205 }
206 
207 //---------------------------------------------------------------------------
209 {
210  DefineNameChars( wxT("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
211  DefineOprtChars( wxT("+-*^/?<>=!%&|~'_") );
212  DefineInfixOprtChars( wxT("/+-*^?<>=!%&|~'_") );
213 }
214 
215 //---------------------------------------------------------------------------
216 /** \brief Initialize the default functions. */
218 {
219  DefineFun( wxT("sign"), Sign);
220  DefineFun( wxT("abs"), Abs);
221  DefineFun( wxT("if"), Ite);
222  DefineFun( wxT("sum"), Sum);
223  DefineFun( wxT("min"), Min);
224  DefineFun( wxT("max"), Max);
225 }
226 
227 //---------------------------------------------------------------------------
228 /** \brief Initialize operators. */
230 {
231  // disable all built in operators, not all of them usefull for integer numbers
232  // (they don't do rounding of values)
233  EnableBuiltInOprt(false);
234 
235  // Disable all built in operators, they wont work with integer numbers
236  // since they are designed for floating point numbers
238  DefineInfixOprt( wxT("!"), Not);
239 
240  DefineOprt( wxT("&"), LogAnd, prLOGIC);
241  DefineOprt( wxT("|"), LogOr, prLOGIC);
242  DefineOprt( wxT("^"), LogXor, prLOGIC);
243  DefineOprt( wxT("&&"), And, prLOGIC);
244  DefineOprt( wxT("||"), Or, prLOGIC);
245 
246  DefineOprt( wxT("<"), Less, prCMP);
247  DefineOprt( wxT(">"), Greater, prCMP);
248  DefineOprt( wxT("<="), LessEq, prCMP);
249  DefineOprt( wxT(">="), GreaterEq, prCMP);
250  DefineOprt( wxT("=="), Equal, prCMP);
251  DefineOprt( wxT("!="), NotEqual, prCMP);
252 
253  DefineOprt( wxT("+"), Add, prADD_SUB);
254  DefineOprt( wxT("-"), Sub, prADD_SUB);
255 
256  DefineOprt( wxT("*"), Mul, prMUL_DIV);
257  DefineOprt( wxT("/"), Div, prMUL_DIV);
258  DefineOprt( wxT("%"), Mod, prMUL_DIV);
259 
260  DefineOprt( wxT(">>"), Shr, prMUL_DIV+1);
261  DefineOprt( wxT("<<"), Shl, prMUL_DIV+1);
262 }
263 
264 } // namespace mu
static int pos_type
Definition: charconv.c:169
Mathematical expressions parser (base parser engine).
Definition: muParserBase.h:64
void AddValIdent(identfun_type a_pCallback)
void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true)
Add a user defined operator.
void DefineOprt(const string_type &a_strName, fun_type2 a_pFun, unsigned a_iPri=0, bool a_bAllowOpt=false)
Define a binary operator.
void DefineOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of binary operators and postfix operators.
void DefineInfixOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of infix operators.
void DefineNameChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of functions, variables, constants.
void EnableBuiltInOprt(bool a_bIsOn=true)
Enable or disable the built in binary operators.
void DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt=true)
Definition: muParserBase.h:138
Error class of the parser.
static int IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_iVal)
static value_type Abs(value_type)
Definition: muParserInt.cpp:44
static value_type LessEq(value_type v1, value_type v2)
Definition: muParserInt.cpp:63
static value_type GreaterEq(value_type v1, value_type v2)
Definition: muParserInt.cpp:64
static value_type Shl(value_type v1, value_type v2)
Definition: muParserInt.cpp:55
static value_type Not(value_type v1)
Definition: muParserInt.cpp:67
static value_type Div(value_type v1, value_type v2)
Definition: muParserInt.cpp:52
static value_type Mul(value_type v1, value_type v2)
Definition: muParserInt.cpp:51
static value_type NotEqual(value_type v1, value_type v2)
Definition: muParserInt.cpp:66
virtual void InitConst()
static value_type Shr(value_type v1, value_type v2)
Definition: muParserInt.cpp:54
static value_type UnaryMinus(value_type)
Definition: muParserInt.cpp:71
static value_type Or(value_type v1, value_type v2)
Definition: muParserInt.cpp:60
static value_type Greater(value_type v1, value_type v2)
Definition: muParserInt.cpp:62
static value_type And(value_type v1, value_type v2)
Definition: muParserInt.cpp:59
static value_type Add(value_type v1, value_type v2)
Definition: muParserInt.cpp:49
static value_type Mod(value_type v1, value_type v2)
Definition: muParserInt.cpp:53
static value_type Max(const value_type *a_afArg, int a_iArgc)
virtual void InitOprt()
Initialize operators.
virtual void InitCharSets()
static value_type Sub(value_type v1, value_type v2)
Definition: muParserInt.cpp:50
static value_type LogOr(value_type v1, value_type v2)
Definition: muParserInt.cpp:57
static value_type LogXor(value_type v1, value_type v2)
Definition: muParserInt.cpp:58
static value_type Ite(value_type, value_type, value_type)
Definition: muParserInt.cpp:46
static value_type Min(const value_type *a_afArg, int a_iArgc)
Definition: muParserInt.cpp:90
static value_type Equal(value_type v1, value_type v2)
Definition: muParserInt.cpp:65
static value_type Sign(value_type)
Definition: muParserInt.cpp:45
static value_type Sum(const value_type *a_afArg, int a_iArgc)
Definition: muParserInt.cpp:77
static value_type Less(value_type v1, value_type v2)
Definition: muParserInt.cpp:61
static value_type LogAnd(value_type v1, value_type v2)
Definition: muParserInt.cpp:56
static int IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_iVal)
static int IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_iVal)
virtual void InitFun()
Initialize the default functions.
const CVect2< U > & v2
Definition: globals.hpp:440
char * buf
int i
static void hex(unsigned char c)
Definition: mdb_dump.c:56
#define wxT(x)
Definition: muParserInt.cpp:32
Definition of a parser using integer value.
constexpr bool NotEqual(std::integral_constant< ncbi::NStr::ECase, case_sensitive > tag, const ct_basic_string< _CharType > &l, const ct_basic_string< _CharType > &r)
constexpr bool Equal(std::integral_constant< ncbi::NStr::ECase, case_sensitive > tag, const ct_basic_string< _CharType > &l, const ct_basic_string< _CharType > &r)
Namespace for mathematical applications.
Definition: muParser.h:41
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:246
std::basic_stringstream< char_type, std::char_traits< char_type >, std::allocator< char_type > > stringstream_type
Typedef for easily using stringstream that respect the parser stringtype.
Definition: muParserDef.h:251
@ prCMP
comparsion operators
Definition: muParserDef.h:211
@ prLOGIC
logic operators
Definition: muParserDef.h:210
@ prADD_SUB
addition
Definition: muParserDef.h:212
@ prMUL_DIV
multiplication/division
Definition: muParserDef.h:213
double value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:228
std::string string_type
The stringtype used by the parser.
Definition: muParserDef.h:234
#define fabs(v)
Definition: ncbi_dispd.c:46
T max(T x_, T y_)
T min(T x_, T y_)
SNot< T > Not(T o)
static int Round(double Num)
Definition: su_pssm.cpp:88
Modified on Sun Mar 03 03:11:07 2024 by modify_doxy.py rev. 669887