muParser API -  1.35
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
muParserInt.cpp
Go to the documentation of this file.
1 /*
2  __________
3  _____ __ __\______ \_____ _______ ______ ____ _______
4  / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
5  | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
6  |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
7  \/ \/ \/ \/
8  Copyright (C) 2011 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 #include "muParserInt.h"
27 
28 #include <cmath>
29 #include <algorithm>
30 #include <numeric>
31 
32 using namespace std;
33 
34 /** \file
35  \brief Implementation of a parser using integer value.
36 */
37 
38 /** \brief Namespace for mathematical applications. */
39 namespace mu
40 {
41 value_type ParserInt::Abs(value_type v) { return (value_type)Round(fabs((double)v)); }
42 value_type ParserInt::Sign(value_type v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; }
43 value_type ParserInt::Ite(value_type v1,
44  value_type v2,
45  value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); }
46 value_type ParserInt::Add(value_type v1, value_type v2) { return Round(v1) + Round(v2); }
47 value_type ParserInt::Sub(value_type v1, value_type v2) { return Round(v1) - Round(v2); }
48 value_type ParserInt::Mul(value_type v1, value_type v2) { return Round(v1) * Round(v2); }
49 value_type ParserInt::Div(value_type v1, value_type v2) { return Round(v1) / Round(v2); }
50 value_type ParserInt::Mod(value_type v1, value_type v2) { return Round(v1) % Round(v2); }
51 value_type ParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); }
52 value_type ParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); }
53 value_type ParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); }
54 value_type ParserInt::LogOr(value_type v1, value_type v2) { return Round(v1) | Round(v2); }
55 value_type ParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); }
56 value_type ParserInt::Or(value_type v1, value_type v2) { return Round(v1) || Round(v2); }
57 value_type ParserInt::Less(value_type v1, value_type v2) { return Round(v1) < Round(v2); }
58 value_type ParserInt::Greater(value_type v1, value_type v2) { return Round(v1) > Round(v2); }
59 value_type ParserInt::LessEq(value_type v1, value_type v2) { return Round(v1) <= Round(v2); }
60 value_type ParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); }
61 value_type ParserInt::Equal(value_type v1, value_type v2) { return Round(v1) == Round(v2); }
62 value_type ParserInt::NotEqual(value_type v1, value_type v2) { return Round(v1) != Round(v2); }
63 value_type ParserInt::Not(value_type v) { return !Round(v); }
64 
65 value_type ParserInt::Pow(value_type v1, value_type v2)
66 {
67  return std::pow((double)Round(v1), (double)Round(v2));
68 }
69 
70 //---------------------------------------------------------------------------
71 // Unary operator Callbacks: Infix operators
72 value_type ParserInt::UnaryMinus(value_type v)
73 {
74  return -Round(v);
75 }
76 
77 //---------------------------------------------------------------------------
78 value_type ParserInt::Sum(const value_type* a_afArg, int a_iArgc)
79 {
80  if (!a_iArgc)
81  throw ParserError(_T("too few arguments for function sum."));
82 
83  value_type fRes=0;
84  for (int i=0; i<a_iArgc; ++i)
85  fRes += a_afArg[i];
86 
87  return fRes;
88 }
89 
90 //---------------------------------------------------------------------------
91 value_type ParserInt::Min(const value_type* a_afArg, int a_iArgc)
92 {
93  if (!a_iArgc)
94  throw ParserError( _T("too few arguments for function min.") );
95 
96  value_type fRes=a_afArg[0];
97  for (int i=0; i<a_iArgc; ++i)
98  fRes = std::min(fRes, a_afArg[i]);
99 
100  return fRes;
101 }
102 
103 //---------------------------------------------------------------------------
104 value_type ParserInt::Max(const value_type* a_afArg, int a_iArgc)
105 {
106  if (!a_iArgc)
107  throw ParserError(_T("too few arguments for function min."));
108 
109  value_type fRes=a_afArg[0];
110  for (int i=0; i<a_iArgc; ++i)
111  fRes = std::max(fRes, a_afArg[i]);
112 
113  return fRes;
114 }
115 
116 //---------------------------------------------------------------------------
117 // Default value recognition callback
118 int ParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
119 {
120  string_type buf(a_szExpr);
121  std::size_t pos = buf.find_first_not_of(_T("0123456789"));
122 
123  if (pos==std::string::npos)
124  return 0;
125 
126  stringstream_type stream( buf.substr(0, pos ) );
127  int iVal(0);
128 
129  stream >> iVal;
130  if (stream.fail())
131  return 0;
132 
133  stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
134  if (stream.fail())
135  iEnd = stream.str().length();
136 
137  if (iEnd==(stringstream_type::pos_type)-1)
138  return 0;
139 
140  *a_iPos += (int)iEnd;
141  *a_fVal = (value_type)iVal;
142  return 1;
143 }
144 
145 //---------------------------------------------------------------------------
146 /** \brief Check a given position in the expression for the presence of
147  a hex value.
148  \param a_szExpr Pointer to the expression string
149  \param [in/out] a_iPos Pointer to an integer value holding the current parsing
150  position in the expression.
151  \param [out] a_fVal Pointer to the position where the detected value shall be stored.
152 
153  Hey values must be prefixed with "0x" in order to be detected properly.
154 */
155 int ParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
156 {
157  if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') )
158  return 0;
159 
160  unsigned iVal(0);
161 
162  // New code based on streams for UNICODE compliance:
163  stringstream_type::pos_type nPos(0);
164  stringstream_type ss(a_szExpr + 2);
165  ss >> std::hex >> iVal;
166  nPos = ss.tellg();
167 
168  if (nPos==(stringstream_type::pos_type)0)
169  return 1;
170 
171  *a_iPos += (int)(2 + nPos);
172  *a_fVal = (value_type)iVal;
173  return 1;
174 }
175 
176 //---------------------------------------------------------------------------
177 int ParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
178 {
179  if (a_szExpr[0]!='#')
180  return 0;
181 
182  unsigned iVal(0),
183  iBits(sizeof(iVal)*8),
184  i(0);
185 
186  for (i=0; (a_szExpr[i+1]=='0' || a_szExpr[i+1]=='1') && i<iBits; ++i)
187  iVal |= (int)(a_szExpr[i+1]=='1') << ((iBits-1)-i);
188 
189  if (i==0)
190  return 0;
191 
192  if (i==iBits)
193  throw exception_type(_T("Binary to integer conversion error (overflow)."));
194 
195  *a_fVal = (unsigned)(iVal >> (iBits-i) );
196  *a_iPos += i+1;
197 
198  return 1;
199 }
200 
201 //---------------------------------------------------------------------------
202 /** \brief Constructor.
203 
204  Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
205 */
206 ParserInt::ParserInt()
207  :ParserBase()
208 {
209  AddValIdent(IsVal); // lowest priority
210  AddValIdent(IsBinVal);
211  AddValIdent(IsHexVal); // highest priority
212 
213  InitCharSets();
214  InitFun();
215  InitOprt();
216 }
217 
218 //---------------------------------------------------------------------------
219 void ParserInt::InitConst()
220 {
221 }
222 
223 //---------------------------------------------------------------------------
224 void ParserInt::InitCharSets()
225 {
226  DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
227  DefineOprtChars( _T("+-*^/?<>=!%&|~'_") );
228  DefineInfixOprtChars( _T("/+-*^?<>=!%&|~'_") );
229 }
230 
231 //---------------------------------------------------------------------------
232 /** \brief Initialize the default functions. */
234 {
235  DefineFun( _T("sign"), Sign);
236  DefineFun( _T("abs"), Abs);
237  DefineFun( _T("if"), Ite);
238  DefineFun( _T("sum"), Sum);
239  DefineFun( _T("min"), Min);
240  DefineFun( _T("max"), Max);
241 }
242 
243 //---------------------------------------------------------------------------
244 /** \brief Initialize operators. */
246 {
247  // disable all built in operators, not all of them useful for integer numbers
248  // (they don't do rounding of values)
249  EnableBuiltInOprt(false);
250 
251  // Disable all built in operators, they wont work with integer numbers
252  // since they are designed for floating point numbers
253  DefineInfixOprt( _T("-"), UnaryMinus);
254  DefineInfixOprt( _T("!"), Not);
255 
256  DefineOprt( _T("&"), LogAnd, prLOGIC);
257  DefineOprt( _T("|"), LogOr, prLOGIC);
258  DefineOprt( _T("&&"), And, prLOGIC);
259  DefineOprt( _T("||"), Or, prLOGIC);
260 
261  DefineOprt( _T("<"), Less, prCMP);
262  DefineOprt( _T(">"), Greater, prCMP);
263  DefineOprt( _T("<="), LessEq, prCMP);
264  DefineOprt( _T(">="), GreaterEq, prCMP);
265  DefineOprt( _T("=="), Equal, prCMP);
266  DefineOprt( _T("!="), NotEqual, prCMP);
267 
268  DefineOprt( _T("+"), Add, prADD_SUB);
269  DefineOprt( _T("-"), Sub, prADD_SUB);
270 
271  DefineOprt( _T("*"), Mul, prMUL_DIV);
272  DefineOprt( _T("/"), Div, prMUL_DIV);
273  DefineOprt( _T("%"), Mod, prMUL_DIV);
274 
275  DefineOprt( _T("^"), Pow, prPOW, oaRIGHT);
276  DefineOprt( _T(">>"), Shr, prMUL_DIV+1);
277  DefineOprt( _T("<<"), Shl, prMUL_DIV+1);
278 }
279 
280 } // namespace mu
void DefineInfixOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of infix operators.
multiplication/division
Definition: muParserDef.h:232
#define _T(x)
Activate this option in order to compile with OpenMP support.
Definition: muParserDef.h:69
void DefineNameChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of functions, variables, constants.
virtual void InitFun()
Initialize the default functions.
virtual void InitOprt()
Initialize operators.
void AddValIdent(identfun_type a_pCallback)
Add a value parsing function.
Definition of a parser using integer value.
STL namespace.
power operator priority (highest)
Definition: muParserDef.h:233
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:264
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 DefineOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of binary operators and postfix operators...
comparsion operators
Definition: muParserDef.h:230
void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt=true)
Define a parser function without arguments.
Definition: muParserBase.h:133
addition
Definition: muParserDef.h:231
void DefineOprt(const string_type &a_strName, fun_type2 a_pFun, unsigned a_iPri=0, EOprtAssociativity a_eAssociativity=oaLEFT, bool a_bAllowOpt=false)
Define a binary operator.
logic operators
Definition: muParserDef.h:229
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:247
Namespace for mathematical applications.
Definition: muParser.cpp:49
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:259
void EnableBuiltInOprt(bool a_bIsOn=true)
Enable or disable the built in binary operators.
MUP_STRING_TYPE string_type
The stringtype used by the parser.
Definition: muParserDef.h:253
Mathematical expressions parser (base parser engine).
Definition: muParserBase.h:62