diff options
author | astrojhgu <astrojhgu@ed2142bd-67ad-457f-ba7c-d818d4011675> | 2009-08-21 04:14:23 +0000 |
---|---|---|
committer | astrojhgu <astrojhgu@ed2142bd-67ad-457f-ba7c-d818d4011675> | 2009-08-21 04:14:23 +0000 |
commit | 3099d2011c505c0c73c4304344e9ee936caab7a3 (patch) | |
tree | adaa9bb1490be182a1af818b1a17d4a8c7d50c6f | |
parent | 36f6c2b1b422b51a4e7dd9d50f9f30aba49aefd3 (diff) | |
download | opt-utilities-3099d2011c505c0c73c4304344e9ee936caab7a3.tar.bz2 |
git-svn-id: file:///home/svn/opt_utilities@45 ed2142bd-67ad-457f-ba7c-d818d4011675
-rw-r--r-- | makefile | 13 | ||||
-rw-r--r-- | models/strmodel1d.hpp | 2 | ||||
-rw-r--r-- | muparser/makefile | 16 | ||||
-rw-r--r-- | muparser/muParser.cpp | 259 | ||||
-rw-r--r-- | muparser/muParser.h | 104 | ||||
-rw-r--r-- | muparser/muParserBase.cpp | 1364 | ||||
-rw-r--r-- | muparser/muParserBase.h | 324 | ||||
-rw-r--r-- | muparser/muParserBytecode.cpp | 396 | ||||
-rw-r--r-- | muparser/muParserBytecode.h | 148 | ||||
-rw-r--r-- | muparser/muParserCallback.cpp | 198 | ||||
-rw-r--r-- | muparser/muParserCallback.h | 94 | ||||
-rw-r--r-- | muparser/muParserDLL.cpp | 657 | ||||
-rw-r--r-- | muparser/muParserDLL.h | 123 | ||||
-rw-r--r-- | muparser/muParserDef.h | 239 | ||||
-rw-r--r-- | muparser/muParserError.cpp | 300 | ||||
-rw-r--r-- | muparser/muParserError.h | 160 | ||||
-rw-r--r-- | muparser/muParserFixes.h | 196 | ||||
-rw-r--r-- | muparser/muParserInt.cpp | 264 | ||||
-rw-r--r-- | muparser/muParserInt.h | 93 | ||||
-rw-r--r-- | muparser/muParserStack.h | 120 | ||||
-rw-r--r-- | muparser/muParserTest.cpp | 1125 | ||||
-rw-r--r-- | muparser/muParserTest.h | 176 | ||||
-rw-r--r-- | muparser/muParserToken.h | 464 | ||||
-rw-r--r-- | muparser/muParserTokenReader.cpp | 822 | ||||
-rw-r--r-- | muparser/muParserTokenReader.h | 156 |
25 files changed, 5 insertions, 7808 deletions
@@ -18,12 +18,12 @@ LDL=-ldl export AR = ar rv export RANLIB = ranlib export RM=rm -f -export CCFLAGS=-DNDEBUG -ansi -pedantic -g -O2 -Wall -c -I . -export CXXFLAGS=-DNDEBUG -ansi -pedantic -g -O2 -Wall -c -I . -DHAVE_X_ERROR +export CCFLAGS=-DNDEBUG -ansi -pedantic -g -O2 -Wall -c -I . -g +export CXXFLAGS=-DNDEBUG -ansi -pedantic -g -O2 -Wall -c -I . -g INC=-I. -I/usr/include/gsl/ -LIB= -L./muparser $(LDL) -lmuparser -g -lgsl -lgslcblas +LIB=-lgsl -lgslcblas OPT_OBJ=models/models.o version_ctrl.o models/strmodel1d.o TARGET=liboptcall test_dl.so models/strmodel1d.o models/models.o @@ -47,20 +47,15 @@ test_dl.so:models/dlmodel_template.c models/strmodel1d.o:models/strmodel1d.cc models/strmodel1d.hpp - $(CXX) -c $< -o $@ -I./muparser $(INC) $(CXXFLAGS) + $(CXX) -c $< -o $@ $(CXXFLAGS) -libmuparser: - make -C muparser - liboptcall: make -C interface clean: rm -f `find .|grep \~` rm -f `find .|grep '\.o'` - rm -f muparser/libmuparser.a - make -C muparser clean make -C interface clean distclean:clean diff --git a/models/strmodel1d.hpp b/models/strmodel1d.hpp index 8d992a0..af74453 100644 --- a/models/strmodel1d.hpp +++ b/models/strmodel1d.hpp @@ -4,7 +4,7 @@ #include <cmath> #include <sstream> #include <cassert> -#include <muparser/muParser.h> +#include <muParser/muParser.h> #include <vector> #include <string> diff --git a/muparser/makefile b/muparser/makefile deleted file mode 100644 index 17e342d..0000000 --- a/muparser/makefile +++ /dev/null @@ -1,16 +0,0 @@ -MUP_OBJ=muParserBase.o muParser.o muParserInt.o\ - muParserBytecode.o muParserDLL.o\ - muParserTest.o\ - muParserCallback.o muParserError.o\ - muParserTokenReader.o - -libmuparser.a:$(MUP_OBJ) - $(AR) $@ *.o - -.cpp.o: - $(CXX) $< $(CXXFLAGS) - -clean: - $(RM) *.o - - diff --git a/muparser/muParser.cpp b/muparser/muParser.cpp deleted file mode 100644 index e92b1a2..0000000 --- a/muparser/muParser.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-#include "muParser.h"
-
-#include <cmath>
-#include <algorithm>
-#include <numeric>
-
-/** \brief Pi (what else?). */
-#define PARSER_CONST_PI 3.141592653589793238462643
-
-/** \brief The eulerian number. */
-#define PARSER_CONST_E 2.718281828459045235360287
-
-using namespace std;
-
-
-/** \brief Namespace for mathematical applications. */
-namespace mu
-{
-
-//---------------------------------------------------------------------------
-// Trigonometric function
-value_type Parser::Sin(value_type v) { return sin(v); }
-value_type Parser::Cos(value_type v) { return cos(v); }
-value_type Parser::Tan(value_type v) { return tan(v); }
-value_type Parser::ASin(value_type v) { return asin(v); }
-value_type Parser::ACos(value_type v) { return acos(v); }
-value_type Parser::ATan(value_type v) { return atan(v); }
-value_type Parser::Sinh(value_type v) { return sinh(v); }
-value_type Parser::Cosh(value_type v) { return cosh(v); }
-value_type Parser::Tanh(value_type v) { return tanh(v); }
-value_type Parser::ASinh(value_type v) { return log(v + sqrt(v * v + 1)); }
-value_type Parser::ACosh(value_type v) { return log(v + sqrt(v * v - 1)); }
-value_type Parser::ATanh(value_type v) { return ((value_type)0.5 * log((1 + v) / (1 - v))); }
-
-//---------------------------------------------------------------------------
-// Logarithm functions
-value_type Parser::Log2(value_type v) { return log(v)/log((value_type)2); } // Logarithm base 2
-value_type Parser::Log10(value_type v) { return log10(v); } // Logarithm base 10
-value_type Parser::Ln(value_type v) { return log(v); } // Logarithm base e (natural logarithm)
-
-//---------------------------------------------------------------------------
-// misc
-value_type Parser::Exp(value_type v) { return exp(v); }
-value_type Parser::Abs(value_type v) { return fabs(v); }
-value_type Parser::Sqrt(value_type v) { return sqrt(v); }
-value_type Parser::Rint(value_type v) { return floor(v + (value_type)0.5); }
-value_type Parser::Sign(value_type v) { return (value_type)((v<0) ? -1 : (v>0) ? 1 : 0); }
-
-//---------------------------------------------------------------------------
-// Conditional (if then else)
-value_type Parser::Ite(value_type v1, value_type v2, value_type v3) { return (v1==1) ? v2 : v3; }
-
-//---------------------------------------------------------------------------
-// Unary operator Callbacks: Infix operators
-value_type Parser::UnaryMinus(value_type v) { return -v; }
-
-//---------------------------------------------------------------------------
-// Functions with variable number of arguments
-// sum
-value_type Parser::Sum(const value_type *a_afArg, int a_iArgc)
-{
- if (!a_iArgc)
- throw exception_type(_T("too few arguments for function sum."));
-
- value_type fRes=0;
- for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
- return fRes;
-}
-
-//---------------------------------------------------------------------------
-// mean value
-value_type Parser::Avg(const value_type *a_afArg, int a_iArgc)
-{
- if (!a_iArgc)
- throw exception_type(_T("too few arguments for function sum."));
-
- value_type fRes=0;
- for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
- return fRes/(double)a_iArgc;
-}
-
-//---------------------------------------------------------------------------
-// minimum
-value_type Parser::Min(const value_type *a_afArg, int a_iArgc)
-{
- if (!a_iArgc)
- throw exception_type(_T("too few arguments for function min."));
-
- value_type fRes=a_afArg[0];
- for (int i=0; i<a_iArgc; ++i) fRes = std::min(fRes, a_afArg[i]);
-
- return fRes;
-}
-
-//---------------------------------------------------------------------------
-// maximum
-value_type Parser::Max(const value_type *a_afArg, int a_iArgc)
-{
- if (!a_iArgc)
- throw exception_type(_T("too few arguments for function min."));
-
- value_type fRes=a_afArg[0];
- for (int i=0; i<a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]);
-
- return fRes;
-}
-
-//---------------------------------------------------------------------------
-// Default value recognition callback
-bool Parser::IsVal(const char_type *a_szExpr, int &a_iPos, value_type &a_fVal)
-{
- value_type fVal(0);
-
-// thanks to CodeProject member sailorickm for writing this fix:
-// http://www.codeproject.com/cpp/FastMathParser.asp?msg=1354598#xx1354598xx
-// i cant test it myself, if you see problems please contact me.
-#if defined (__hpux) || (defined __GNUC__ && (__GNUC__ == 3 && (__GNUC_MINOR__ < 3 )))
- int iEnd = 0;
- int nAssigned = sscanf(a_szExpr, "%lf%n", &fVal, &iEnd);
- if (nAssigned == 0)
- iEnd = -1;
-#else
- stringstream_type stream(a_szExpr);
- stream.seekg(0); // todo: check if this really is necessary
- stream >> fVal;
- int iEnd = stream.tellg(); // Position after reading
-#endif
-
- if (iEnd==-1)
- return false;
-
- a_iPos += iEnd;
- a_fVal = fVal;
- return true;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Constructor.
-
- Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
-*/
-Parser::Parser()
- :ParserBase()
- ,m_fEpsilon((value_type)1e-7)
-{
- AddValIdent(IsVal);
-
- InitCharSets();
- InitFun();
- InitConst();
- InitOprt();
-}
-
-//---------------------------------------------------------------------------
-/** Define the character sets. */
-void Parser::InitCharSets()
-{
- DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
- DefineOprtChars( _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_") );
- DefineInfixOprtChars( _T("/+-*^?<>=#!$%&|~'_") );
-}
-
-//---------------------------------------------------------------------------
-/** \brief Initialize the default functions. */
-void Parser::InitFun()
-{
- // trigonometric functions
- DefineFun(_T("sin"), Sin);
- DefineFun(_T("cos"), Cos);
- DefineFun(_T("tan"), Tan);
- // arcus functions
- DefineFun(_T("asin"), ASin);
- DefineFun(_T("acos"), ACos);
- DefineFun(_T("atan"), ATan);
- // hyperbolic functions
- DefineFun(_T("sinh"), Sinh);
- DefineFun(_T("cosh"), Cosh);
- DefineFun(_T("tanh"), Tanh);
- // arcus hyperbolic functions
- DefineFun(_T("asinh"), ASinh);
- DefineFun(_T("acosh"), ACosh);
- DefineFun(_T("atanh"), ATanh);
- // Logarithm functions
- DefineFun(_T("log2"), Log2);
- DefineFun(_T("log10"), Log10);
- DefineFun(_T("log"), Log10);
- DefineFun(_T("ln"), Ln);
- // misc
- DefineFun(_T("exp"), Exp);
- DefineFun(_T("sqrt"), Sqrt);
- DefineFun(_T("sign"), Sign);
- DefineFun(_T("rint"), Rint);
- DefineFun(_T("abs"), Abs);
- DefineFun(_T("if"), Ite);
- // Functions with variable number of arguments
- DefineFun(_T("sum"), Sum);
- DefineFun(_T("avg"), Avg);
- DefineFun(_T("min"), Min);
- DefineFun(_T("max"), Max);
-}
-
-//---------------------------------------------------------------------------
-/** \brief Initialize operators. */
-void Parser::InitConst()
-{
- DefineConst(_T("_pi"), (value_type)PARSER_CONST_PI);
- DefineConst(_T("_e"), (value_type)PARSER_CONST_E);
-}
-
-//---------------------------------------------------------------------------
-/** \brief Initialize operators. */
-void Parser::InitOprt()
-{
- DefineInfixOprt(_T("-"), UnaryMinus);
-}
-
-//---------------------------------------------------------------------------
-/** \brief Numerically differentiate with regard to a variable. */
-value_type Parser::Diff(value_type *a_Var, value_type a_fPos) const
-{
- assert(m_fEpsilon);
- value_type fEpsilon( (a_fPos==0) ? (value_type)1e-10 : m_fEpsilon * a_fPos ),
- fRes(0), fBuf(*a_Var), f[4] = {0,0,0,0};
-
- *a_Var = a_fPos+2*fEpsilon; f[0] = Eval();
- *a_Var = a_fPos+1*fEpsilon; f[1] = Eval();
- *a_Var = a_fPos-1*fEpsilon; f[2] = Eval();
- *a_Var = a_fPos-2*fEpsilon; f[3] = Eval();
- *a_Var = fBuf; // restore variable
-
- fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon);
- return fRes;
-}
-
-} // namespace mu
diff --git a/muparser/muParser.h b/muparser/muParser.h deleted file mode 100644 index 5aff62d..0000000 --- a/muparser/muParser.h +++ /dev/null @@ -1,104 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-#ifndef MU_PARSER_H
-#define MU_PARSER_H
-
-#include "muParserBase.h"
-#include <vector>
-
-
-namespace mu
-{
-
-/** \brief Mathematical expressions parser (reference implementation).
-
- Standard implementation of the mathematical expressions parser.
- Can be used as a reference implementation for subclassing the parser.
-
- <small>
- (C) 2004-2006 Ingo Berg<br>
- ingo_berg(at)gmx.de
- </small>
-*/
-class Parser : public ParserBase
-{
-private:
- // Trigonometric functions
- static value_type Sin(value_type);
- static value_type Cos(value_type);
- static value_type Tan(value_type);
- // arcus functions
- static value_type ASin(value_type);
- static value_type ACos(value_type);
- static value_type ATan(value_type);
- // hyperbolic functions
- static value_type Sinh(value_type);
- static value_type Cosh(value_type);
- static value_type Tanh(value_type);
- // arcus hyperbolic functions
- static value_type ASinh(value_type);
- static value_type ACosh(value_type);
- static value_type ATanh(value_type);
- // Logarithm functions
- static value_type Log2(value_type); // Logarithm Base 2
- static value_type Log10(value_type); // Logarithm Base 10
- static value_type Ln(value_type); // Logarithm Base e (natural logarithm)
- // misc
- static value_type Exp(value_type);
- static value_type Abs(value_type);
- static value_type Sqrt(value_type);
- static value_type Rint(value_type);
- static value_type Sign(value_type);
- static value_type Ite(value_type, value_type, value_type);
-
- // Prefix operators
- // !!! Unary Minus is a MUST if you want to use negative signs !!!
- static value_type UnaryMinus(value_type);
-
- // Functions with variable number of arguments
- static value_type Sum(const value_type*, int); // sum
- static value_type Avg(const value_type*, int); // mean value
- static value_type Min(const value_type*, int); // minimum
- static value_type Max(const value_type*, int); // maximum
-
- static bool IsVal(const char_type *a_szExpr, int &a_iPos, value_type &a_fVal);
-
- value_type m_fEpsilon; ///< Epsilon used for numerical differentiation.
-
-public:
- Parser();
-
- virtual void InitCharSets();
- virtual void InitFun();
- virtual void InitConst();
- virtual void InitOprt();
-
- value_type Diff(value_type *a_Var, value_type a_fPos) const;
-};
-
-} // namespace mu
-
-#endif
-
diff --git a/muparser/muParserBase.cpp b/muparser/muParserBase.cpp deleted file mode 100644 index e81e53e..0000000 --- a/muparser/muParserBase.cpp +++ /dev/null @@ -1,1364 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "muParser.h"
-
-#include <cassert>
-#include <cmath>
-#include <memory>
-#include <vector>
-#include <sstream>
-
-using namespace std;
-
-
-namespace mu
-{
-
-//------------------------------------------------------------------------------
-/** \brief Identifiers for built in binary operators.
-
- When defining custom binary operators with #AddOprt(...) make sure not to choose
- names conflicting with these definitions.
-*/
-const char_type* ParserBase::c_DefaultOprt[] =
-{
- _T("<="), _T(">="), _T("!="),
- _T("=="), _T("<"), _T(">"),
- _T("+"), _T("-"), _T("*"),
- _T("/"), _T("^"), _T("and"),
- _T("or"), _T("xor"), _T("="),
- _T("("), _T(")"), _T(","), 0
-};
-
-//------------------------------------------------------------------------------
-/** \brief Constructor.
- \param a_szFormula the formula to interpret.
- \throw ParserException if a_szFormula is null.
-*/
-ParserBase::ParserBase()
- :m_pParseFormula(&ParserBase::ParseString)
- ,m_pCmdCode(0)
- ,m_vByteCode()
- ,m_vStringBuf()
- ,m_pTokenReader()
- ,m_FunDef()
- ,m_PostOprtDef()
- ,m_InfixOprtDef()
- ,m_OprtDef()
- ,m_ConstDef()
- ,m_StrVarDef()
- ,m_VarDef()
- ,m_bOptimize(true)
- ,m_bUseByteCode(true)
- ,m_bBuiltInOp(true)
- ,m_sNameChars()
- ,m_sOprtChars()
- ,m_sInfixOprtChars()
-{
- InitTokenReader();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Copy constructor.
-
- Implemented by calling Assign(a_Parser)
-*/
-ParserBase::ParserBase(const ParserBase &a_Parser)
- :m_pParseFormula(&ParserBase::ParseString)
- ,m_pCmdCode(0)
- ,m_vByteCode()
- ,m_vStringBuf()
- ,m_pTokenReader()
- ,m_FunDef()
- ,m_PostOprtDef()
- ,m_InfixOprtDef()
- ,m_OprtDef()
- ,m_ConstDef()
- ,m_StrVarDef()
- ,m_VarDef()
- ,m_bOptimize(true)
- ,m_bUseByteCode(true)
- ,m_bBuiltInOp(true)
-{
- m_pTokenReader.reset(new token_reader_type(this));
- Assign(a_Parser);
-}
-
-//---------------------------------------------------------------------------
-/** \brief Assignement operator.
-
- Implemented by calling Assign(a_Parser). Self assignement is suppressed.
- \param a_Parser Object to copy to this.
- \return *this
- \throw nothrow
-*/
-ParserBase& ParserBase::operator=(const ParserBase &a_Parser)
-{
- Assign(a_Parser);
- return *this;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Copy state of a parser object to this.
-
- Clears Variables and Functions of this parser.
- Copies the states of all internal variables.
- Resets parse function to string parse mode.
-
- \param a_Parser the source object.
-*/
-void ParserBase::Assign(const ParserBase &a_Parser)
-{
- if (&a_Parser==this)
- return;
-
- // Don't copy bytecode instead cause the parser to create new bytecode
- // by resetting the parse function.
- ReInit();
-
- m_ConstDef = a_Parser.m_ConstDef; // Copy user define constants
- m_VarDef = a_Parser.m_VarDef; // Copy user defined variables
- m_bOptimize = a_Parser.m_bOptimize;
- m_bUseByteCode = a_Parser.m_bUseByteCode;
- m_bBuiltInOp = a_Parser.m_bBuiltInOp;
- m_vStringBuf = a_Parser.m_vStringBuf;
- m_pTokenReader.reset(a_Parser.m_pTokenReader->Clone(this));
- m_StrVarDef = a_Parser.m_StrVarDef;
- m_vStringVarBuf = a_Parser.m_vStringVarBuf;
-
- // Copy function and operator callbacks
- m_FunDef = a_Parser.m_FunDef; // Copy function definitions
- m_PostOprtDef = a_Parser.m_PostOprtDef; // post value unary operators
- m_InfixOprtDef = a_Parser.m_InfixOprtDef; // unary operators for infix notation
-
- m_sNameChars = a_Parser.m_sNameChars;
- m_sOprtChars = a_Parser.m_sOprtChars;
- m_sInfixOprtChars = a_Parser.m_sInfixOprtChars;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Initialize the token reader.
-
- Create new token reader object and submit pointers to function, operator,
- constant and variable definitions.
-
- \post m_pTokenReader.get()!=0
- \throw nothrow
-*/
-void ParserBase::InitTokenReader()
-{
- m_pTokenReader.reset(new token_reader_type(this));
-}
-
-//---------------------------------------------------------------------------
-/** \brief Reset parser to string parsing mode and clear internal buffers.
-
- Clear bytecode, reset the token reader.
- \throw nothrow
-*/
-void ParserBase::ReInit() const
-{
- m_pParseFormula = &ParserBase::ParseString;
- m_vStringBuf.clear();
- m_vByteCode.clear();
- m_pTokenReader->ReInit();
-}
-
-//---------------------------------------------------------------------------
-void ParserBase::AddValIdent(identfun_type a_pCallback)
-{
- m_pTokenReader->AddValIdent(a_pCallback);
-}
-
-//---------------------------------------------------------------------------
-void ParserBase::SetVarFactory(facfun_type a_pFactory, void *pUserData)
-{
- m_pTokenReader->SetVarCreator(a_pFactory, pUserData);
-}
-
-//---------------------------------------------------------------------------
-/** \brief Add a function or operator callback to the parser.
-*/
-void ParserBase::AddCallback( const string_type &a_strName,
- const ParserCallback &a_Callback,
- funmap_type &a_Storage,
- const char_type *a_szCharSet )
-{
- if (a_Callback.GetAddr()==0)
- Error(ecINVALID_FUN_PTR);
-
- const funmap_type *pFunMap = &a_Storage;
-
- // Check for conflicting operator or function names
- if ( pFunMap!=&m_FunDef && m_FunDef.find(a_strName)!=m_FunDef.end() )
- Error(ecNAME_CONFLICT);
-
- if ( pFunMap!=&m_PostOprtDef && m_PostOprtDef.find(a_strName)!=m_PostOprtDef.end() )
- Error(ecNAME_CONFLICT);
-
- if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_InfixOprtDef.find(a_strName)!=m_InfixOprtDef.end() )
- Error(ecNAME_CONFLICT);
-
- if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_OprtDef.find(a_strName)!=m_OprtDef.end() )
- Error(ecNAME_CONFLICT);
-
- CheckName(a_strName, a_szCharSet);
- a_Storage[a_strName] = a_Callback;
- ReInit();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Check if a name contains invalid characters.
-
- \throw ParserException if the name contains invalid charakters.
-*/
-void ParserBase::CheckName(const string_type &a_sName,
- const string_type &a_szCharSet) const
-{
- if ( !a_sName.length() ||
- (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) ||
- (a_sName[0]>='0' && a_sName[0]<='9'))
- {
- Error(ecINVALID_NAME);
- }
-}
-
-//---------------------------------------------------------------------------
-/** \brief Set the formula.
- Triggers first time calculation thus the creation of the bytecode and
- scanning of used variables.
-
- \param a_strFormula Formula as string_type
- \throw ParserException in case of syntax errors.
-*/
-void ParserBase::SetExpr(const string_type &a_sExpr)
-{
- // <ibg> 20060222: Bugfix for Borland-Kylix:
- // adding a space to the expression will keep Borlands KYLIX from going wild
- // when calling tellg on a stringstream created from the expression after
- // reading a value at the end of an expression. (mu::Parser::IsVal function)
- // (tellg returns -1 otherwise causing the parser to ignore the value)
- string_type sBuf(a_sExpr + _T(" ") );
- m_pTokenReader->SetFormula(sBuf);
- ReInit();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Add a user defined operator.
- \post Will reset the Parser to string parsing mode.
-*/
-void ParserBase::DefinePostfixOprt(const string_type &a_sName,
- fun_type1 a_pFun,
- bool a_bAllowOpt)
-{
- AddCallback( a_sName,
- ParserCallback(a_pFun, a_bAllowOpt, prPOSTFIX, cmOPRT_POSTFIX),
- m_PostOprtDef,
- ValidOprtChars() );
-}
-
-//---------------------------------------------------------------------------
-/** \brief Add a user defined operator.
- \post Will reset the Parser to string parsing mode.
- \param a_sName [in] operator Identifier
- \param a_pFun [in] Operator callback function
- \param a_iPrec [in] Operator Precedence (default=prSIGN)
- \param a_bAllowOpt [in] True if operator is volatile (default=false)
-
- \sa EPrec
-*/
-void ParserBase::DefineInfixOprt(const string_type &a_sName,
- fun_type1 a_pFun,
- int a_iPrec,
- bool a_bAllowOpt)
-{
- AddCallback( a_sName,
- ParserCallback(a_pFun, a_bAllowOpt, a_iPrec, cmOPRT_INFIX),
- m_InfixOprtDef,
- ValidOprtChars() );
-}
-
-//---------------------------------------------------------------------------
-void ParserBase::DefineOprt( const string_type &a_sName,
- fun_type2 a_pFun,
- unsigned a_iPrec,
- bool a_bAllowOpt )
-{
- // Check for conflicts with built in operator names
- for (int i=0; m_bBuiltInOp && i<cmCOMMA; ++i)
- if (a_sName == string_type(c_DefaultOprt[i]))
- Error(ecBUILTIN_OVERLOAD);
-
- AddCallback( a_sName,
- ParserCallback(a_pFun, a_bAllowOpt, a_iPrec, cmOPRT_BIN),
- m_OprtDef,
- ValidOprtChars() );
-}
-
-//---------------------------------------------------------------------------
-void ParserBase::DefineStrConst(const string_type &a_strName, const string_type &a_strVal)
-{
- // Test if a constant with that names already exists
- if (m_StrVarDef.find(a_strName)!=m_StrVarDef.end())
- Error(ecNAME_CONFLICT);
-
- CheckName(a_strName, ValidNameChars());
-
- // Store variable string in internal buffer
- m_vStringVarBuf.push_back(a_strVal);
-
- // bind buffer index to variable name
- m_StrVarDef[a_strName] = m_vStringBuf.size();
-
- ReInit();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Add a user defined variable.
- \post Will reset the Parser to string parsing mode.
- \pre [assert] a_fVar!=0
- \throw ParserException in case the name contains invalid signs.
-*/
-void ParserBase::DefineVar(const string_type &a_sName, value_type *a_pVar)
-{
- if (a_pVar==0)
- Error(ecINVALID_VAR_PTR);
-
- // Test if a constant with that names already exists
- if (m_ConstDef.find(a_sName)!=m_ConstDef.end())
- Error(ecNAME_CONFLICT);
-
- if (m_FunDef.find(a_sName)!=m_FunDef.end())
- Error(ecNAME_CONFLICT);
-
- CheckName(a_sName, ValidNameChars());
- m_VarDef[a_sName] = a_pVar;
- ReInit();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Add a user defined constant.
- \post Will reset the Parser to string parsing mode.
- \throw ParserException in case the name contains invalid signs.
-*/
-void ParserBase::DefineConst(const string_type &a_sName, value_type a_fVal)
-{
- CheckName(a_sName, ValidNameChars());
- m_ConstDef[a_sName] = a_fVal;
- ReInit();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Get operator priority.
-
- \throw ParserException if a_Oprt is no operator code
-*/
-int ParserBase::GetOprtPri(const token_type &a_Tok) const
-{
- switch (a_Tok.GetCode())
- {
- // built in operators
- case cmEND: return -5;
- case cmCOMMA: return -4;
- case cmBO :
- case cmBC : return -2;
- case cmASSIGN: return -1;
- case cmAND:
- case cmXOR:
- case cmOR: return prLOGIC;
- case cmLT :
- case cmGT :
- case cmLE :
- case cmGE :
- case cmNEQ:
- case cmEQ : return prCMP;
- case cmADD:
- case cmSUB: return prADD_SUB;
- case cmMUL:
- case cmDIV: return prMUL_DIV;
- case cmPOW: return prPOW;
-
- // user defined binary operators
- case cmOPRT_INFIX:
- case cmOPRT_BIN: return a_Tok.GetPri();
- default: Error(ecINTERNAL_ERROR, 5);
- return 999;
- }
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return a map containing the used variables only. */
-const varmap_type& ParserBase::GetUsedVar() const
-{
- try
- {
- m_pTokenReader->IgnoreUndefVar(true);
- ParseString(); // implicitely create or update the map with the
- // used variables stored in the token reader if not already done
- m_pTokenReader->IgnoreUndefVar(false);
- }
- catch(exception_type &e)
- {
- m_pTokenReader->IgnoreUndefVar(false);
- throw e;
- }
-
- // Make sure to stay in string parse mode, dont call ReInit()
- // because it deletes the array with the used variables
- m_pParseFormula = &ParserBase::ParseString;
-
- return m_pTokenReader->GetUsedVar();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return a map containing the used variables only. */
-const varmap_type& ParserBase::GetVar() const
-{
- return m_VarDef;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return a map containing all parser constants. */
-const valmap_type& ParserBase::GetConst() const
-{
- return m_ConstDef;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return prototypes of all parser functions.
-
- The return type is a map of the public type #funmap_type containing the prototype
- definitions for all numerical parser functions. String functions are not part of
- this map. The Prototype definition is encapsulated in objects of the class FunProt
- one per parser function each associated with function names via a map construct.
- \return #m_FunDef
- \sa FunProt
- \throw nothrow
-*/
-const funmap_type& ParserBase::GetFunDef() const
-{
- return m_FunDef;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Retrieve the formula. */
-const string_type& ParserBase::GetExpr() const
-{
- return m_pTokenReader->GetFormula();
-}
-
-//---------------------------------------------------------------------------
-ParserBase::token_type ParserBase::ApplyNumFunc( const token_type &a_FunTok,
- const std::vector<token_type> &a_vArg) const
-{
- token_type valTok;
- int iArgCount = (unsigned)a_vArg.size();
- void *pFunc = a_FunTok.GetFuncAddr();
- assert(pFunc);
-
- // Collect the function arguments from the value stack
- switch(a_FunTok.GetArgCount())
- {
- case -1:
- // Function with variable argument count
- // copy arguments into a vector<value_type>
- {
- /** \todo remove the unnecessary argument vector by changing order in stArg. */
- std::vector<value_type> vArg;
- for (int i=0; i<iArgCount; ++i)
- vArg.push_back(a_vArg[i].GetVal());
-
- valTok.SetVal( ((multfun_type)a_FunTok.GetFuncAddr())(&vArg[0], (int)vArg.size()) );
- }
- break;
-
- case 1: valTok.SetVal( ((fun_type1)pFunc)(a_vArg[0].GetVal()) ); break;
- case 2: valTok.SetVal( ((fun_type2)pFunc)(a_vArg[1].GetVal(),
- a_vArg[0].GetVal()) ); break;
- case 3: valTok.SetVal( ((fun_type3)pFunc)(a_vArg[2].GetVal(),
- a_vArg[1].GetVal(),
- a_vArg[0].GetVal()) ); break;
- case 4: valTok.SetVal( ((fun_type4)pFunc)(a_vArg[3].GetVal(),
- a_vArg[2].GetVal(),
- a_vArg[1].GetVal(),
- a_vArg[0].GetVal()) ); break;
- case 5: valTok.SetVal( ((fun_type5)pFunc)(a_vArg[4].GetVal(),
- a_vArg[3].GetVal(),
- a_vArg[2].GetVal(),
- a_vArg[1].GetVal(),
- a_vArg[0].GetVal()) ); break;
- default: Error(ecINTERNAL_ERROR, 6);
- }
-
- // Find out if the result will depend on a variable
- /** \todo remove this loop, put content in the loop that takes the argument values.
-
- (Attention: SetVal will reset Flags.)
- */
- bool bVolatile = a_FunTok.IsFlagSet(token_type::flVOLATILE);
- for (int i=0; (bVolatile==false) && (i<iArgCount); ++i)
- bVolatile |= a_vArg[i].IsFlagSet(token_type::flVOLATILE);
-
- if (bVolatile)
- valTok.AddFlags(token_type::flVOLATILE);
-
-#if defined(_MSC_VER)
- #pragma warning( disable : 4311 )
-#endif
-
- // Formula optimization
- if ( m_bOptimize &&
- !valTok.IsFlagSet(token_type::flVOLATILE) &&
- !a_FunTok.IsFlagSet(token_type::flVOLATILE) )
- {
- m_vByteCode.RemoveValEntries(iArgCount);
- m_vByteCode.AddVal( valTok.GetVal() );
- }
- else
- {
- // operation dosnt depends on a variable or the function is flagged unoptimizeable
- // we cant optimize here...
- m_vByteCode.AddFun(pFunc, (a_FunTok.GetArgCount()==-1) ? -iArgCount : iArgCount);
- }
-
- return valTok;
-
-#if defined(_MSC_VER)
- #pragma warning( default : 4311 )
-#endif
-}
-
-//---------------------------------------------------------------------------
-/** \brief Execute a function that takes a single string argument.
-
- \param a_FunTok Function token.
- \throw exception_type If the function token is not a string function
-*/
-ParserBase::token_type ParserBase::ApplyStrFunc(const token_type &a_FunTok,
- const std::vector<token_type> &a_vArg) const
-{
- if (a_vArg.back().GetCode()!=cmSTRING)
- Error(ecSTRING_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString());
-
- token_type valTok;
- int iArgCount = (unsigned)a_vArg.size();
- void *pFunc = a_FunTok.GetFuncAddr();
- assert(pFunc);
-
- try
- {
- // Collect the function arguments from the value stack
- switch(a_FunTok.GetArgCount())
- {
- case 0: valTok.SetVal( ((strfun_type1)pFunc)(a_vArg[0].GetAsString().c_str()) ); break;
- case 1: valTok.SetVal( ((strfun_type2)pFunc)(a_vArg[1].GetAsString().c_str(),
- a_vArg[0].GetVal()) ); break;
- case 2: valTok.SetVal( ((strfun_type3)pFunc)(a_vArg[2].GetAsString().c_str(),
- a_vArg[1].GetVal(),
- a_vArg[0].GetVal()) ); break;
- default: Error(ecINTERNAL_ERROR);
- }
- }
- catch(ParserError& /*e*/)
- {
- Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString());
- }
-
- // Find out if the result will depend on a variable
- /** \todo remove this loop, put content in the loop that takes the argument values.
-
- (Attention: SetVal will reset Flags.)
- */
- bool bVolatile = a_FunTok.IsFlagSet(token_type::flVOLATILE);
- for (int i=0; (bVolatile==false) && (i<iArgCount); ++i)
- bVolatile |= a_vArg[i].IsFlagSet(token_type::flVOLATILE);
-
- if (bVolatile)
- valTok.AddFlags(token_type::flVOLATILE);
-
- // string functions won't be optimized
- m_vByteCode.AddStrFun((void*)pFunc, a_FunTok.GetArgCount(), a_vArg.back().GetIdx());
-
- return valTok;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Apply a function token.
-
- \param iArgCount Number of Arguments actually gathered used only for multiarg functions.
- \post Function have been taken from the stack, the result has been pushed
- \post The function token is removed from the stack
- \throw exception_type if Argument count does not mach function requirements.
-*/
-void ParserBase::ApplyFunc( ParserStack<token_type> &a_stOpt,
- ParserStack<token_type> &a_stVal,
- int a_iArgCount) const
-{
- assert(m_pTokenReader.get());
-
- // Operator stack empty or does not contain tokens with callback functions
- if (a_stOpt.empty() || a_stOpt.top().GetFuncAddr()==0 )
- return;
-
- token_type funTok = a_stOpt.pop();
- assert(funTok.GetFuncAddr());
-
- // Binary operators must rely on their internal operator number
- // since counting of operators relies on commas for function arguments
- // binary operators do not have commas in their expression
- int iArgCount = ( funTok.GetCode()==cmOPRT_BIN ) ? funTok.GetArgCount() : a_iArgCount;
-
- if (funTok.GetArgCount()>0 && iArgCount>funTok.GetArgCount())
- Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString());
-
- if ( funTok.GetCode()!=cmOPRT_BIN && iArgCount<funTok.GetArgCount() )
- Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString());
-
- if ( funTok.GetCode()==cmFUNC_STR && iArgCount>funTok.GetArgCount() )
- Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString());
-
- // Collect the numeric function arguments from the value stack and store them
- // in a vector
- std::vector<token_type> stArg;
- for (int i=0; i<iArgCount; ++i)
- {
- stArg.push_back( a_stVal.pop() );
- if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR )
- Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString());
- }
-
- // for string functions add the string argument
- if (funTok.GetCode()==cmFUNC_STR)
- {
- stArg.push_back( a_stVal.pop() );
- if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR )
- Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString());
- }
-
- // String functions accept only one parameter
- if (funTok.GetType()==tpSTR)
- {
- token_type token( ApplyStrFunc(funTok, stArg) );
- a_stVal.push( token );
- }
- else
- {
- token_type token( ApplyNumFunc(funTok, stArg) );
- a_stVal.push( token );
- }
-/*
-#ifdef __BORLANDC__
- // Borland C++ Compiler does not support taking references on
- // unnamed temporaries
- if (funTok.GetType()==tpSTR)
- {
- ParserToken<value_type, string_type> pt( ApplyStrFunc(funTok, stArg.back()) );
- a_stVal.push(pt);
- }
- else
- {
- ParserToken<value_type, string_type> pt( ApplyNumFunc(funTok, stArg) );
- a_stVal.push(pt);
- }
-#else
- // String functions accept only one parameter
- a_stVal.push( (funTok.GetType()==tpSTR) ? ApplyStrFunc(funTok, stArg) :
- ApplyNumFunc(funTok, stArg) );
-#endif // __BORLANDC__
-*/
-}
-
-//---------------------------------------------------------------------------
-void ParserBase::ApplyBinOprt( ParserStack<token_type> &a_stOpt,
- ParserStack<token_type> &a_stVal) const
-{
- assert(a_stOpt.size());
-
- // user defined binary operator
- if (a_stOpt.top().GetCode()==cmOPRT_BIN)
- {
- ApplyFunc(a_stOpt, a_stVal, 2);
- }
- else
- {
- // internal binary operator
- MUP_ASSERT(a_stVal.size()>=2);
-
- token_type valTok1 = a_stVal.pop(),
- valTok2 = a_stVal.pop(),
- optTok = a_stOpt.pop(),
- resTok;
-
- if ( valTok1.GetType()!=valTok2.GetType() ||
- (valTok1.GetType()==tpSTR && valTok2.GetType()==tpSTR) )
- Error(ecOPRT_TYPE_CONFLICT, m_pTokenReader->GetPos(), optTok.GetAsString());
-
- value_type x = valTok2.GetVal(),
- y = valTok1.GetVal();
-
- switch (optTok.GetCode())
- {
- // built in binary operators
- case cmAND: resTok.SetVal( (int)x & (int)y ); break;
- case cmOR: resTok.SetVal( (int)x | (int)y ); break;
- case cmXOR: resTok.SetVal( (int)x ^ (int)y ); break;
- case cmLT: resTok.SetVal( x < y ); break;
- case cmGT: resTok.SetVal( x > y ); break;
- case cmLE: resTok.SetVal( x <= y ); break;
- case cmGE: resTok.SetVal( x >= y ); break;
- case cmNEQ: resTok.SetVal( x != y ); break;
- case cmEQ: resTok.SetVal( x == y ); break;
- case cmADD: resTok.SetVal( x + y ); break;
- case cmSUB: resTok.SetVal( x - y ); break;
- case cmMUL: resTok.SetVal( x * y ); break;
- case cmDIV: resTok.SetVal( x / y ); break;
- case cmPOW: resTok.SetVal(pow(x, y)); break;
-
- case cmASSIGN:
- // The assignement operator needs special treatment
- // it uses a different format when stored in the bytecode!
- {
- if (valTok2.GetCode()!=cmVAR)
- Error(ecINTERNAL_ERROR, 7);
-
- value_type *pVar = valTok2.GetVar();
- resTok.SetVal( *pVar = y );
- a_stVal.push( resTok );
-
- m_vByteCode.AddAssignOp(pVar);
- return; // we must return since the following
- // stuff does not apply
- }
-
- default: Error(ecINTERNAL_ERROR, 8);
- }
-
- // Create the bytecode entries
- if (!m_bOptimize)
- {
- // Optimization flag is not set
- m_vByteCode.AddOp(optTok.GetCode());
- }
- else if ( valTok1.IsFlagSet(token_type::flVOLATILE) ||
- valTok2.IsFlagSet(token_type::flVOLATILE) )
- {
- // Optimization flag is not set, but one of the value
- // depends on a variable
- m_vByteCode.AddOp(optTok.GetCode());
- resTok.AddFlags(token_type::flVOLATILE);
- }
- else
- {
- // operator call can be optimized; If optimization is possible
- // the two previous tokens must be value tokens / they will be removed
- // and replaced with the result of the pending operation.
- m_vByteCode.RemoveValEntries(2);
- m_vByteCode.AddVal(resTok.GetVal());
- }
-
- a_stVal.push( resTok );
- }
-}
-
-//---------------------------------------------------------------------------
-/** \brief Parse the command code.
-
- Command code contains precalculated stack positions of the values and the
- associated operators.
- The Stack is filled beginning from index one the value at index zero is
- not used at all.
-
- \sa ParseString(), ParseValue()
-*/
-value_type ParserBase::ParseCmdCode() const
-{
-#if defined(_MSC_VER)
- #pragma warning( disable : 4312 )
-#endif
-
- value_type Stack[99];
- ECmdCode iCode;
- bytecode_type idx(0);
- int i(0);
-
- __start:
-
- idx = m_pCmdCode[i];
- iCode = (ECmdCode)m_pCmdCode[i+1];
- i += 2;
-
-#ifdef _DEBUG
- if (idx>=99)
- throw exception_type(ecGENERIC, _T(""), m_pTokenReader->GetFormula(), -1);
-#endif
-
- switch (iCode)
- {
- // built in binary operators
- case cmAND: Stack[idx] = (int)Stack[idx] & (int)Stack[idx+1]; goto __start;
- case cmOR: Stack[idx] = (int)Stack[idx] | (int)Stack[idx+1]; goto __start;
- case cmXOR: Stack[idx] = (int)Stack[idx] ^ (int)Stack[idx+1]; goto __start;
- case cmLE: Stack[idx] = Stack[idx] <= Stack[idx+1]; goto __start;
- case cmGE: Stack[idx] = Stack[idx] >= Stack[idx+1]; goto __start;
- case cmNEQ: Stack[idx] = Stack[idx] != Stack[idx+1]; goto __start;
- case cmEQ: Stack[idx] = Stack[idx] == Stack[idx+1]; goto __start;
- case cmLT: Stack[idx] = Stack[idx] < Stack[idx+1]; goto __start;
- case cmGT: Stack[idx] = Stack[idx] > Stack[idx+1]; goto __start;
- case cmADD: Stack[idx] += Stack[1+idx]; goto __start;
- case cmSUB: Stack[idx] -= Stack[1+idx]; goto __start;
- case cmMUL: Stack[idx] *= Stack[1+idx]; goto __start;
- case cmDIV: Stack[idx] /= Stack[1+idx]; goto __start;
- case cmPOW: Stack[idx] = pow(Stack[idx], Stack[1+idx]); goto __start;
-
- // Assignement needs special treatment
- case cmASSIGN:
- {
- // next is a pointer to the target
- value_type **pDest = (value_type**)(&m_pCmdCode[i]);
-
- // advance index according to pointer size
- i += m_vByteCode.GetPtrSize();
- // assign the value
- Stack[idx] = **pDest = Stack[idx+1];
- }
- goto __start;
-
- // user defined binary operators
- case cmOPRT_BIN:
- Stack[idx] = (**(fun_type2**)(&m_pCmdCode[i]))(Stack[idx], Stack[idx+1]);
- ++i;
- goto __start;
-
- // variable tokens
- case cmVAR:
- Stack[idx] = **(value_type**)(&m_pCmdCode[i]);
- i += m_vByteCode.GetValSize();
- goto __start;
-
- // value tokens
- case cmVAL:
- Stack[idx] = *(value_type*)(&m_pCmdCode[i]);
- i += m_vByteCode.GetValSize();
- goto __start;
-
- // Next is treatment of string functions
- case cmFUNC_STR:
- {
- // The function argument count
- int iArgCount = (int)m_pCmdCode[ i++ ];
-
- // The index of the string argument in the string table
- int iIdxStack = (int)m_pCmdCode[ i++ ];
- MUP_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() );
-
- switch(iArgCount) // switch according to argument count
- {
- case 0: Stack[idx] = (*(strfun_type1*)(&m_pCmdCode[i]))(m_vStringBuf[iIdxStack].c_str()); break;
- case 1: Stack[idx] = (*(strfun_type2*)(&m_pCmdCode[i]))(m_vStringBuf[iIdxStack].c_str(), Stack[idx]); break;
- case 2: Stack[idx] = (*(strfun_type3*)(&m_pCmdCode[i]))(m_vStringBuf[iIdxStack].c_str(), Stack[idx], Stack[idx+1]); break;
- }
- i += m_vByteCode.GetPtrSize();
- }
- goto __start;
-
- // Next is treatment of numeric functions
- case cmFUNC:
- {
- int iArgCount = (int)m_pCmdCode[i++];
-
- switch(iArgCount) // switch according to argument count
- {
- case 1: Stack[idx] = (*(fun_type1*)(&m_pCmdCode[i]))(Stack[idx]); break;
- case 2: Stack[idx] = (*(fun_type2*)(&m_pCmdCode[i]))(Stack[idx], Stack[idx+1]); break;
- case 3: Stack[idx] = (*(fun_type3*)(&m_pCmdCode[i]))(Stack[idx], Stack[idx+1], Stack[idx+2]); break;
- case 4: Stack[idx] = (*(fun_type4*)(&m_pCmdCode[i]))(Stack[idx], Stack[idx+1], Stack[idx+2], Stack[idx+3]); break;
- case 5: Stack[idx] = (*(fun_type5*)(&m_pCmdCode[i]))(Stack[idx], Stack[idx+1], Stack[idx+2], Stack[idx+3], Stack[idx+4]); break;
- default:
- if (iArgCount>0) // function with variable arguments store the number as a negative value
- Error(ecINTERNAL_ERROR, 1);
-
- Stack[idx] =(*(multfun_type*)(&m_pCmdCode[i]))(&Stack[idx], -iArgCount);
- break;
- }
- i += m_vByteCode.GetPtrSize();
- }
- goto __start;
-
- case cmEND:
- return Stack[1];
-
- default:
- Error(ecINTERNAL_ERROR, 2);
- return 0;
- }
-
-#if defined(_MSC_VER)
- #pragma warning( default : 4312 )
-#endif
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return result for constant functions.
-
- Seems pointless, but for parser functions that are made up of only a value, which occur
- in real world applications, this speeds up things by removing the parser overhead almost
- completely.
-*/
-value_type ParserBase::ParseValue() const
-{
- return *(value_type*)(&m_pCmdCode[2]);
-}
-
-//---------------------------------------------------------------------------
-/** \brief One of the two main parse functions.
-
- Parse expression from input string. Perform syntax checking and create bytecode.
- After parsing the string and creating the bytecode the function pointer
- #m_pParseFormula will be changed to the second parse routine the uses bytecode instead of string parsing.
-
- \sa ParseCmdCode(), ParseValue()
-*/
-value_type ParserBase::ParseString() const
-{
-#if defined(_MSC_VER)
- #pragma warning( disable : 4311 )
-#endif
- if (!m_pTokenReader->GetFormula().length())
- Error(ecUNEXPECTED_EOF, 0);
-
- ParserStack<token_type> stOpt, stVal;
- ParserStack<int> stArgCount;
- token_type opta, opt; // for storing operators
- token_type val, tval; // for storing value
- string_type strBuf; // buffer for string function arguments
-
- ReInit();
-
- for(;;)
- {
- opt = m_pTokenReader->ReadNextToken();
-
- switch (opt.GetCode())
- {
- //
- // Next three are different kind of value entries
- //
- case cmSTRING:
- opt.SetIdx((int)m_vStringBuf.size()); // Assign buffer index to token
- stVal.push(opt);
- m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer
- break;
-
- case cmVAR:
- stVal.push(opt);
- m_vByteCode.AddVar( static_cast<value_type*>(opt.GetVar()) );
- break;
-
- case cmVAL:
- stVal.push(opt);
- m_vByteCode.AddVal( opt.GetVal() );
- break;
-
- case cmCOMMA:
- if (stArgCount.empty())
- Error(ecUNEXPECTED_COMMA, m_pTokenReader->GetPos());
- ++stArgCount.top(); // Record number of arguments
- // fall through...
- case cmEND:
- case cmBC:
- {
- while ( stOpt.size() && stOpt.top().GetCode() != cmBO)
- {
- if (stOpt.top().GetCode()==cmOPRT_INFIX)
- ApplyFunc(stOpt, stVal, 1); // infix operator
- else
- ApplyBinOprt(stOpt, stVal);
- }
-
- // <ibg> 20060218 infix operator treatment moved here
- if (stOpt.size() && stOpt.top().GetCode()==cmOPRT_INFIX)
- ApplyFunc(stOpt, stVal, 1); // infix operator
-
- if ( opt.GetCode()!=cmBC || stOpt.size()==0 || stOpt.top().GetCode()!=cmBO )
- break;
-
- // if opt is ")" and opta is "(" the bracket has been evaluated, now its time to check
- // if there is either a function or a sign pending
- // neither the opening nor the closing bracket will be pushed back to
- // the operator stack
- // Check if a function is standing in front of the opening bracket,
- // if yes evaluate it afterwards check for infix operators
- assert(stArgCount.size());
- int iArgCount = stArgCount.pop();
-
- stOpt.pop(); // Take opening bracket from stack
-
- if (iArgCount>1 && ( stOpt.size()==0 ||
- (stOpt.top().GetCode()!=cmFUNC &&
- stOpt.top().GetCode()!=cmFUNC_STR) ) )
- Error(ecUNEXPECTED_ARG, m_pTokenReader->GetPos());
-
- if (stOpt.size() && stOpt.top().GetCode()!=cmOPRT_INFIX)
- ApplyFunc(stOpt, stVal, iArgCount);
- } // if bracket content is evaluated
- break;
-
- //
- // Next are the binary operator entries
- //
- case cmAND: // built in binary operators
- case cmOR:
- case cmXOR:
- case cmLT:
- case cmGT:
- case cmLE:
- case cmGE:
- case cmNEQ:
- case cmEQ:
- case cmADD:
- case cmSUB:
- case cmMUL:
- case cmDIV:
- case cmPOW:
- case cmASSIGN:
- case cmOPRT_BIN:
- // A binary operator (user defined or built in) has been found.
- while ( stOpt.size() && stOpt.top().GetCode() != cmBO)
- {
- if (GetOprtPri(stOpt.top()) < GetOprtPri(opt))
- break;
-
- if (stOpt.top().GetCode()==cmOPRT_INFIX)
- ApplyFunc(stOpt, stVal, 1); // infix operator
- else
- ApplyBinOprt(stOpt, stVal);
- } // while ( ... )
-
- // The operator can't be evaluated right now, push back to the operator stack
- stOpt.push(opt);
- break;
-
- //
- // Last section contains functions and operators implicitely mapped to functions
- //
- case cmBO:
- stArgCount.push( (stOpt.size() && stOpt.top().GetCode()==cmFUNC_STR) ? 0 : 1 );
- stOpt.push(opt);
- break;
-
- case cmFUNC_STR:
- case cmFUNC:
- case cmOPRT_INFIX:
- stOpt.push(opt);
- break;
-
- case cmOPRT_POSTFIX:
- stOpt.push(opt);
- ApplyFunc(stOpt, stVal, 1); // this is the postfix operator
- break;
-
- default: Error(ecINTERNAL_ERROR, 3);
- } // end of switch operator-token
-
- if ( opt.GetCode() == cmEND )
- {
- m_vByteCode.Finalize();
- break;
- }
-
-#if defined(MUP_DUMP_STACK)
- StackDump(stVal, stOpt);
- m_vByteCode.AsciiDump();
-#endif
- } // while (true)
-
- // Store pointer to start of bytecode
- m_pCmdCode = m_vByteCode.GetRawData();
-
-#if defined(MUP_DUMP_CMDCODE)
- m_vByteCode.AsciiDump();
-#endif
-
- // get the last value (= final result) from the stack
- if (stVal.size()!=1)
- Error(ecEMPTY_EXPRESSION);
-
- if (stVal.top().GetType()!=tpDBL)
- Error(ecSTR_RESULT);
-
- // no error, so change the function pointer for the main parse routine
- value_type fVal = stVal.top().GetVal(); // Result from String parsing
-
- if (m_bUseByteCode)
- {
- m_pParseFormula = (m_pCmdCode[1]==cmVAL && m_pCmdCode[6]==cmEND) ?
- &ParserBase::ParseValue :
- &ParserBase::ParseCmdCode;
- }
-
- return fVal;
-
-#if defined(_MSC_VER)
- #pragma warning( default : 4311 )
-#endif
-}
-
-
-//---------------------------------------------------------------------------
-/** \brief Create an error containing the parse error position.
-
- This function will create an Parser Exception object containing the error text and
- its position.
-
- \param a_iErrc [in] The error code of type #EErrorCodes.
- \param a_iPos [in] The position where the error was detected.
- \param a_strTok [in] The token string representation associated with the error.
- \throw ParserException always throws thats the only purpose of this function.
-*/
-void ParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const string_type &a_sTok) const
-{
- throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetFormula(), a_iPos);
-}
-
-//------------------------------------------------------------------------------
-/** \brief Clear all user defined variables.
-
- Resets the parser to string parsing mode by calling #ReInit.
- \throw nothrow
-*/
-void ParserBase::ClearVar()
-{
- m_VarDef.clear();
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Remove a variable from internal storage.
-
-Removes a variable if it exists. If the Variable does not exist nothing will be done.
-
-\throw nothrow
-*/
-void ParserBase::RemoveVar(const string_type &a_strVarName)
-{
- varmap_type::iterator item = m_VarDef.find(a_strVarName);
- if (item!=m_VarDef.end())
- {
- m_VarDef.erase(item);
- ReInit();
- }
-}
-
-//------------------------------------------------------------------------------
-/** \brief Clear the formula.
-
-Clear the formula and existing bytecode.
-
-\post Resets the parser to string parsing mode.
-\throw nothrow
-*/
-void ParserBase::ClearFormula()
-{
- m_vByteCode.clear();
- m_pCmdCode = 0;
- m_pTokenReader->SetFormula(_T(""));
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Clear all functions.
- \post Resets the parser to string parsing mode.
- \throw nothrow
-*/
-void ParserBase::ClearFun()
-{
- m_FunDef.clear();
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Clear all user defined constants.
-
- Both numeric and string constants will be removed from the internal storage.
- \post Resets the parser to string parsing mode.
- \throw nothrow
-*/
-void ParserBase::ClearConst()
-{
- m_ConstDef.clear();
- m_StrVarDef.clear();
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Clear all user defined postfix operators.
- \post Resets the parser to string parsing mode.
- \throw nothrow
-*/
-void ParserBase::ClearPostfixOprt()
-{
- m_PostOprtDef.clear();
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Clear all user defined binary operators.
- \post Resets the parser to string parsing mode.
- \throw nothrow
-*/
-void ParserBase::ClearOprt()
-{
- m_OprtDef.clear();
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Clear the user defined Prefix operators.
- \post Resets the parser to string parser mode.
- \throw nothrow
-*/
-void ParserBase::ClearInfixOprt()
-{
- m_InfixOprtDef.clear();
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Enable or disable the formula optimization feature.
- \post Resets the parser to string parser mode.
- \throw nothrow
-*/
-void ParserBase::EnableOptimizer(bool a_bIsOn)
-{
- m_bOptimize = a_bIsOn;
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Enable or disable parsing from Bytecode.
-
- \attention There is no reason to disable bytecode. It will
- drastically decrease parsing speed.
-*/
-void ParserBase::EnableByteCode(bool a_bIsOn)
-{
- m_bUseByteCode = a_bIsOn;
- if (!a_bIsOn)
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Enable or disable the built in binary operators.
- \throw nothrow
- \sa m_bBuiltInOp, ReInit()
-
- If you disable the built in binary operators there will be no binary operators
- defined. Thus you must add them manually one by one. It is not possible to
- disable built in operators selectively. This function will Reinitialize the
- parser by calling ReInit().
-*/
-void ParserBase::EnableBuiltInOprt(bool a_bIsOn)
-{
- m_bBuiltInOp = a_bIsOn;
- ReInit();
-}
-
-//------------------------------------------------------------------------------
-/** \brief Query status of built in variables.
- \return #m_bBuiltInOp; true if built in operators are enabled.
- \throw nothrow
-*/
-bool ParserBase::HasBuiltInOprt() const
-{
- return m_bBuiltInOp;
-}
-
-#if defined(MUP_DUMP_STACK) | defined(MUP_DUMP_CMDCODE)
-
-//------------------------------------------------------------------------------
-/** \brief Dump stack content.
-
- This function is used for debugging only.
-*/
-void ParserBase::StackDump( const ParserStack<token_type> &a_stVal,
- const ParserStack<token_type> &a_stOprt ) const
-{
- ParserStack<token_type> stOprt(a_stOprt),
- stVal(a_stVal);
-
- mu::console() << _T("\nValue stack:\n");
- while ( !stVal.empty() )
- {
- token_type val = stVal.pop();
- if (val.GetType()==tpSTR)
- mu::console() << _T(" \"") << val.GetAsString() << _T("\" ");
- else
- mu::console() << _T(" ") << val.GetVal() << _T(" ");
- }
- mu::console() << "\nOperator stack:\n";
-
- while ( !stOprt.empty() )
- {
- if (stOprt.top().GetCode()<=cmASSIGN)
- {
- mu::console() << _T("OPRT_INTRNL \"")
- << ParserBase::c_DefaultOprt[stOprt.top().GetCode()]
- << _T("\" \n");
- }
- else
- {
- switch(stOprt.top().GetCode())
- {
- case cmVAR: mu::console() << _T("VAR\n"); break;
- case cmVAL: mu::console() << _T("VAL\n"); break;
- case cmFUNC: mu::console() << _T("FUNC_NUM \"")
- << stOprt.top().GetAsString()
- << _T("\"\n"); break;
- case cmOPRT_INFIX: mu::console() << _T("OPRT_INFIX \"")
- << stOprt.top().GetAsString()
- << _T("\"\n"); break;
- case cmOPRT_BIN: mu::console() << _T("OPRT_BIN \"")
- << stOprt.top().GetAsString()
- << _T("\"\n"); break;
- case cmFUNC_STR: mu::console() << _T("FUNC_STR\n"); break;
- case cmEND: mu::console() << _T("END\n"); break;
- case cmUNKNOWN: mu::console() << _T("UNKNOWN\n"); break;
- case cmBO: mu::console() << _T("BRACKET \"(\"\n"); break;
- case cmBC: mu::console() << _T("BRACKET \")\"\n"); break;
- default: mu::console() << stOprt.top().GetType() << _T(" "); break;
- }
- }
- stOprt.pop();
- }
-
- mu::console() << dec << endl;
-}
-
-#endif // defined(MUP_DUMP_STACK) | defined(MUP_DUMP_CMDCODE)
-
-} // namespace mu
-
-
diff --git a/muparser/muParserBase.h b/muparser/muParserBase.h deleted file mode 100644 index c4cc433..0000000 --- a/muparser/muParserBase.h +++ /dev/null @@ -1,324 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-#ifndef MU_PARSER_BASE_H
-#define MU_PARSER_BASE_H
-
-#include <cmath>
-#include <string>
-#include <iostream>
-#include <map>
-#include <memory>
-
-#include "muParserDef.h"
-#include "muParserStack.h"
-#include "muParserTokenReader.h"
-#include "muParserBytecode.h"
-#include "muParserError.h"
-
-
-namespace mu
-{
-
-/** \brief Mathematical expressions parser (base parser engine).
-
- Version 1.27 (20061201)
-
- This is the implementation of a bytecode based mathematical expressions parser.
- The formula will be parsed from string and converted into a bytecode.
- Future calculations will be done with the bytecode instead the formula string
- resulting in a significant performance increase.
- Complementary to a set of internally implemented functions the parser is able to handle
- user defined functions and variables.
-
- \author (C) 2004-2006 Ingo Berg
-*/
-class ParserBase
-{
-friend class ParserTokenReader;
-
-private:
- typedef value_type (ParserBase::*ParseFunction)() const;
- typedef ParserToken<value_type, string_type> token_type;
- typedef std::vector<string_type> stringbuf_type;
- typedef ParserTokenReader token_reader_type;
-
- static const char_type *c_DefaultOprt[];
-
- public:
- /** \brief Type of the error class.
-
- Included for backwards compatibility.
- */
- typedef ParserError exception_type;
-
- ParserBase();
- ParserBase( const ParserBase &a_Parser );
- ParserBase& operator=(const ParserBase &a_Parser);
-
- //---------------------------------------------------------------------------
- /** \brief Destructor. (trivial)
-
- \throw nothrow
- */
- virtual ~ParserBase()
- {}
-
- //---------------------------------------------------------------------------
- /** \brief Calculate the result.
-
- A note on const correctness:
- I consider it important that Calc is a const function.
- Due to caching operations Calc changes only the state of internal variables with one exception
- m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making
- Calc non const GetUsedVar is non const because it explicitely calls Eval() forcing this update.
-
- \pre A formula must be set.
- \pre Variables must have been set (if needed)
-
- \sa #m_pParseFormula
- \return The evaluation result
- \throw ParseException if no Formula is set or in case of any other error related to the formula.
- */
- inline value_type Eval() const
- {
- return (this->*m_pParseFormula)();
- }
-
- void SetExpr(const string_type &a_sExpr);
- void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
-
- void EnableOptimizer(bool a_bIsOn=true);
- void EnableByteCode(bool a_bIsOn=true);
- void EnableBuiltInOprt(bool a_bIsOn=true);
-
- bool HasBuiltInOprt() const;
- void AddValIdent(identfun_type a_pCallback);
-
-#define MUP_DEFINE_FUNC(TYPE) \
- inline void DefineFun(const string_type &a_strName, TYPE a_pFun, bool a_bAllowOpt = true) \
- { \
- AddCallback( a_strName, ParserCallback(a_pFun, a_bAllowOpt), \
- m_FunDef, ValidNameChars() ); \
- }
-
- MUP_DEFINE_FUNC(fun_type1)
- MUP_DEFINE_FUNC(fun_type2)
- MUP_DEFINE_FUNC(fun_type3)
- MUP_DEFINE_FUNC(fun_type4)
- MUP_DEFINE_FUNC(fun_type5)
- MUP_DEFINE_FUNC(multfun_type)
- MUP_DEFINE_FUNC(strfun_type1)
- MUP_DEFINE_FUNC(strfun_type2)
- MUP_DEFINE_FUNC(strfun_type3)
-#undef MUP_DEFINE_FUNC
-
- void DefineOprt(const string_type &a_strName, fun_type2 a_pFun, unsigned a_iPri=0, bool a_bAllowOpt = false);
- void DefineConst(const string_type &a_sName, value_type a_fVal);
- void DefineStrConst(const string_type &a_sName, const string_type &a_strVal);
- void DefineVar(const string_type &a_sName, value_type *a_fVar);
- void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
- void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true);
-
- // Clear user defined variables, constants or functions
- void ClearVar();
- void ClearFun();
- void ClearConst();
- void ClearInfixOprt();
- void ClearPostfixOprt();
- void ClearOprt();
-
- void RemoveVar(const string_type &a_strVarName);
- const varmap_type& GetUsedVar() const;
- const varmap_type& GetVar() const;
- const valmap_type& GetConst() const;
- const string_type& GetExpr() const;
- const funmap_type& GetFunDef() const;
-
- //---------------------------------------------------------------------------
- /** \brief Return the strings of all Operator identifiers.
-
- GetOprt is a const function returning a pinter to an array of const char pointers.
-
- \return Returns a pointer to the c_DefaultOprt array of const char *.
- \throw nothrow
- */
- const char_type ** GetOprtDef() const
- {
- return (const char_type **)(&c_DefaultOprt[0]);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Define the set of valid characters to be used in names of
- functions, variables, constants.
- */
- void DefineNameChars(const char_type *a_szCharset)
- {
- m_sNameChars = a_szCharset;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Define the set of valid characters to be used in names of
- binary operators and postfix operators.
- */
- void DefineOprtChars(const char_type *a_szCharset)
- {
- m_sOprtChars = a_szCharset;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Define the set of valid characters to be used in names of
- infix operators.
- */
- void DefineInfixOprtChars(const char_type *a_szCharset)
- {
- m_sInfixOprtChars = a_szCharset;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Virtual function that defines the characters allowed in name identifiers.
- \sa #ValidOprtChars, #ValidPrefixOprtChars
- */
- const char_type* ValidNameChars() const
- {
- assert(m_sNameChars.size());
- return m_sNameChars.c_str();
- }
-
- //---------------------------------------------------------------------------
- /** \brief Virtual function that defines the characters allowed in operator definitions.
- \sa #ValidNameChars, #ValidPrefixOprtChars
- */
- const char_type* ValidOprtChars() const
- {
- assert(m_sOprtChars.size());
- return m_sOprtChars.c_str();
- }
-
- //---------------------------------------------------------------------------
- /** \brief Virtual function that defines the characters allowed in infix operator definitions.
- \sa #ValidNameChars, #ValidOprtChars
- */
- const char_type* ValidInfixOprtChars() const
- {
- assert(m_sInfixOprtChars.size());
- return m_sInfixOprtChars.c_str();
- }
-
- void Error( EErrorCodes a_iErrc,
- int a_iPos = (int)mu::string_type::npos,
- const string_type &a_strTok = string_type() ) const;
-
- protected:
-
- //---------------------------------------------------------------------------
- /** \brief Initialize user defined functions.
-
- Calls the virtual functions InitFun(), InitConst() and InitOprt().
- */
- void Init()
- {
- InitCharSets();
- InitFun();
- InitConst();
- InitOprt();
- }
-
- //---------------------------------------------------------------------------
- virtual void InitCharSets() = 0;
- virtual void InitFun() = 0;
- virtual void InitConst() = 0;
- virtual void InitOprt() = 0;
-
- private:
- void Assign(const ParserBase &a_Parser);
- void InitTokenReader();
- void ReInit() const;
-
- void AddCallback( const string_type &a_strName,
- const ParserCallback &a_Callback,
- funmap_type &a_Storage,
- const char_type *a_szCharSet );
-
- void ApplyBinOprt(ParserStack<token_type> &a_stOpt,
- ParserStack<token_type> &a_stVal) const;
-
- void ApplyFunc(ParserStack<token_type> &a_stOpt,
- ParserStack<token_type> &a_stVal,
- int iArgCount) const;
-
- token_type ApplyNumFunc(const token_type &a_FunTok,
- const std::vector<token_type> &a_vArg) const;
-
- token_type ApplyStrFunc(const token_type &a_FunTok,
- const std::vector<token_type> &a_vArg) const;
-
- int GetOprtPri(const token_type &a_Tok) const;
-
- value_type ParseString() const;
- value_type ParseCmdCode() const;
- value_type ParseValue() const;
-
- void ClearFormula();
- void CheckName(const string_type &a_strName, const string_type &a_CharSet) const;
-
-#if defined(MUP_DUMP_STACK) | defined(MUP_DUMP_CMDCODE)
- void StackDump(const ParserStack<token_type > &a_stVal,
- const ParserStack<token_type > &a_stOprt) const;
-#endif
-
- /** \brief Pointer to the parser function.
-
- Eval() calls the function whose address is stored there.
- */
- mutable ParseFunction m_pParseFormula;
- mutable const ParserByteCode::map_type *m_pCmdCode; ///< Formula converted to bytecode, points to the data of the bytecode class.
- mutable ParserByteCode m_vByteCode; ///< The Bytecode class.
- mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
- stringbuf_type m_vStringVarBuf;
-
- /** \brief Managed pointer to the token reader object. */
- std::auto_ptr<token_reader_type> m_pTokenReader;
-
- funmap_type m_FunDef; ///< Map of function names and pointers.
- funmap_type m_PostOprtDef; ///< Postfix operator callbacks
- funmap_type m_InfixOprtDef; ///< unary infix operator.
- funmap_type m_OprtDef; ///< Binary operator callbacks
- valmap_type m_ConstDef; ///< user constants.
- strmap_type m_StrVarDef; ///< user defined string constants
- varmap_type m_VarDef; ///< user defind variables.
-
- bool m_bOptimize; ///< Flag that indicates if the optimizer is on or off.
- bool m_bUseByteCode; ///< Flag that indicates if bytecode parsing is on or off.
- bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
-
- string_type m_sNameChars; ///< Charset for names
- string_type m_sOprtChars; ///< Charset for postfix/ binary operator tokens
- string_type m_sInfixOprtChars; ///< Charset for infix operator tokens
-};
-
-} // namespace mu
-
-#endif
-
diff --git a/muparser/muParserBytecode.cpp b/muparser/muParserBytecode.cpp deleted file mode 100644 index 7c8db24..0000000 --- a/muparser/muParserBytecode.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "muParserBytecode.h"
-
-#include <cassert>
-#include <string>
-#include <stack>
-#include <vector>
-#include <iostream>
-
-#include "muParserDef.h"
-#include "muParserError.h"
-#include "muParserToken.h"
-
-
-namespace mu
-{
-
- //---------------------------------------------------------------------------
- /** \brief Bytecode default constructor.
-
- \pre [assert] sizeof(value_type)>=sizeof(map_type)
- \pre [assert] sizeof(value_type*)>=sizeof(map_type)
- */
- ParserByteCode::ParserByteCode()
- :m_iStackPos(0)
- ,m_vBase()
- ,mc_iSizeVal( sizeof(value_type) / sizeof(map_type) )
- ,mc_iSizePtr( std::max( (int)sizeof(value_type*) /
- (int)sizeof(map_type), 1 ) )
- ,mc_iSizeValEntry( 2 + mc_iSizeVal)
- {
- m_vBase.reserve(1000);
- assert( sizeof(value_type)>=sizeof(map_type) );
- }
-
- //---------------------------------------------------------------------------
- /** \brief Destructor (trivial).*/
- ParserByteCode::~ParserByteCode()
- {}
-
- //---------------------------------------------------------------------------
- /** \brief Copy constructor.
-
- Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
- */
- ParserByteCode::ParserByteCode(const ParserByteCode &a_ByteCode)
- :mc_iSizeVal( sizeof(value_type)/sizeof(map_type) )
- ,mc_iSizePtr( sizeof(value_type*) / sizeof(map_type) )
- ,mc_iSizeValEntry( 2 + mc_iSizeVal)
- {
- Assign(a_ByteCode);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Assignment operator.
-
- Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
- */
- ParserByteCode& ParserByteCode::operator=(const ParserByteCode &a_ByteCode)
- {
- Assign(a_ByteCode);
- return *this;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Store an address in bytecode.
-
- \param a_pAddr Address to be stored.
- \throw nothrow
- */
- void ParserByteCode::StorePtr(void *a_pAddr)
- {
- #if defined(_MSC_VER)
- #pragma warning( disable : 4311 )
- #endif
-
- // demo code for packing / unpacking pointers into bytecode
-// void *ptr(NULL);
-// double **pVal;
-// double fVal;
-// map_type dbg[2];
-// dbg[0] = *( reinterpret_cast<map_type*>(&a_pAddr) ),
-// dbg[1] = *( reinterpret_cast<map_type*>(&a_pAddr) + 1 );
-// Version 1:
-// *( (map_type*)&ptr+0) = dbg[0];
-// *( (map_type*)&ptr+1) = dbg[1];
-// Version 2:
-// memcpy(&ptr, dbg, sizeof(dbg));
-// Version 3:
-// pVal = (double**)dbg;
-// fVal = **(double**)dbg;
-
- for (int i=0; i<mc_iSizePtr; ++i)
- {
- m_vBase.push_back( *( reinterpret_cast<map_type*>(&a_pAddr) + i ) );
- }
-
- #if defined(_MSC_VER)
- #pragma warning( default : 4311 )
- #endif
- }
-
- //---------------------------------------------------------------------------
- /** \brief Copy state of another object to this.
-
- \throw nowthrow
- */
- void ParserByteCode::Assign(const ParserByteCode &a_ByteCode)
- {
- if (this==&a_ByteCode)
- return;
-
- m_iStackPos = a_ByteCode.m_iStackPos;
- m_vBase = a_ByteCode.m_vBase;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Add a Variable pointer to bytecode.
- \param a_pVar Pointer to be added.
- \throw nothrow
- */
- void ParserByteCode::AddVar(value_type *a_pVar)
- {
- m_vBase.push_back( ++m_iStackPos );
- m_vBase.push_back( cmVAR );
-
- StorePtr(a_pVar);
-
- int iSize = GetValSize()-GetPtrSize();
- assert(iSize>=0);
-
- // Make sure variable entries have the same size like value entries.
- // (necessary for optimization; fill with zeros)
- for (int i=0; i<iSize; ++i)
- m_vBase.push_back(0);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Add a Variable pointer to bytecode.
-
- Value entries in byte code consist of:
- <ul>
- <li>value array position of the value</li>
- <li>the operator code according to ParserToken::cmVAL</li>
- <li>the value stored in #mc_iSizeVal number of bytecode entries.</li>
- </ul>
-
- \param a_pVal Value to be added.
- \throw nothrow
- */
- void ParserByteCode::AddVal(value_type a_fVal)
- {
- m_vBase.push_back( ++m_iStackPos );
- m_vBase.push_back( cmVAL );
-
- for (int i=0; i<mc_iSizeVal; ++i)
- m_vBase.push_back( *(reinterpret_cast<map_type*>(&a_fVal) + i) );
- }
-
- //---------------------------------------------------------------------------
- /** \brief Add an operator identifier to bytecode.
-
- Operator entries in byte code consist of:
- <ul>
- <li>value array position of the result</li>
- <li>the operator code according to ParserToken::ECmdCode</li>
- </ul>
-
- \sa ParserToken::ECmdCode
- */
- void ParserByteCode::AddOp(ECmdCode a_Oprt)
- {
- m_vBase.push_back(--m_iStackPos);
- m_vBase.push_back(a_Oprt);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Add an assignement operator
-
- Operator entries in byte code consist of:
- <ul>
- <li>cmASSIGN code</li>
- <li>the pointer of the destination variable</li>
- </ul>
-
- \sa ParserToken::ECmdCode
- */
- void ParserByteCode::AddAssignOp(value_type *a_pVar)
- {
- m_vBase.push_back(--m_iStackPos);
- m_vBase.push_back(cmASSIGN);
- StorePtr(a_pVar);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Add function to bytecode.
-
- \param a_iArgc Number of arguments, negative numbers indicate multiarg functions.
- \param a_pFun Pointer to function callback.
- */
- void ParserByteCode::AddFun(void *a_pFun, int a_iArgc)
- {
- if (a_iArgc>=0)
- {
- m_iStackPos = m_iStackPos - a_iArgc + 1;
- }
- else
- {
- m_iStackPos = m_iStackPos + a_iArgc + 1;
- }
-
- m_vBase.push_back(m_iStackPos);
- m_vBase.push_back(cmFUNC);
- m_vBase.push_back(a_iArgc);
-
- StorePtr(a_pFun);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Add Strung function entry to the parser bytecode.
- \throw nothrow
-
- A string function entry consists of the stack position of the return value,
- followed by a cmSTRFUNC code, the function pointer and an index into the
- string buffer maintained by the parser.
- */
- void ParserByteCode::AddStrFun(void *a_pFun, int a_iArgc, int a_iIdx)
- {
- m_iStackPos = m_iStackPos - a_iArgc + 1;
- m_vBase.push_back(m_iStackPos);
- m_vBase.push_back(cmFUNC_STR);
- m_vBase.push_back(a_iArgc);
- m_vBase.push_back(a_iIdx);
-
- StorePtr(a_pFun);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Add end marker to bytecode.
-
- \throw nothrow
- */
- void ParserByteCode::Finalize()
- {
- // yes we need the end code three times!! (I forgot why)
- m_vBase.push_back(cmEND);
- m_vBase.push_back(cmEND);
- m_vBase.push_back(cmEND);
-
- // shrink bytecode vector to fit
- storage_type(m_vBase).swap(m_vBase);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Get Pointer to bytecode data storage. */
- const ParserByteCode::map_type* ParserByteCode::GetRawData() const
- {
- assert(m_vBase.size());
- return &m_vBase[0];
- }
-
- //---------------------------------------------------------------------------
- /** \brief Delete the bytecode.
-
- \throw nothrow
-
- The name of this function is a violation of my own coding guidelines
- but this way it's more in line with the STL functions thus more
- intuitive.
- */
- void ParserByteCode::clear()
- {
- m_vBase.clear();
- m_iStackPos = 0;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Remove a value number of entries from the bytecode.
-
- \attention Currently I don't test if the entries are really value entries.
- */
- void ParserByteCode::RemoveValEntries(unsigned a_iNumber)
- {
- unsigned iSize = a_iNumber * mc_iSizeValEntry;
- assert( m_vBase.size() >= iSize );
- m_vBase.resize(m_vBase.size()-iSize);
-
- assert(m_iStackPos >= a_iNumber);
- m_iStackPos -= (a_iNumber);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Dump bytecode (for debugging only!). */
- void ParserByteCode::AsciiDump()
- {
- if (!m_vBase.size())
- {
- std::cout << "No bytecode available\n";
- return;
- }
-
- std::cout << "Entries:" << (int)m_vBase.size()
- << " (ValSize:" << mc_iSizeVal
- << " entries, PtrSize:" << mc_iSizePtr
- << " entries, MapSize:" << sizeof(map_type)
- << " byte)\n";
- int i = 0;
-
- while ( m_vBase[i] != cmEND && i<(int)m_vBase.size())
- {
- std::cout << "IDX[" << m_vBase[i++] << "]\t";
- switch (m_vBase[i])
- {
- case cmVAL: std::cout << "VAL "; ++i;
- std::cout << "[" << *( reinterpret_cast<double*>(&m_vBase[i]) ) << "]\n";
- i += mc_iSizeVal;
- break;
-
- case cmVAR: std::cout << "VAR "; ++i;
- std::cout << "[ADDR: 0x" << std::hex << *(value_type**)&m_vBase[i] << "]\n";
- i += mc_iSizePtr;
-
- // Variable entries have the same size like value entries
- // the remaining spave must be skipped
- i+= std::max(mc_iSizeVal - mc_iSizePtr, 0);
- break;
-
- case cmFUNC:
- std::cout << "CALL\t"; ++i;
- std::cout << "[ARG:" << std::dec << m_vBase[i] << "]"; ++i;
- std::cout << "[ADDR: 0x" << std::hex << *(value_type**)&m_vBase[i] << "]\n";
- i += mc_iSizePtr;
- break;
-
- case cmFUNC_STR:
- std::cout << "CALL STRFUNC\t"; ++i;
- std::cout << "[ARG:" << std::dec << m_vBase[i] << "]"; ++i;
- std::cout << "[IDX:" << std::dec << m_vBase[i] << "]"; ++i;
- std::cout << "[ADDR: 0x" << *(value_type**)&m_vBase[i] << "]\n";
- i += mc_iSizePtr;
- break;
-
- case cmLT: std::cout << "LT\n"; ++i; break;
- case cmGT: std::cout << "GT\n"; ++i; break;
- case cmLE: std::cout << "LE\n"; ++i; break;
- case cmGE: std::cout << "GE\n"; ++i; break;
- case cmEQ: std::cout << "EQ\n"; ++i; break;
- case cmNEQ: std::cout << "NEQ\n"; ++i; break;
- case cmADD: std::cout << "ADD\n"; ++i; break;
- case cmAND: std::cout << "AND\n"; ++i; break;
- case cmOR: std::cout << "OR\n"; ++i; break;
- case cmXOR: std::cout << "XOR\n"; ++i; break;
- case cmSUB: std::cout << "SUB\n"; ++i; break;
- case cmMUL: std::cout << "MUL\n"; ++i; break;
- case cmDIV: std::cout << "DIV\n"; ++i; break;
- case cmPOW: std::cout << "POW\n"; ++i; break;
-
- case cmASSIGN:
- std::cout << "ASSIGN\t"; ++i;
- std::cout << "[ADDR: 0x" << *(value_type**)&m_vBase[i] << "]\n";
- i += mc_iSizePtr;
- break;
-
- default: std::cout << "(unknown code: " << m_vBase[i] << ")\n";
- ++i;
- break;
- } // switch cmdCode
- } // while bytecode
-
- std::cout << "END" << std::endl;
- }
-} // namespace mu
diff --git a/muparser/muParserBytecode.h b/muparser/muParserBytecode.h deleted file mode 100644 index d425990..0000000 --- a/muparser/muParserBytecode.h +++ /dev/null @@ -1,148 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-#ifndef MU_PARSER_BYTECODE_H
-#define MU_PARSER_BYTECODE_H
-
-#include <cassert>
-#include <string>
-#include <stack>
-#include <vector>
-
-#include "muParserDef.h"
-#include "muParserError.h"
-#include "muParserToken.h"
-
-
-namespace mu
-{
-
-
-/** \brief Bytecode implementation of the Math Parser.
-
- The bytecode contains the formula converted to revers polish notation stored in a continious
- memory area. Associated with this data are operator codes, variable pointers, constant
- values and function pointers. Those are necessary in order to calculate the result.
- All those data items will be casted to the underlying datatype of the bytecode.
-
- \author (C) 2004, 2005 Ingo Berg
-*/
-class ParserByteCode
-{
-public:
- /** \brief Underlying type of the container.
-
- The bytecode is a vector of this type containing control codes,
- values and pointers. Values and pointer will be casted to this
- type before their storage.
- */
- typedef bytecode_type map_type;
-
-private:
-
- /** \brief Token type for internal use only. */
- typedef ParserToken<value_type, string_type> token_type;
-
- /** \brief Core type of the bytecode. */
- typedef std::vector<map_type> storage_type;
-
- /** \brief Position in the Calculation array. */
- unsigned m_iStackPos;
-
- /** \brief Core type of the bytecode. */
- storage_type m_vBase;
-
- /** \brief Size of a value entry in the bytecode, relative to TMapType size. */
- const int mc_iSizeVal;
-
- /** \brief Size of a pointer, relative to size of underlying TMapType.
-
- \attention The size is related to the size of TMapType not bytes!
- */
- const int mc_iSizePtr;
-
- /** \brief A value entry requires that much entires in the bytecode.
-
- Value entry consists of:
- <ul>
- <li>One entry for Stack index</li>
- <li>One entry for Token identifier</li>
- <li>mc_iSizeVal entries for the value</li>
- <ul>
-
- \sa AddVal(TBaseData a_fVal)
- */
- const int mc_iSizeValEntry;
-
- void StorePtr(void *a_pAddr);
-
-public:
- ParserByteCode();
- ~ParserByteCode();
- ParserByteCode(const ParserByteCode &a_ByteCode);
- ParserByteCode& operator=(const ParserByteCode &a_ByteCode);
- void Assign(const ParserByteCode &a_ByteCode);
-
- void AddVar(value_type *a_pVar);
- void AddVal(value_type a_fVal);
- void AddOp(ECmdCode a_Oprt);
- void AddAssignOp(value_type *a_pVar);
- void AddFun(void *a_pFun, int a_iArgc);
- void AddStrFun(void *a_pFun, int a_iArgc, int a_iIdx);
-
- void Finalize();
- void clear();
- const map_type* GetRawData() const;
-
- /** \brief Return size of a value entry.
-
- That many bytecode entries are necessary to store a value.
-
- \sa mc_iSizeVal
- */
- unsigned GetValSize() const
- {
- return mc_iSizeVal;
- }
-
- /** \brief Return size of a pointer entry.
-
- That many bytecode entries are necessary to store a pointer.
-
- \sa mc_iSizePtr
- */
- unsigned GetPtrSize() const
- {
- return mc_iSizePtr;
- }
-
- void RemoveValEntries(unsigned a_iNumber);
- void AsciiDump();
-};
-
-} // namespace mu
-
-#endif
-
-
diff --git a/muparser/muParserCallback.cpp b/muparser/muParserCallback.cpp deleted file mode 100644 index 1312ad7..0000000 --- a/muparser/muParserCallback.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "muParserCallback.h"
-
-
-namespace mu
-{
-
- ParserCallback::ParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode)
- :m_pFun((void*)a_pFun)
- ,m_iArgc(1)
- ,m_iPri(a_iPrec)
- ,m_iCode(a_iCode)
- ,m_iType(tpDBL)
- ,m_bAllowOpti(a_bAllowOpti)
- {}
-
-
- ParserCallback::ParserCallback( fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode)
- :m_pFun((void*)a_pFun)
- ,m_iArgc(2)
- ,m_iPri(a_iPrec)
- ,m_iCode(a_iCode)
- ,m_iType(tpDBL)
- ,m_bAllowOpti(a_bAllowOpti)
- {}
-
-
- ParserCallback::ParserCallback(fun_type3 a_pFun, bool a_bAllowOpti)
- :m_pFun((void*)a_pFun)
- ,m_iArgc(3)
- ,m_iPri(-1)
- ,m_iCode(cmFUNC)
- ,m_iType(tpDBL)
- ,m_bAllowOpti(a_bAllowOpti)
- {}
-
-
- ParserCallback::ParserCallback(fun_type4 a_pFun, bool a_bAllowOpti)
- :m_pFun((void*)a_pFun)
- ,m_iArgc(4)
- ,m_iPri(-1)
- ,m_iCode(cmFUNC)
- ,m_iType(tpDBL)
- ,m_bAllowOpti(a_bAllowOpti)
- {}
-
- ParserCallback::ParserCallback(fun_type5 a_pFun, bool a_bAllowOpti)
- :m_pFun((void*)a_pFun)
- ,m_iArgc(5)
- ,m_iPri(-1)
- ,m_iCode(cmFUNC)
- ,m_iType(tpDBL)
- ,m_bAllowOpti(a_bAllowOpti)
- {}
-
- ParserCallback::ParserCallback(multfun_type a_pFun, bool a_bAllowOpti)
- :m_pFun((void*)a_pFun)
- ,m_iArgc(-1)
- ,m_iPri(-1)
- ,m_iCode(cmFUNC)
- ,m_iType(tpDBL)
- ,m_bAllowOpti(a_bAllowOpti)
- {}
-
- ParserCallback::ParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti)
- :m_pFun((void*)a_pFun)
- ,m_iArgc(0)
- ,m_iPri(-1)
- ,m_iCode(cmFUNC_STR)
- ,m_iType(tpSTR)
- ,m_bAllowOpti(a_bAllowOpti)
- {}
-
- ParserCallback::ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti)
- :m_pFun((void*)a_pFun)
- ,m_iArgc(1)
- ,m_iPri(-1)
- ,m_iCode(cmFUNC_STR)
- ,m_iType(tpSTR)
- ,m_bAllowOpti(a_bAllowOpti)
- {}
-
- ParserCallback::ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti)
- :m_pFun((void*)a_pFun)
- ,m_iArgc(2)
- ,m_iPri(-1)
- ,m_iCode(cmFUNC_STR)
- ,m_iType(tpSTR)
- ,m_bAllowOpti(a_bAllowOpti)
- {}
-
- /** \brief Default constructor.
-
- \throw nothrow
- */
- ParserCallback::ParserCallback()
- :m_pFun(0)
- ,m_iArgc(0)
- ,m_iCode(cmUNKNOWN)
- ,m_iType(tpVOID)
- ,m_bAllowOpti(0)
- {}
-
- /** \brief Copy constructor.
-
- \throw nothrow
- */
- ParserCallback::ParserCallback(const ParserCallback &a_Fun)
- {
- m_pFun = a_Fun.m_pFun;
- m_iArgc = a_Fun.m_iArgc;
- m_bAllowOpti = a_Fun.m_bAllowOpti;
- m_iCode = a_Fun.m_iCode;
- m_iType = a_Fun.m_iType;
- m_iPri = a_Fun.m_iPri;
- }
-
- /** \brief Clone this instance and return a pointer to the new instance. */
- ParserCallback* ParserCallback::Clone() const
- {
- return new ParserCallback(*this);
- }
-
-
- /** \brief Return tru if the function is conservative.
-
- Conservative functions return always the same result for the same argument.
- \throw nothrow
- */
- bool ParserCallback::IsOptimizable() const
- {
- return m_bAllowOpti;
- }
-
- /** \brief Get the callback address for the parser function.
-
- The type of the address is void. It needs to be recasted according to the
- argument number to the right type.
-
- \throw nothrow
- \return #pFun
- */
- void* ParserCallback::GetAddr() const
- {
- return m_pFun;
- }
-
- /** \brief Return the callback code. */
- ECmdCode ParserCallback::GetCode() const
- {
- return m_iCode;
- }
-
-
- ETypeCode ParserCallback::GetType() const
- {
- return m_iType;
- }
-
- /** \brief Return the operator priority.
-
- Only valid if the callback token is an operator token (binary or infix).
- */
- int ParserCallback::GetPri() const
- {
- return m_iPri;
- }
-
- /** \brief Returns the number of function Arguments. */
- int ParserCallback::GetArgc() const
- {
- return m_iArgc;
- }
-} // namespace mu
diff --git a/muparser/muParserCallback.h b/muparser/muParserCallback.h deleted file mode 100644 index 9fecddb..0000000 --- a/muparser/muParserCallback.h +++ /dev/null @@ -1,94 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef MU_PARSER_CALLBACK_H
-#define MU_PARSER_CALLBACK_H
-
-#include "muParserDef.h"
-
-
-namespace mu
-{
-
-/** \brief Encapsulation of prototypes for a numerical parser function.
-
- Encapsulates the prototyp for numerical parser functions. The class
- stores the number of arguments for parser functions as well
- as additional flags indication the function is non optimizeable.
- The pointer to the callback function pointer is stored as void*
- and needs to be casted according to the argument count.
- Negative argument counts indicate a parser function with a variable number
- of arguments.
- This class is not used for string function prototyping.
-
- \author (C) 2004-2006 Ingo Berg
-*/
-class ParserCallback
-{
-public:
- ParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC);
- ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC);
- ParserCallback(fun_type3 a_pFun, bool a_bAllowOpti);
- ParserCallback(fun_type4 a_pFun, bool a_bAllowOpti);
- ParserCallback(fun_type5 a_pFun, bool a_bAllowOpti);
- ParserCallback(multfun_type a_pFun, bool a_bAllowOpti);
- ParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti);
- ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti);
- ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti);
- ParserCallback();
- ParserCallback(const ParserCallback &a_Fun);
-
- ParserCallback* Clone() const;
-
- bool IsOptimizable() const;
- void* GetAddr() const;
- ECmdCode GetCode() const;
- ETypeCode GetType() const;
- int GetPri() const;
- int GetArgc() const;
-
-private:
- void *m_pFun; ///< Pointer to the callback function, casted to void
-
- /** \brief Number of numeric function arguments
-
- This number is negative for functions with variable number of arguments. in this cases
- they represent the actual number of arguments found.
- */
- int m_iArgc;
- int m_iPri; ///< Valid only for binary and infix operators; Operator precedence.
- ECmdCode m_iCode;
- ETypeCode m_iType;
- bool m_bAllowOpti; ///< Flag indication optimizeability
-};
-
-//------------------------------------------------------------------------------
-/** \brief Container for Callback objects. */
-typedef std::map<string_type, ParserCallback> funmap_type;
-
-} // namespace mu
-
-#endif
-
diff --git a/muparser/muParserDLL.cpp b/muparser/muParserDLL.cpp deleted file mode 100644 index 0f85cb7..0000000 --- a/muparser/muParserDLL.cpp +++ /dev/null @@ -1,657 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-
-#if defined(MUPARSER_DLL) && defined(_WIN32)
-
-#include "muParserDLL.h"
-#include "muParser.h"
-#include "muParserError.h"
-
-
-#define MU_PARSER_TRY \
- try \
- {
-
-#define MU_PARSER_CATCH \
- } \
- catch(exception_type &e) \
- { \
- g_bError = true; \
- g_ParserError = e; \
- if (g_pErrHandler) \
- g_pErrHandler(); \
- } \
- catch(...) \
- { \
- g_bError = true; \
- g_ParserError = exception_type(mu::ecINTERNAL_ERROR); \
- if (g_pErrHandler) \
- g_pErrHandler(); \
- }
-
-//---------------------------------------------------------------------------
-typedef mu::ParserBase::exception_type exception_type;
-typedef mu::ParserBase* parser_type;
-
-#if !defined(_UNICODE)
- typedef std::string string_type;
-#else
- typedef std::wstring string_type;
-#endif
-
-typedef string_type::value_type char_type;
-
-//---------------------------------------------------------------------------
-//
-//
-// unexported variables
-//
-//
-//---------------------------------------------------------------------------
-
-/** \brief The last exception that was caught.
-*/
-exception_type g_ParserError;
-errhandler_type g_pErrHandler;
-
-//---------------------------------------------------------------------------
-/** \brief Flags indicating an error occured.
-*/
-bool g_bError;
-
-//---------------------------------------------------------------------------
-//
-//
-// unexported functions
-//
-//
-//---------------------------------------------------------------------------
-
-parser_type GetPtr(parser_handle a_hParser)
-{
- return static_cast<parser_type>(a_hParser);
-}
-
-//---------------------------------------------------------------------------
-/** \brief DLL entry point.
-*/
-BOOL APIENTRY DllMain( HANDLE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/ )
-{
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- case DLL_THREAD_ATTACH:
- g_pErrHandler = 0;
- g_bError = false;
- break;
-
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
-
- return TRUE;
-}
-
-//---------------------------------------------------------------------------
-//
-//
-// exported functions
-//
-//
-//---------------------------------------------------------------------------
-
-MU_PARSER_API void mupSetErrorHandler(errhandler_type a_pHandler)
-{
- g_pErrHandler = a_pHandler;
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupSetVarFactory(parser_handle a_hParser, facfun_type a_pFactory, void *pUserData)
-{
- parser_type p(GetPtr(a_hParser));
- p->SetVarFactory(a_pFactory, pUserData);
-}
-
-//---------------------------------------------------------------------------
-/** \brief Create a new Parser instance and return its handle.
-*/
-MU_PARSER_API parser_handle mupInit()
-{
- return (void*)(new mu::Parser());
-}
-
-//---------------------------------------------------------------------------
-/** \brief Release the parser instance related with a parser handle.
-*/
-MU_PARSER_API void mupRelease(parser_handle a_hParser)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- delete p;
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-/** \brief Evaluate the expression.
-*/
-MU_PARSER_API double mupEval(parser_handle a_hParser)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- return p->Eval();
- MU_PARSER_CATCH
-
- return 0;
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupSetExpr(parser_handle a_hParser, const char *a_szExpr)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->SetExpr(a_szExpr);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupRemoveVar(parser_handle a_hParser, const char *a_szName)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->RemoveVar( string_type(a_szName) );
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-/** \brief Release all parser variables.
- \param a_hParser Handle to the parser instance.
-*/
-MU_PARSER_API void mupClearVar(parser_handle a_hParser)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->ClearVar();
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-/** \brief Release all parser variables.
- \param a_hParser Handle to the parser instance.
-*/
-MU_PARSER_API void mupClearConst(parser_handle a_hParser)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->ClearConst();
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-/** \brief Clear all user defined operators.
- \param a_hParser Handle to the parser instance.
-*/
-MU_PARSER_API void mupClearOprt(parser_handle a_hParser)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->ClearOprt();
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineFun1(parser_handle a_hParser, const char *a_szName, fun_type1 a_pFun, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineFun2(parser_handle a_hParser, const char *a_szName, fun_type2 a_pFun, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineFun3(parser_handle a_hParser, const char *a_szName, fun_type3 a_pFun, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineFun4(parser_handle a_hParser, const char *a_szName, fun_type4 a_pFun, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineFun5(parser_handle a_hParser, const char *a_szName, fun_type5 a_pFun, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineStrFun1(parser_handle a_hParser, const char *a_szName, strfun_type1 a_pFun, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineStrFun2(parser_handle a_hParser, const char *a_szName, strfun_type2 a_pFun, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineStrFun3(parser_handle a_hParser, const char *a_szName, strfun_type3 a_pFun, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineMultFun(parser_handle a_hParser, const char *a_szName, multfun_type a_pFun, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineOprt(parser_handle a_hParser, const char *a_szName, fun_type2 a_pFun, int a_iPri, bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineOprt(a_szName, a_pFun, a_iPri, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineVar(parser_handle a_hParser, const char *a_szName, double *a_pVar)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineVar(a_szName, a_pVar);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineConst(parser_handle a_hParser, const char *a_szName, double a_fVal)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineConst(a_szName, a_fVal);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineStrConst(parser_handle a_hParser, const char *a_szName, const char *a_szVal)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineStrConst(a_szName, a_szVal);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API const char* mupGetExpr(parser_handle a_hParser)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- return p->GetExpr().c_str();
- MU_PARSER_CATCH
-
- return "";
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefinePostfixOprt(parser_handle a_hParser,
- const char *a_szName,
- fun_type1 a_pOprt,
- bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefinePostfixOprt(a_szName, a_pOprt, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineInfixOprt(parser_handle a_hParser,
- const char *a_szName,
- fun_type1 a_pOprt,
- bool a_bAllowOpt)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->DefineInfixOprt(a_szName, a_pOprt, a_bAllowOpt);
- MU_PARSER_CATCH
-}
-
-// Define character sets for identifiers
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineNameChars(parser_handle a_hParser, const char *a_szCharset)
-{
- parser_type p(GetPtr(a_hParser));
- p->DefineNameChars(a_szCharset);
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineOprtChars(parser_handle a_hParser, const char *a_szCharset)
-{
- parser_type p(GetPtr(a_hParser));
- p->DefineOprtChars(a_szCharset);
-}
-
-//---------------------------------------------------------------------------
-MU_PARSER_API void mupDefineInfixOprtChars(parser_handle a_hParser, const char *a_szCharset)
-{
- parser_type p(GetPtr(a_hParser));
- p->DefineInfixOprtChars(a_szCharset);
-}
-
-//---------------------------------------------------------------------------
-/** \brief Get the number of variables defined in the parser.
- \param a_hParser [in] Must be a valid parser handle.
- \return The number of used variables.
- \sa mupGetExprVar
-*/
-MU_PARSER_API int mupGetVarNum(parser_handle a_hParser)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- const mu::varmap_type VarMap = p->GetVar();
- return (int)VarMap.size();
- MU_PARSER_CATCH
-
- return 0; // never reached
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return a variable that is used in an expression.
-
- Prior to calling this function call mupGetExprVarNum in order to get the
- number of variables in the expression. If the parameter a_iVar is greater
- than the number of variables both a_szName and a_pVar will be set to zero.
- As a side effect this function will trigger an internal calculation of the
- expression undefined variables will be set to zero during this calculation.
- During the calculation user defined callback functions present in the expression
- will be called, this is unavoidable.
-
- \param a_hParser [in] A valid parser handle.
- \param a_iVar [in] The index of the variable to return.
- \param a_szName [out] Pointer to the variable name.
- \param a_pVar [out] Pointer to the variable.
- \throw nothrow
-*/
-MU_PARSER_API void mupGetVar(parser_handle a_hParser, unsigned a_iVar, const char **a_szName, double **a_pVar)
-{
- // A static buffer is needed for the name since i cant return the
- // pointer from the map.
- static char szName[1024];
-
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- const mu::varmap_type VarMap = p->GetVar();
-
- if (a_iVar>=VarMap.size())
- {
- *a_szName = 0;
- *a_pVar = 0;
- return;
- }
- mu::varmap_type::const_iterator item;
-
- item = VarMap.begin();
- for (unsigned i=0; i<a_iVar; ++i)
- item++;
-
- strncpy(szName, item->first.c_str(), sizeof(szName));
- szName[sizeof(szName)-1] = 0;
-
- *a_szName = &szName[0];
- *a_pVar = item->second;
- return;
-
- MU_PARSER_CATCH
-
- *a_szName = 0;
- *a_pVar = 0;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Get the number of variables used in the expression currently set in the parser.
- \param a_hParser [in] Must be a valid parser handle.
- \return The number of used variables.
- \sa mupGetExprVar
-*/
-MU_PARSER_API int mupGetExprVarNum(parser_handle a_hParser)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- const mu::varmap_type VarMap = p->GetUsedVar();
- return (int)VarMap.size();
- MU_PARSER_CATCH
-
- return 0; // never reached
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return a variable that is used in an expression.
-
- Prior to calling this function call mupGetExprVarNum in order to get the
- number of variables in the expression. If the parameter a_iVar is greater
- than the number of variables both a_szName and a_pVar will be set to zero.
- As a side effect this function will trigger an internal calculation of the
- expression undefined variables will be set to zero during this calculation.
- During the calculation user defined callback functions present in the expression
- will be called, this is unavoidable.
-
- \param a_hParser [in] A valid parser handle.
- \param a_iVar [in] The index of the variable to return.
- \param a_szName [out] Pointer to the variable name.
- \param a_pVar [out] Pointer to the variable.
- \throw nothrow
-*/
-MU_PARSER_API void mupGetExprVar(parser_handle a_hParser, unsigned a_iVar, const char **a_szName, double **a_pVar)
-{
- // A static buffer is needed for the name since i cant return the
- // pointer from the map.
- static char szName[1024];
-
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- const mu::varmap_type VarMap = p->GetUsedVar();
-
- if (a_iVar>=VarMap.size())
- {
- *a_szName = 0;
- *a_pVar = 0;
- return;
- }
- mu::varmap_type::const_iterator item;
-
- item = VarMap.begin();
- for (unsigned i=0; i<a_iVar; ++i)
- item++;
-
- strncpy(szName, item->first.c_str(), sizeof(szName));
- szName[sizeof(szName)-1] = 0;
-
- *a_szName = &szName[0];
- *a_pVar = item->second;
- return;
-
- MU_PARSER_CATCH
-
- *a_szName = 0;
- *a_pVar = 0;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return the number of constants defined in a parser. */
-MU_PARSER_API int mupGetConstNum(parser_handle a_hParser)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- const mu::valmap_type ValMap = p->GetConst();
- return (int)ValMap.size();
- MU_PARSER_CATCH
-
- return 0; // never reached
-}
-
-//---------------------------------------------------------------------------
-/** \brief Retrieve name and value of a single parser constant.
- \param a_hParser [in] a valid parser handle
- \param a_iVar [in] Index of the constant to query
- \param a_pszName [out] pointer to a null terminated string with the constant name
- \param [out] The constant value
-*/
-MU_PARSER_API void mupGetConst(parser_handle a_hParser, unsigned a_iVar,
- const char **a_pszName, double &a_fVal)
-{
- // A static buffer is needed for the name since i cant return the
- // pointer from the map.
- static char szName[1024];
-
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- const mu::valmap_type ValMap = p->GetConst();
-
- if (a_iVar>=ValMap.size())
- {
- *a_pszName = 0;
- a_fVal = 0;
- return;
- }
-
- mu::valmap_type::const_iterator item;
- item = ValMap.begin();
- for (unsigned i=0; i<a_iVar; ++i)
- item++;
-
- strncpy(szName, item->first.c_str(), sizeof(szName));
- szName[sizeof(szName)-1] = 0;
-
- *a_pszName = &szName[0];
- a_fVal = item->second;
- return;
-
- MU_PARSER_CATCH
-
- *a_pszName = 0;
- a_fVal = 0;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Add a custom value regognition function.
-*/
-MU_PARSER_API void mupAddValIdent(parser_handle a_hParser, identfun_type a_pFun)
-{
- MU_PARSER_TRY
- parser_type p(GetPtr(a_hParser));
- p->AddValIdent(a_pFun);
- MU_PARSER_CATCH
-}
-
-//---------------------------------------------------------------------------
-/** \brief Query if an error occured.
-
- After querying the internal error bit will be reset. So a consecutive call
- will return false.
-*/
-MU_PARSER_API bool mupError()
-{
- bool bError(g_bError);
- g_bError = false;
- return bError;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Reset the internal error flag.
-*/
-MU_PARSER_API void mupErrorReset()
-{
- g_bError = false;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return the message associated with the last error.
-*/
-MU_PARSER_API const char* mupGetErrorMsg()
-{
- return g_ParserError.GetMsg().c_str();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return the message associated with the last error.
-*/
-MU_PARSER_API const char* mupGetErrorToken()
-{
- return g_ParserError.GetToken().c_str();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return the code associated with the last error.
-*/
-MU_PARSER_API int mupGetErrorCode()
-{
- return g_ParserError.GetCode();
-}
-
-//---------------------------------------------------------------------------
-/** \brief Return the postion associated with the last error. */
-MU_PARSER_API int mupGetErrorPos()
-{
- return (int)g_ParserError.GetPos();
-}
-
-
-#endif // MUPARSER_DLL
diff --git a/muparser/muParserDLL.h b/muparser/muParserDLL.h deleted file mode 100644 index 20e2db8..0000000 --- a/muparser/muParserDLL.h +++ /dev/null @@ -1,123 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-// Folgender ifdef-Block ist die Standardmethode zum Erstellen von Makros, die das Exportieren
-// aus einer DLL vereinfachen. Alle Dateien in der DLL werden mit dem MUPARSERLIB_EXPORTS-Symbol
-// kompiliert, das in der Befehlszeile definiert wurde. Das Symbol darf nicht für ein Projekt definiert werden,
-// das diese DLL verwendet. Alle anderen Projekte, deren Quelldateien diese Datei beinhalten, erkennen
-// MUPARSERLIB_API-Funktionen als aus einer DLL importiert, während die DLL mit diesem Makro
-// definierte Symbole als exportiert ansieht.
-#ifndef MU_PARSER_DLL_H
-#define MU_PARSER_DLL_H
-
-#ifdef MUPARSERLIB_EXPORTS
-#define MU_PARSER_API __declspec(dllexport)
-#else
-#define MU_PARSER_API __declspec(dllimport)
-#endif
-
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-typedef void* parser_handle;
-typedef double (*fun_type1)(double);
-typedef double (*fun_type2)(double, double);
-typedef double (*fun_type3)(double, double, double);
-typedef double (*fun_type4)(double, double, double, double);
-typedef double (*fun_type5)(double, double, double, double, double);
-typedef double (*multfun_type)(const double*, int);
-typedef double (*strfun_type1)(const char*);
-typedef double (*strfun_type2)(const char*, double);
-typedef double (*strfun_type3)(const char*, double, double);
-typedef void (*errhandler_type)();
-typedef double* (*facfun_type)(const char*, void *);
-typedef bool (*identfun_type)(const char*, int&, double&);
-
-extern "C"
-{
-
-// Basic operations / initialization
-MU_PARSER_API parser_handle mupInit();
-MU_PARSER_API void mupRelease(parser_handle a_hParser);
-MU_PARSER_API const char* mupGetExpr(parser_handle a_hParser);
-MU_PARSER_API void mupSetExpr(parser_handle a_hParser, const char *a_szExpr);
-MU_PARSER_API void mupSetErrorHandler(errhandler_type a_pErrHandler);
-MU_PARSER_API void mupSetVarFactory(parser_handle a_hParser, facfun_type a_pFactory, void *pUserData);
-
-MU_PARSER_API double mupEval(parser_handle a_hParser);
-
-// Defining callbacks / variables / constants
-MU_PARSER_API void mupDefineFun1(parser_handle a_hParser, const char *a_szName, fun_type1 a_pFun, bool a_bAllowOpt = true);
-MU_PARSER_API void mupDefineFun2(parser_handle a_hParser, const char *a_szName, fun_type2 a_pFun, bool a_bAllowOpt = true);
-MU_PARSER_API void mupDefineFun3(parser_handle a_hParser, const char *a_szName, fun_type3 a_pFun, bool a_bAllowOpt = true);
-MU_PARSER_API void mupDefineFun4(parser_handle a_hParser, const char *a_szName, fun_type4 a_pFun, bool a_bAllowOpt = true);
-MU_PARSER_API void mupDefineFun5(parser_handle a_hParser, const char *a_szName, fun_type5 a_pFun, bool a_bAllowOpt = true);
-// string functions
-MU_PARSER_API void mupDefineStrFun1(parser_handle a_hParser, const char *a_szName, strfun_type1 a_pFun, bool a_bAllowOpt = true);
-MU_PARSER_API void mupDefineStrFun2(parser_handle a_hParser, const char *a_szName, strfun_type2 a_pFun, bool a_bAllowOpt = true);
-MU_PARSER_API void mupDefineStrFun3(parser_handle a_hParser, const char *a_szName, strfun_type3 a_pFun, bool a_bAllowOpt = true);
-
-MU_PARSER_API void mupDefineMultFun(parser_handle a_hParser, const char *a_szName, multfun_type a_pFun, bool a_bAllowOpt = true);
-MU_PARSER_API void mupDefineOprt(parser_handle a_hParser, const char *a_szName, fun_type2 a_pFun, int a_iPri = 0, bool a_bAllowOpt = true);
-MU_PARSER_API void mupDefineConst(parser_handle a_hParser, const char *a_szName, double a_fVal);
-MU_PARSER_API void mupDefineStrConst(parser_handle a_hParser, const char *a_szName, const char *a_sVal);
-MU_PARSER_API void mupDefineVar(parser_handle a_hParser, const char *a_szName, double *a_fVar);
-MU_PARSER_API void mupDefinePostfixOprt(parser_handle a_hParser, const char *a_szName, fun_type1 a_pOprt, bool a_bAllowOpt = true);
-MU_PARSER_API void mupDefineInfixOprt(parser_handle a_hParser, const char *a_szName, fun_type1 a_pOprt, bool a_bAllowOpt=true);
-
-// Define character sets for identifiers
-MU_PARSER_API void mupDefineNameChars(parser_handle a_hParser, const char *a_szCharset);
-MU_PARSER_API void mupDefineOprtChars(parser_handle a_hParser, const char *a_szCharset);
-MU_PARSER_API void mupDefineInfixOprtChars(parser_handle a_hParser, const char *a_szCharset);
-
-// Remove all / single variables
-MU_PARSER_API void mupRemoveVar(parser_handle a_hParser, const char *a_szName);
-MU_PARSER_API void mupClearVar(parser_handle a_hParser);
-MU_PARSER_API void mupClearConst(parser_handle a_hParser);
-MU_PARSER_API void mupClearOprt(parser_handle a_hParser);
-
-// Querying variables / expression variables / constants
-MU_PARSER_API int mupGetExprVarNum(parser_handle a_hParser);
-MU_PARSER_API int mupGetVarNum(parser_handle a_hParser);
-MU_PARSER_API int mupGetConstNum(parser_handle a_hParser);
-MU_PARSER_API void mupGetExprVar(parser_handle a_hParser, unsigned a_iVar, const char **a_pszName, double **a_pVar);
-MU_PARSER_API void mupGetVar(parser_handle a_hParser, unsigned a_iVar, const char **a_pszName, double **a_pVar);
-MU_PARSER_API void mupGetConst(parser_handle a_hParser, unsigned a_iVar, const char **a_pszName, double &a_pVar);
-
-// Add value recognition callbacks
-MU_PARSER_API void mupAddValIdent(parser_handle a_hParser, identfun_type);
-
-// Error handling
-MU_PARSER_API bool mupError();
-MU_PARSER_API void mupErrorReset();
-MU_PARSER_API const char* mupGetErrorMsg();
-MU_PARSER_API int mupGetErrorCode();
-MU_PARSER_API int mupGetErrorPos();
-MU_PARSER_API const char* mupGetErrorToken();
-
-} // extern "C"
-
-#endif
diff --git a/muparser/muParserDef.h b/muparser/muParserDef.h deleted file mode 100644 index 164b882..0000000 --- a/muparser/muParserDef.h +++ /dev/null @@ -1,239 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-#ifndef MUP_DEF_H
-#define MUP_DEF_H
-
-#include <iostream>
-#include <string>
-#include <sstream>
-#include <map>
-
-#include "muParserFixes.h"
-
-/** \brief Define the base datatype for values.
-
- This datatype must be a built in value type. You can not use custom classes.
- It has been tested with float, double and long double types, int should
- work as well.
-*/
-#define MUP_BASETYPE double
-
-
-/** \brief Definition of the basic bytecode datatype. */
-#define MUP_BYTECODE_TYPE long
-
-/** \brief Maybe I use this for unicode support later. */
-#if defined(_UNICODE)
- /** \brief Definition of the basic parser string type. */
- #define MUP_STRING_TYPE std::wstring
-
- #if !defined(_T)
- #define _T(x) L##x
- #endif // not defined _T
-#else
- #ifndef _T
- #define _T
- #endif
-
- /** \brief Definition of the basic parser string type. */
- #define MUP_STRING_TYPE std::string
-#endif
-
-#if defined(_DEBUG)
- /** \brief Debug macro to force an abortion of the programm with a certain message.
- */
- #define MUP_FAIL(MSG) \
- bool MSG=false; \
- assert(MSG);
-
- #ifndef _UNICODE
- /** \brief An assertion that does not kill the program.
-
- This macro is neutralised in UNICODE builds. It's
- too difficult to translate.
- */
- #define MUP_ASSERT(COND) \
- if (!(COND)) \
- { \
- stringstream_type ss; \
- ss << "Assertion \""#COND"\" failed: " \
- << __FILE__ << " line " \
- << __LINE__ << "."; \
- throw ParserError( ss.str() ); \
- }
- #else
- #define MUP_ASSERT(COND)
- #endif // _UNICODE
-#else
- #define MUP_FAIL(MSG)
- #define MUP_ASSERT(COND)
-#endif
-
-//------------------------------------------------------------------------------
-//
-// do not change anything beyond this point...
-//
-// !!! This section is devoted to macros that are used for debugging
-// !!! or for features that are not fully implemented yet.
-//
-//#define MUP_DUMP_STACK
-//#define MUP_DUMP_CMDCODE
-
-
-namespace mu
-{
-#if defined(_UNICODE)
-
- //------------------------------------------------------------------------------
- /** \brief Encapsulate wcout. */
- inline std::wostream& console()
- {
- return std::wcout;
- }
-
- /** \brief Encapsulate cin. */
- inline std::wistream& console_in()
- {
- return std::wcin;
- }
-
-#else
-
- /** \brief Encapsulate cout. */
- inline std::ostream& console()
- {
- return std::cout;
- }
-
- /** \brief Encapsulate cin. */
- inline std::istream& console_in()
- {
- return std::cin;
- }
-
-#endif
-
- //------------------------------------------------------------------------------
- /** \brief Bytecode values.
-
- \attention The order of the operator entries must match the order in ParserBase::c_DefaultOprt!
- */
- enum ECmdCode
- {
- // The following are codes for built in binary operators
- // apart from built in operators the user has the opportunity to
- // add user defined operators.
- cmLE = 0, ///< Operator item: less or equal
- cmGE = 1, ///< Operator item: greater or equal
- cmNEQ = 2, ///< Operator item: not equal
- cmEQ = 3, ///< Operator item: equals
- cmLT = 4, ///< Operator item: less than
- cmGT = 5, ///< Operator item: greater than
- cmADD = 6, ///< Operator item: add
- cmSUB = 7, ///< Operator item: subtract
- cmMUL = 8, ///< Operator item: multiply
- cmDIV = 9, ///< Operator item: division
- cmPOW = 10, ///< Operator item: y to the power of ...
- cmAND = 11, ///< Operator item: logical and
- cmOR = 12, ///< Operator item: logical or
- cmXOR = 13, ///< Operator item: logical xor
- cmASSIGN = 14, ///< Operator item: Assignment operator
- cmBO = 15, ///< Operator item: opening bracket
- cmBC = 16, ///< Operator item: closing bracket
- cmCOMMA = 17, ///< Operator item: comma
- cmVAR = 18, ///< variable item
- cmSTRVAR = 19,
- cmVAL = 20, ///< value item
-
- cmFUNC = 21, ///< Code for a function item
- cmFUNC_STR = 22, ///< Code for a function with a string parameter
-
- cmSTRING = 23, ///< Code for a string token
- cmOPRT_BIN = 24, ///< user defined binary operator
- cmOPRT_POSTFIX = 25, ///< code for postfix operators
- cmOPRT_INFIX = 26, ///< code for infix operators
- cmEND = 27, ///< end of formula
- cmUNKNOWN = 28 ///< uninitialized item
- };
-
- //------------------------------------------------------------------------------
- /** \brief Types internally used by the parser.
- */
- enum ETypeCode
- {
- tpSTR = 0, ///> String type (Function arguments and constants only, no string variables)
- tpDBL = 1, ///> Floating point variables
- tpVOID = 2 ///> Undefined type.
- };
-
- //------------------------------------------------------------------------------
- /** \brief Parser operator precedence values. */
- enum EPrec
- {
- // binary operators
- prLOGIC = 1, ///> logic operators
- prCMP = 2, ///> comparsion operators
- prADD_SUB = 3, ///> addition
- prMUL_DIV = 4, ///> multiplication/division
- prPOW = 5, ///> power operator priority (highest)
-
- // infix operators
- prINFIX = 4, ///> Signs have a higher priority than ADD_SUB, but lower than power operator
- prPOSTFIX = 4 ///> Postfix operator priority (currently unused)
- };
-
- //------------------------------------------------------------------------------
- // basic types
- typedef MUP_BASETYPE value_type;
- typedef MUP_STRING_TYPE string_type;
- typedef MUP_BYTECODE_TYPE bytecode_type;
- typedef string_type::value_type char_type;
- typedef std::basic_stringstream<char_type,
- std::char_traits<char_type>,
- std::allocator<char_type> > stringstream_type;
-
- // Data container types
- typedef std::map<string_type, value_type*> varmap_type;
- typedef std::map<string_type, value_type> valmap_type;
- typedef std::map<string_type, std::size_t> strmap_type;
-
- // Parser callbacks
- typedef value_type (*fun_type1)(value_type);
- typedef value_type (*fun_type2)(value_type, value_type);
- typedef value_type (*fun_type3)(value_type, value_type, value_type);
- typedef value_type (*fun_type4)(value_type, value_type, value_type, value_type);
- typedef value_type (*fun_type5)(value_type, value_type, value_type, value_type, value_type);
- typedef value_type (*multfun_type)(const value_type*, int);
- typedef value_type (*strfun_type1)(const char_type*);
- typedef value_type (*strfun_type2)(const char_type*, value_type);
- typedef value_type (*strfun_type3)(const char_type*, value_type, value_type);
-
- // Parser utility callback functions (unrelated to the math callbacks)
- typedef bool (*identfun_type)(const char_type*, int&, value_type&);
- typedef value_type* (*facfun_type)(const char_type*, void*);
-} // end fo namespace
-
-#endif
-
diff --git a/muparser/muParserError.cpp b/muparser/muParserError.cpp deleted file mode 100644 index 237f529..0000000 --- a/muparser/muParserError.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-#include "muParserError.h"
-
-
-namespace mu
-{
- const ParserErrorMsg ParserErrorMsg::m_Instance;
-
- //------------------------------------------------------------------------------
- const ParserErrorMsg& ParserErrorMsg::Instance()
- {
- return m_Instance;
- }
-
- //------------------------------------------------------------------------------
- string_type ParserErrorMsg::operator[](unsigned a_iIdx) const
- {
- return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : string_type();
- }
-
-
- //---------------------------------------------------------------------------
- ParserErrorMsg::~ParserErrorMsg()
- {}
-
- //---------------------------------------------------------------------------
- /** \brief Assignement operator is deactivated.
- */
- ParserErrorMsg& ParserErrorMsg::operator=(const ParserErrorMsg& )
- {
- assert(false);
- return *this;
- }
-
- //---------------------------------------------------------------------------
- ParserErrorMsg::ParserErrorMsg(const ParserErrorMsg&)
- {}
-
- //---------------------------------------------------------------------------
- ParserErrorMsg::ParserErrorMsg()
- :m_vErrMsg(0)
- {
- m_vErrMsg.resize(ecCOUNT);
-
- m_vErrMsg[ecUNASSIGNABLE_TOKEN] = _T("Undefined token \"$TOK$\" found at position $POS$.");
- m_vErrMsg[ecINTERNAL_ERROR] = _T("Internal error");
- m_vErrMsg[ecINVALID_NAME] = _T("Invalid function-, variable- or constant name.");
- m_vErrMsg[ecINVALID_FUN_PTR] = _T("Invalid pointer to callback function.");
- m_vErrMsg[ecEMPTY_EXPRESSION] = _T("Expression is empty.");
- m_vErrMsg[ecINVALID_VAR_PTR] = _T("Invalid pointer to variable.");
- m_vErrMsg[ecUNEXPECTED_OPERATOR] = _T("Unexpected operator \"$TOK$\" found at position $POS$");
- m_vErrMsg[ecUNEXPECTED_EOF] = _T("Unexpected end of formula at position $POS$");
- m_vErrMsg[ecUNEXPECTED_COMMA] = _T("Unexpected comma at position $POS$");
- m_vErrMsg[ecUNEXPECTED_PARENS] = _T("Unexpected parenthesis \"$TOK$\" at position $POS$");
- m_vErrMsg[ecUNEXPECTED_FUN] = _T("Unexpected function \"$TOK$\" at position $POS$");
- m_vErrMsg[ecUNEXPECTED_VAL] = _T("Unexpected value \"$TOK$\" found at position $POS$");
- m_vErrMsg[ecUNEXPECTED_VAR] = _T("Unexpected variable \"$TOK$\" found at position $POS$");
- m_vErrMsg[ecUNEXPECTED_ARG] = _T("Function arguments used without a function (position: $POS$)");
- m_vErrMsg[ecMISSING_PARENS] = _T("Missing parenthesis");
- m_vErrMsg[ecTOO_MANY_PARAMS] = _T("Too many parameters for function \"$TOK$\" at formula position $POS$");
- m_vErrMsg[ecTOO_FEW_PARAMS] = _T("Too few parameters for function \"$TOK$\" at formula position $POS$");
- m_vErrMsg[ecDIV_BY_ZERO] = _T("Divide by zero");
- m_vErrMsg[ecDOMAIN_ERROR] = _T("Domain error");
- m_vErrMsg[ecNAME_CONFLICT] = _T("Name conflict");
- m_vErrMsg[ecOPT_PRI] = _T("Invalid value for operator priority (must be greater or equal to zero).");
- m_vErrMsg[ecBUILTIN_OVERLOAD] = _T("Binary operator identifier conflicts with a built in operator.");
- m_vErrMsg[ecUNEXPECTED_STR] = _T("Unexpected string token found at position $POS$.");
- m_vErrMsg[ecUNTERMINATED_STRING] = _T("Unterminated string starting at position $POS$.");
- m_vErrMsg[ecSTRING_EXPECTED] = _T("String function called with a non string type of argument.");
- m_vErrMsg[ecVAL_EXPECTED] = _T("String value used where a numerical argument is expected.");
- m_vErrMsg[ecOPRT_TYPE_CONFLICT] = _T("No suitable overload for operator \"$TOK$\" at position $POS$.");
- m_vErrMsg[ecGENERIC] = _T("Parser error.");
- m_vErrMsg[ecSTR_RESULT] = _T("Function result is a string.");
-
- #if defined(_DEBUG)
- for (int i=0; i<ecCOUNT; ++i)
- if (!m_vErrMsg[i].length())
- assert(false);
- #endif
- }
-
- //---------------------------------------------------------------------------
- //
- //
- //
- // ParserError class
- //
- //
- //
- //---------------------------------------------------------------------------
-
- //------------------------------------------------------------------------------
- ParserError::ParserError()
- :m_strMsg()
- ,m_strFormula()
- ,m_strTok()
- ,m_iPos(-1)
- ,m_iErrc(ecUNDEFINED)
- ,m_ErrMsg(ParserErrorMsg::Instance())
- {
- }
-
- //------------------------------------------------------------------------------
- /** \brief This Constructor is used for internal exceptions only.
-
- It does not contain any information but the error code.
- */
- ParserError::ParserError(EErrorCodes /*a_iErrc*/)
- :m_ErrMsg(ParserErrorMsg::Instance())
- {
- Reset();
- m_strMsg = _T("parser error");
- }
-
- //------------------------------------------------------------------------------
- ParserError::ParserError(const string_type &sMsg)
- :m_ErrMsg(ParserErrorMsg::Instance())
- {
- Reset();
- m_strMsg = sMsg;
- }
-
- //------------------------------------------------------------------------------
- ParserError::ParserError( EErrorCodes a_iErrc,
- const string_type &sTok,
- const string_type &sFormula,
- int a_iPos )
- :m_strMsg()
- ,m_strFormula(sFormula)
- ,m_strTok(sTok)
- ,m_iPos(a_iPos)
- ,m_iErrc(a_iErrc)
- ,m_ErrMsg(ParserErrorMsg::Instance())
- {
- m_strMsg = m_ErrMsg[m_iErrc];
- stringstream_type stream;
- stream << (int)m_iPos;
- ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
- ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
- }
-
- //------------------------------------------------------------------------------
- ParserError::ParserError( EErrorCodes a_iErrc, int a_iPos, const string_type &sTok)
- :m_strMsg()
- ,m_strFormula()
- ,m_strTok(sTok)
- ,m_iPos(a_iPos)
- ,m_iErrc(a_iErrc)
- ,m_ErrMsg(ParserErrorMsg::Instance())
- {
- m_strMsg = m_ErrMsg[m_iErrc];
- stringstream_type stream;
- stream << (int)m_iPos;
- ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
- ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
- }
-
- //------------------------------------------------------------------------------
- ParserError::ParserError( const char_type *a_szMsg, int a_iPos, const string_type &sTok)
- :m_strMsg(a_szMsg)
- ,m_strFormula()
- ,m_strTok(sTok)
- ,m_iPos(a_iPos)
- ,m_iErrc(ecGENERIC)
- ,m_ErrMsg(ParserErrorMsg::Instance())
- {
- stringstream_type stream;
- stream << (int)m_iPos;
- ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
- ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
- }
-
- //------------------------------------------------------------------------------
- ParserError::ParserError(const ParserError &a_Obj)
- :m_strMsg(a_Obj.m_strMsg)
- ,m_strFormula(a_Obj.m_strFormula)
- ,m_strTok(a_Obj.m_strTok)
- ,m_iPos(a_Obj.m_iPos)
- ,m_iErrc(a_Obj.m_iErrc)
- ,m_ErrMsg(ParserErrorMsg::Instance())
- {
- }
-
- //------------------------------------------------------------------------------
- ParserError& ParserError::operator=(const ParserError &a_Obj)
- {
- if (this==&a_Obj)
- return *this;
-
- m_strMsg = a_Obj.m_strMsg;
- m_strFormula = a_Obj.m_strFormula;
- m_strTok = a_Obj.m_strTok;
- m_iPos = a_Obj.m_iPos;
- m_iErrc = a_Obj.m_iErrc;
- return *this;
- }
-
- //------------------------------------------------------------------------------
- ParserError::~ParserError()
- {
- }
-
- /** \brief Replace all ocuurences of a substring with another string. */
- void ParserError::ReplaceSubString( string_type &strSource,
- const string_type &strFind,
- const string_type &strReplaceWith)
- {
- string_type strResult;
- string_type::size_type iPos(0), iNext(0);
-
- for(;;)
- {
- iNext = strSource.find(strFind, iPos);
- strResult.append(strSource, iPos, iNext-iPos);
-
- if( iNext==string_type::npos )
- break;
-
- strResult.append(strReplaceWith);
- iPos = iNext + strFind.length();
- }
-
- strSource.swap(strResult);
- }
-
- //------------------------------------------------------------------------------
- void ParserError::Reset()
- {
- m_strMsg = _T("");
- m_strFormula = _T("");
- m_strTok = _T("");
- m_iPos = -1;
- m_iErrc = ecUNDEFINED;
- }
-
- //------------------------------------------------------------------------------
- void ParserError::SetFormula(const string_type &a_strFormula)
- {
- m_strFormula = a_strFormula;
- }
-
- //------------------------------------------------------------------------------
- const string_type& ParserError::GetExpr() const
- {
- return m_strFormula;
- }
-
- //------------------------------------------------------------------------------
- const string_type& ParserError::GetMsg() const
- {
- return m_strMsg;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Return the formula position related to the error.
-
- If the error is not related to a distinct position this will return -1
- */
- std::size_t ParserError::GetPos() const
- {
- return m_iPos;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Return string related with this token (if available). */
- const string_type& ParserError::GetToken() const
- {
- return m_strTok;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Return the error code. */
- EErrorCodes ParserError::GetCode() const
- {
- return m_iErrc;
- }
-} // namespace mu
diff --git a/muparser/muParserError.h b/muparser/muParserError.h deleted file mode 100644 index c550eff..0000000 --- a/muparser/muParserError.h +++ /dev/null @@ -1,160 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef MU_PARSER_ERROR_H
-#define MU_PARSER_ERROR_H
-
-#include <cassert>
-#include <stdexcept>
-#include <string>
-#include <sstream>
-#include <vector>
-#include <memory>
-
-#include "muParserDef.h"
-
-
-namespace mu
-{
-
-/** \brief Error codes. */
-enum EErrorCodes
-{
- // Formula syntax errors
- ecUNEXPECTED_OPERATOR = 0, ///< Unexpected binary operator found
- ecUNASSIGNABLE_TOKEN = 1, ///< Token cant be identified.
- ecUNEXPECTED_EOF = 2, ///< Unexpected end of formula. (Example: "2+sin(")
- ecUNEXPECTED_COMMA = 3, ///< An unexpected comma has been found. (Example: "1,23")
- ecUNEXPECTED_ARG = 4, ///< An unexpected argument has been found
- ecUNEXPECTED_VAL = 5, ///< An unexpected value token has been found
- ecUNEXPECTED_VAR = 6, ///< An unexpected variable token has been found
- ecUNEXPECTED_PARENS = 7, ///< Unexpected Parenthesis, opening or closing
- ecUNEXPECTED_STR = 8, ///< A string has been found at an inapropriate position
- ecSTRING_EXPECTED = 9, ///< A string function has been called with a different type of argument
- ecVAL_EXPECTED = 10, ///< A numerical function has been called with a non value type of argument
- ecMISSING_PARENS = 11, ///< Missing parens. (Example: "3*sin(3")
- ecUNEXPECTED_FUN = 12, ///< Unexpected function found. (Example: "sin(8)cos(9)")
- ecUNTERMINATED_STRING = 13, ///< unterminated string constant. (Example: "3*valueof("hello)")
- ecTOO_MANY_PARAMS = 14, ///< Too many function parameters
- ecTOO_FEW_PARAMS = 15, ///< Too few function parameters. (Example: "ite(1<2,2)")
- ecOPRT_TYPE_CONFLICT = 16, ///< binary operators may only be applied to value items of the same type
- ecSTR_RESULT = 17, ///< result is a string
-
- // Invalid Parser input Parameters
- ecINVALID_NAME = 18, ///< Invalid function, variable or constant name.
- ecBUILTIN_OVERLOAD = 19, ///< Trying to overload builtin operator
- ecINVALID_FUN_PTR = 20, ///< Invalid callback function pointer
- ecINVALID_VAR_PTR = 21, ///< Invalid variable pointer
- ecEMPTY_EXPRESSION = 22, ///< The Expression is empty
- ecNAME_CONFLICT = 23, ///< Name conflict
- ecOPT_PRI = 24, ///< Invalid operator priority
- //
- ecDOMAIN_ERROR = 25, ///< catch division by zero, sqrt(-1), log(0) (currently unused)
- ecDIV_BY_ZERO = 26, ///< Division by zero (currently unused)
- ecGENERIC = 27, ///< Generic error
-
- // internal errors
- ecINTERNAL_ERROR = 28, ///< Internal error of any kind.
-
- // The last two are special entries
- ecCOUNT, ///< This is no error code, It just stores just the total number of error codes
- ecUNDEFINED = -1 ///< Undefined message, placeholder to detect unassigned error messages
-};
-
-//---------------------------------------------------------------------------
-class ParserErrorMsg
-{
-public:
- typedef ParserErrorMsg self_type;
-
- ParserErrorMsg& operator=(const ParserErrorMsg &);
- ParserErrorMsg(const ParserErrorMsg&);
- ParserErrorMsg();
-
- ~ParserErrorMsg();
-
- static const ParserErrorMsg& Instance();
- string_type operator[](unsigned a_iIdx) const;
-
-private:
- std::vector<string_type> m_vErrMsg;
- static const self_type m_Instance;
-};
-
-//---------------------------------------------------------------------------
-/** \brief Error class of the parser.
-
- Part of the math parser package.
-
- \author Ingo Berg
-*/
-/* final */ class ParserError
-{
-private:
- //------------------------------------------------------------------------------
- /** \brief Replace all ocuurences of a substring with another string. */
- void ReplaceSubString( string_type &strSource,
- const string_type &strFind,
- const string_type &strReplaceWith);
- void Reset();
-
-public:
- ParserError();
- explicit ParserError(EErrorCodes a_iErrc);
- explicit ParserError(const string_type &sMsg);
- ParserError( EErrorCodes a_iErrc,
- const string_type &sTok,
- const string_type &sFormula = string_type(_T("(formula is not available)")),
- int a_iPos = -1);
- ParserError( EErrorCodes a_iErrc,
- int a_iPos,
- const string_type &sTok);
- ParserError( const char_type *a_szMsg,
- int a_iPos = -1,
- const string_type &sTok = string_type());
- ParserError(const ParserError &a_Obj);
- ParserError& operator=(const ParserError &a_Obj);
- ~ParserError();
-
- void SetFormula(const string_type &a_strFormula);
- const string_type& GetExpr() const;
- const string_type& GetMsg() const;
- std::size_t GetPos() const;
- const string_type& GetToken() const;
- EErrorCodes GetCode() const;
-
-private:
- string_type m_strMsg; ///< The message string
- string_type m_strFormula; ///< Formula string
- string_type m_strTok; ///< Token related with the error
- int m_iPos; ///< Formula position related to the error
- EErrorCodes m_iErrc; ///< Error code
- const ParserErrorMsg &m_ErrMsg;
-};
-
-} // namespace mu
-
-#endif
-
diff --git a/muparser/muParserFixes.h b/muparser/muParserFixes.h deleted file mode 100644 index 02ca007..0000000 --- a/muparser/muParserFixes.h +++ /dev/null @@ -1,196 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef MU_PARSER_FIXES_H
-#define MU_PARSER_FIXES_H
-
-//
-// Compatibility fixes
-//
-
-//---------------------------------------------------------------------------
-//
-// Intel Compiler
-//
-//---------------------------------------------------------------------------
-
-#ifdef __INTEL_COMPILER
-
-// remark #981: operands are evaluated in unspecified order
-// disabled -> completely pointless if the functions do not have side effects
-//
-#pragma warning(disable:981)
-
-// remark #383: value copied to temporary, reference to temporary used
-#pragma warning(disable:383)
-
-// remark #1572: floating-point equality and inequality comparisons are unreliable
-// disabled -> everyone knows it, the parser passes this problem
-// deliberately to the user
-#pragma warning(disable:1572)
-
-#endif
-
-
-//---------------------------------------------------------------------------
-//
-// MSVC6
-//
-//---------------------------------------------------------------------------
-
-
-#if _MSC_VER==1200
-
-/** \brief Macro to replace the MSVC6 auto_ptr with the _my_auto_ptr class.
-
- Hijack auto_ptr and replace it with a version that actually does
- what an auto_ptr normally does. If you use std::auto_ptr in your other code
- it might either explode or work much better. The original crap created
- by Microsoft, called auto_ptr and bundled with MSVC6 is not standard compliant.
-*/
-#define auto_ptr _my_auto_ptr
-
-// This is another stupidity that needs to be undone in order to de-pollute
-// the global namespace!
-#undef min
-#undef max
-
-
-namespace std
-{
- typedef ::size_t size_t;
-
- //---------------------------------------------------------------------------
- /** \brief MSVC6 fix: Dummy function to put rand into namespace std.
-
- This is a hack for MSVC6 only. It's dirty, it's ugly and it works, provided
- inlining is enabled. Necessary because I will not pollute or change my
- code in order to adopt it to MSVC6 interpretation of how C++ should look like!
- */
- inline int rand(void)
- {
- return ::rand();
- }
-
- //---------------------------------------------------------------------------
- /** \brief MSVC6 fix: Dummy function to put strlen into namespace std.
-
- This is a hack for MSVC6 only. It's dirty, it's ugly and it works, provided
- inlining is enabled. Necessary because I will not pollute or change my
- code in order to adopt it to MSVC6 interpretation of how C++ should look like!
- */
- inline size_t strlen(const char *szMsg)
- {
- return ::strlen(szMsg);
- }
-
- //---------------------------------------------------------------------------
- /** \brief MSVC6 fix: Dummy function to put strncmp into namespace std.
-
- This is a hack for MSVC6 only. It's dirty, it's ugly and it works, provided
- inlining is enabled. Necessary because I will not pollute or change my
- code in order to adopt it to MSVC6 interpretation of how C++ should look like!
- */
- inline int strncmp(const char *a, const char *b, size_t len)
- {
- return ::strncmp(a,b,len);
- }
-
- //---------------------------------------------------------------------------
- template<typename T>
- T max(T a, T b)
- {
- return (a>b) ? a : b;
- }
-
- //---------------------------------------------------------------------------
- template<typename T>
- T min(T a, T b)
- {
- return (a<b) ? a : b;
- }
-
- //---------------------------------------------------------------------------
- /** Standard compliant auto_ptr redefinition for MSVC6.
-
- The code is taken from VS.NET 2003, slightly modified to reduce
- it's dependencies from other classes.
- */
- template<class _Ty>
- class _my_auto_ptr
- {
- public:
- typedef _Ty element_type;
-
- explicit _my_auto_ptr(_Ty *_Ptr = 0)
- :_Myptr(_Ptr)
- {}
-
- _my_auto_ptr(_my_auto_ptr<_Ty>& _Right)
- :_Myptr(_Right.release())
- {}
-
- template<class _Other>
- operator _my_auto_ptr<_Other>()
- {
- return (_my_auto_ptr<_Other>(*this));
- }
-
- template<class _Other>
- _my_auto_ptr<_Ty>& operator=(_my_auto_ptr<_Other>& _Right)
- {
- reset(_Right.release());
- return (*this);
- }
-
- ~auto_ptr() { delete _Myptr; }
- _Ty& operator*() const { return (*_Myptr); }
- _Ty *operator->() const { return (&**this); }
- _Ty *get() const { return (_Myptr); }
-
- _Ty *release()
- {
- _Ty *_Tmp = _Myptr;
- _Myptr = 0;
- return (_Tmp);
- }
-
- void reset(_Ty* _Ptr = 0)
- {
- if (_Ptr != _Myptr)
- delete _Myptr;
- _Myptr = _Ptr;
- }
-
- private:
- _Ty *_Myptr;
- }; // class _my_auto_ptr
-} // namespace std
-
-#endif // Microsoft Visual Studio Version 6.0
-
-#endif // include guard
-
-
diff --git a/muparser/muParserInt.cpp b/muparser/muParserInt.cpp deleted file mode 100644 index 1b072bc..0000000 --- a/muparser/muParserInt.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "muParserInt.h"
-
-#include <cmath>
-#include <algorithm>
-#include <numeric>
-
-using namespace std;
-
-
-/** \brief Namespace for mathematical applications. */
-namespace mu
-{
-
-value_type ParserInt::Abs(value_type v) { return Round(fabs(v)); }
-value_type ParserInt::Sign(value_type v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; }
-value_type ParserInt::Ite(value_type v1,
- value_type v2,
- value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); }
-value_type ParserInt::Add(value_type v1, value_type v2) { return Round(v1) + Round(v2); }
-value_type ParserInt::Sub(value_type v1, value_type v2) { return Round(v1) - Round(v2); }
-value_type ParserInt::Mul(value_type v1, value_type v2) { return Round(v1) * Round(v2); }
-value_type ParserInt::Div(value_type v1, value_type v2) { return Round(v1) / Round(v2); }
-value_type ParserInt::Mod(value_type v1, value_type v2) { return Round(v1) % Round(v2); }
-value_type ParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); }
-value_type ParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); }
-value_type ParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); }
-value_type ParserInt::LogOr(value_type v1, value_type v2) { return Round(v1) | Round(v2); }
-value_type ParserInt::LogXor(value_type v1, value_type v2) { return Round(v1) ^ Round(v2); }
-value_type ParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); }
-value_type ParserInt::Or(value_type v1, value_type v2) { return Round(v1) || Round(v2); }
-value_type ParserInt::Less(value_type v1, value_type v2) { return Round(v1) < Round(v2); }
-value_type ParserInt::Greater(value_type v1, value_type v2) { return Round(v1) > Round(v2); }
-value_type ParserInt::LessEq(value_type v1, value_type v2) { return Round(v1) <= Round(v2); }
-value_type ParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); }
-value_type ParserInt::Equal(value_type v1, value_type v2) { return Round(v1) == Round(v2); }
-value_type ParserInt::NotEqual(value_type v1, value_type v2) { return Round(v1) != Round(v2); }
-value_type ParserInt::Not(value_type v) { return !Round(v); }
-
-//---------------------------------------------------------------------------
-// Unary operator Callbacks: Infix operators
-value_type ParserInt::UnaryMinus(value_type v)
-{
- return -Round(v);
-}
-
-//---------------------------------------------------------------------------
-value_type ParserInt::Sum(const value_type* a_afArg, int a_iArgc)
-{
- if (!a_iArgc)
- throw ParserError(_T("too few arguments for function sum."));
-
- value_type fRes=0;
- for (int i=0; i<a_iArgc; ++i)
- fRes += a_afArg[i];
-
- return fRes;
-}
-
-//---------------------------------------------------------------------------
-value_type ParserInt::Min(const value_type* a_afArg, int a_iArgc)
-{
- if (!a_iArgc)
- throw ParserError( _T("too few arguments for function min.") );
-
- value_type fRes=a_afArg[0];
- for (int i=0; i<a_iArgc; ++i)
- fRes = std::min(fRes, a_afArg[i]);
-
- return fRes;
-}
-
-//---------------------------------------------------------------------------
-value_type ParserInt::Max(const value_type* a_afArg, int a_iArgc)
-{
- if (!a_iArgc)
- throw ParserError(_T("too few arguments for function min."));
-
- value_type fRes=a_afArg[0];
- for (int i=0; i<a_iArgc; ++i)
- fRes = std::max(fRes, a_afArg[i]);
-
- return fRes;
-}
-
-//---------------------------------------------------------------------------
-// Default value recognition callback
-bool ParserInt::IsVal(const char_type *a_szExpr, int &a_iPos, value_type &a_fVal)
-{
- stringstream_type stream(a_szExpr);
- int iVal(0);
-
- stream >> iVal;
- int iEnd = stream.tellg(); // Position after reading
-
- if (iEnd==-1)
- return false;
-
- a_iPos += iEnd;
- a_fVal = (value_type)iVal;
- return true;
-}
-
-//---------------------------------------------------------------------------
-bool ParserInt::IsHexVal(const char_type *a_szExpr, int &a_iPos, value_type &a_fVal)
-{
- if (a_szExpr[0]!='$')
- return false;
-
- unsigned iVal(0);
-
-// New code based on streams for UNICODE compliance:
- stringstream_type::pos_type nPos(0);
- stringstream_type ss(a_szExpr+1);
- ss >> std::hex >> iVal;
- nPos = ss.tellg();
-
- if (nPos==(stringstream_type::pos_type)0)
- return false;
-
- a_iPos += 1 + nPos;
-
-/*
- // original code based on sscanf. Working but not UNICODE compliant!
- int iLen(0);
- if (sscanf(a_szExpr+1, "%x%n", &iVal, &iLen)==0)
- return false;
-
- a_iPos += iLen+1;
-*/
-
- a_fVal = iVal;
- return true;
-}
-
-//---------------------------------------------------------------------------
-bool ParserInt::IsBinVal(const char_type *a_szExpr, int &a_iPos, value_type &a_fVal)
-{
- if (a_szExpr[0]!='#')
- return false;
-
- unsigned iVal(0),
- iBits(sizeof(iVal)*8),
- i(0);
-
- for (i=0; (a_szExpr[i+1]=='0' || a_szExpr[i+1]=='1') && i<iBits; ++i)
- iVal |= (int)(a_szExpr[i+1]=='1') << ((iBits-1)-i);
-
- if (i==0)
- return false;
-
- if (i==iBits)
- throw exception_type(_T("Binary to integer conversion error (overflow)."));
-
- a_fVal = (unsigned)(iVal >> (iBits-i) );
- a_iPos += i+1;
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-/** \brief Constructor.
-
- Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
-*/
-ParserInt::ParserInt()
-:ParserBase()
-{
- AddValIdent(IsVal);
- AddValIdent(IsHexVal);
- AddValIdent(IsBinVal);
-
- InitCharSets();
- InitFun();
- InitOprt();
-}
-
-//---------------------------------------------------------------------------
-void ParserInt::InitConst()
-{
-}
-
-//---------------------------------------------------------------------------
-void ParserInt::InitCharSets()
-{
- DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
- DefineOprtChars( _T("+-*^/?<>=!%&|~'_") );
- DefineInfixOprtChars( _T("/+-*^?<>=!%&|~'_") );
-}
-
-//---------------------------------------------------------------------------
-/** \brief Initialize the default functions. */
-void ParserInt::InitFun()
-{
- DefineFun( _T("sign"), Sign);
- DefineFun( _T("abs"), Abs);
- DefineFun( _T("if"), Ite);
- DefineFun( _T("sum"), Sum);
- DefineFun( _T("min"), Min);
- DefineFun( _T("max"), Max);
-}
-
-//---------------------------------------------------------------------------
-/** \brief Initialize operators. */
-void ParserInt::InitOprt()
-{
- // disable all built in operators, not all of them usefull for integer numbers
- // (they don't do rounding of values)
- EnableBuiltInOprt(false);
-
- // Disable all built in operators, they wont work with integer numbers
- // since they are designed for floating point numbers
- DefineInfixOprt( _T("-"), UnaryMinus);
- DefineInfixOprt( _T("!"), Not);
-
- DefineOprt( _T("&"), LogAnd, prLOGIC);
- DefineOprt( _T("|"), LogOr, prLOGIC);
- DefineOprt( _T("^"), LogXor, prLOGIC);
- DefineOprt( _T("&&"), And, prLOGIC);
- DefineOprt( _T("||"), Or, prLOGIC);
-
- DefineOprt( _T("<"), Less, prCMP);
- DefineOprt( _T(">"), Greater, prCMP);
- DefineOprt( _T("<="), LessEq, prCMP);
- DefineOprt( _T(">="), GreaterEq, prCMP);
- DefineOprt( _T("=="), Equal, prCMP);
- DefineOprt( _T("!="), NotEqual, prCMP);
-
- DefineOprt( _T("+"), Add, prADD_SUB);
- DefineOprt( _T("-"), Sub, prADD_SUB);
-
- DefineOprt( _T("*"), Mul, prMUL_DIV);
- DefineOprt( _T("/"), Div, prMUL_DIV);
- DefineOprt( _T("%"), Mod, prMUL_DIV);
-
- DefineOprt( _T(">>"), Shr, prMUL_DIV+1);
- DefineOprt( _T("<<"), Shl, prMUL_DIV+1);
-}
-
-} // namespace mu
diff --git a/muparser/muParserInt.h b/muparser/muParserInt.h deleted file mode 100644 index 008792d..0000000 --- a/muparser/muParserInt.h +++ /dev/null @@ -1,93 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef MU_PARSER_INT_H
-#define MU_PARSER_INT_H
-
-#include "muParserBase.h"
-#include <vector>
-
-
-namespace mu
-{
-
-/** \brief Mathematical expressions parser.
-
- This version of the parser handles only integer numbers. It disables the built in operators thus it is
- slower than muParser. Integer values are stored in the double value_type and converted if needed.
-*/
-class ParserInt : public ParserBase
-{
-private:
- static int Round(value_type v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); };
-
- static value_type Abs(value_type);
- static value_type Sign(value_type);
- static value_type Ite(value_type, value_type, value_type);
- // !! The unary Minus is a MUST, otherwise you cant use negative signs !!
- static value_type UnaryMinus(value_type);
- // Functions with variable number of arguments
- static value_type Sum(const value_type* a_afArg, int a_iArgc); // sum
- static value_type Min(const value_type* a_afArg, int a_iArgc); // minimum
- static value_type Max(const value_type* a_afArg, int a_iArgc); // maximum
- // binary operator callbacks
- static value_type Add(value_type v1, value_type v2);
- static value_type Sub(value_type v1, value_type v2);
- static value_type Mul(value_type v1, value_type v2);
- static value_type Div(value_type v1, value_type v2);
- static value_type Mod(value_type v1, value_type v2);
- static value_type Shr(value_type v1, value_type v2);
- static value_type Shl(value_type v1, value_type v2);
- static value_type LogAnd(value_type v1, value_type v2);
- static value_type LogOr(value_type v1, value_type v2);
- static value_type LogXor(value_type v1, value_type v2);
- static value_type And(value_type v1, value_type v2);
- static value_type Or(value_type v1, value_type v2);
- static value_type Xor(value_type v1, value_type v2);
- static value_type Less(value_type v1, value_type v2);
- static value_type Greater(value_type v1, value_type v2);
- static value_type LessEq(value_type v1, value_type v2);
- static value_type GreaterEq(value_type v1, value_type v2);
- static value_type Equal(value_type v1, value_type v2);
- static value_type NotEqual(value_type v1, value_type v2);
- static value_type Not(value_type v1);
-
- static bool IsHexVal(const char_type *a_szExpr, int &a_iPos, value_type &a_iVal);
- static bool IsBinVal(const char_type *a_szExpr, int &a_iPos, value_type &a_iVal);
- static bool IsVal(const char_type *a_szExpr, int &a_iPos, value_type &a_iVal);
-
-public:
- ParserInt();
-
- virtual void InitFun();
- virtual void InitOprt();
- virtual void InitConst();
- virtual void InitCharSets();
-};
-
-} // namespace mu
-
-#endif
-
diff --git a/muparser/muParserStack.h b/muparser/muParserStack.h deleted file mode 100644 index e035582..0000000 --- a/muparser/muParserStack.h +++ /dev/null @@ -1,120 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef MU_PARSER_STACK_H
-#define MU_PARSER_STACK_H
-
-#include <cassert>
-#include <string>
-#include <stack>
-#include <vector>
-
-#include "muParserError.h"
-#include "muParserToken.h"
-
-
-namespace mu
-{
-
- /** \brief Parser stack implementation.
-
- Stack implementation based on a std::stack. The behaviour of pop() had been
- slightly changed in order to get an error code if the stack is empty.
- The stack is used within the Parser both as a value stack and as an operator stack.
-
- \author (C) 2004, 2005 Ingo Berg
- */
- template <typename TValueType>
- class ParserStack
- {
- private:
- /** \brief Type of the underlying stack implementation. */
- typedef std::stack<TValueType, std::vector<TValueType> > impl_type;
- impl_type m_Stack;
-
- public:
-
- //---------------------------------------------------------------------------
- ParserStack()
- :m_Stack()
- {}
-
- //---------------------------------------------------------------------------
- virtual ~ParserStack()
- {}
-
- //---------------------------------------------------------------------------
- /** \brief Pop a value from the stack.
-
- Unlike the standard implementation this function will return the value that
- is going to be taken from the stack.
-
- \throw ParserException in case the stack is empty.
- \sa pop(int &a_iErrc)
- */
- TValueType pop()
- {
- if (empty())
- throw ParserError( _T("stack is empty.") );
-
- TValueType el = top();
- m_Stack.pop();
- return el;
- }
-
- /** \brief Push an object into the stack.
-
- \param a_Val object to push into the stack.
- \throw nothrow
- */
- void push(const TValueType& a_Val)
- {
- m_Stack.push(a_Val);
- }
-
- /** \brief Return the number of stored elements. */
- unsigned size() const
- {
- return (unsigned)m_Stack.size();
- }
-
- /** \brief Returns true if stack is empty false otherwise. */
- bool empty() const
- {
- return m_Stack.size()==0;
- }
-
- /** \brief Return reference to the top object in the stack.
-
- The top object is the one pushed most recently.
- */
- TValueType& top()
- {
- return m_Stack.top();
- }
- };
-} // namespace MathUtils
-
-#endif
diff --git a/muparser/muParserTest.cpp b/muparser/muParserTest.cpp deleted file mode 100644 index eed6cc4..0000000 --- a/muparser/muParserTest.cpp +++ /dev/null @@ -1,1125 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "muParserTest.h"
-
-#include <cstdio>
-#include <cmath>
-#include <iostream>
-
-#define PARSER_CONST_PI 3.141592653589793238462643
-#define PARSER_CONST_E 2.718281828459045235360287
-
-using namespace std;
-
-
-namespace mu
-{
- namespace Test
- {
- int ParserTester::c_iCount = 0;
-
- //---------------------------------------------------------------------------
- ParserTester::ParserTester()
- :m_vTestFun()
- {
- AddTest(&ParserTester::TestNames);
- AddTest(&ParserTester::TestSyntax);
- AddTest(&ParserTester::TestPostFix);
- AddTest(&ParserTester::TestInfixOprt);
- AddTest(&ParserTester::TestVarConst);
- AddTest(&ParserTester::TestVolatile);
- AddTest(&ParserTester::TestMultiArg);
- AddTest(&ParserTester::TestFormula);
- AddTest(&ParserTester::TestInterface);
- AddTest(&ParserTester::TestBinOprt);
- AddTest(&ParserTester::TestException);
- AddTest(&ParserTester::TestStrArg);
-
- ParserTester::c_iCount = 0;
- }
-
- //---------------------------------------------------------------------------
- int ParserTester::TestInterface()
- {
- int iStat = 0;
- mu::console() << _T("testing member functions...");
-
- // Test RemoveVar
- value_type afVal[3] = {1,2,3};
- Parser p;
-
- try
- {
- p.DefineVar( _T("a"), &afVal[0]);
- p.DefineVar( _T("b"), &afVal[1]);
- p.DefineVar( _T("c"), &afVal[2]);
- p.SetExpr( _T("a+b+c") );
- p.Eval();
- }
- catch(...)
- {
- iStat += 1; // this is not supposed to happen
- }
-
- try
- {
- p.RemoveVar( _T("c") );
- p.Eval();
- iStat += 1; // not supposed to reach this, nonexisting variable "c" deleted...
- }
- catch(...)
- {
- // failure is expected...
- }
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
- //---------------------------------------------------------------------------
- int ParserTester::TestStrArg()
- {
- int iStat = 0;
- mu::console() << _T("testing string arguments...");
-
- iStat += EqnTest(_T("valueof(\"aaa\")+valueof(\"bbb\") "), 246, true);
- iStat += EqnTest(_T("2*(valueof(\"aaa\")-23)+valueof(\"bbb\")"), 323, true);
- // use in expressions with variables
- iStat += EqnTest(_T("a*(atof(\"10\")-b)"), 8, true);
- iStat += EqnTest(_T("a-(atof(\"10\")*b)"), -19, true);
- // string + numeric arguments
- iStat += EqnTest(_T("strfun1(\"100\")"), 100, true);
- iStat += EqnTest(_T("strfun2(\"100\",1)"), 101, true);
- iStat += EqnTest(_T("strfun3(\"99\",1,2)"), 102, true);
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
- //---------------------------------------------------------------------------
- int ParserTester::TestBinOprt()
- {
- int iStat = 0;
- mu::console() << _T("testing binary operators...");
-
- // built in operators
- // xor operator
- iStat += EqnTest(_T("1 xor 2"), 3, true);
- iStat += EqnTest(_T("a xor b"), 3, true); // with a=1 and b=2
- iStat += EqnTest(_T("1 xor 2 xor 3"), 0, true);
- iStat += EqnTest(_T("a xor b xor 3"), 0, true); // with a=1 and b=2
- iStat += EqnTest(_T("a xor b xor c"), 0, true); // with a=1 and b=2
- iStat += EqnTest(_T("(1 xor 2) xor 3"), 0, true);
- iStat += EqnTest(_T("(a xor b) xor c"), 0, true); // with a=1 and b=2
- iStat += EqnTest(_T("(a) xor (b) xor c"), 0, true); // with a=1 and b=2
- iStat += EqnTest(_T("1 or 2"), 3, true);
- iStat += EqnTest(_T("a or b"), 3, true); // with a=1 and b=2
-
- // Assignement operator
- iStat += EqnTest(_T("a = b"), 2, true);
- iStat += EqnTest(_T("a = sin(b)"), 0.909297, true);
- iStat += EqnTest(_T("a = 1+sin(b)"), 1.909297, true);
-
- // Test user defined binary operators
- iStat += EqnTestInt(_T("1 | 2"), 3, true);
- iStat += EqnTestInt(_T("1 || 2"), 1, true);
- iStat += EqnTestInt(_T("123 & 456"), 72, true);
- iStat += EqnTestInt(_T("(123 & 456) % 10"), 2, true);
- iStat += EqnTestInt(_T("1 && 0"), 0, true);
- iStat += EqnTestInt(_T("123 && 456"), 1, true);
- iStat += EqnTestInt(_T("1 << 3"), 8, true);
- iStat += EqnTestInt(_T("8 >> 3"), 1, true);
- iStat += EqnTestInt(_T("10 ^ 10"), 0, true);
- iStat += EqnTestInt(_T("10 * 10 ^ 99"), 7, true);
- iStat += EqnTestInt(_T("9 / 4"), 2, true);
- iStat += EqnTestInt(_T("9 % 4"), 1, true);
- iStat += EqnTestInt(_T("if(5%2,1,0)"), 1, true);
- iStat += EqnTestInt(_T("if(4%2,1,0)"), 0, true);
- iStat += EqnTestInt(_T("-10+1"), -9, true);
- iStat += EqnTestInt(_T("1+2*3"), 7, true);
- iStat += EqnTestInt(_T("const1 != const2"), 1, true);
- iStat += EqnTestInt(_T("const1 != const2"), 0, false);
- iStat += EqnTestInt(_T("const1 == const2"), 0, true);
- iStat += EqnTestInt(_T("const1 == 1"), 1, true);
- iStat += EqnTestInt(_T("10*(const1 == 1)"), 10, true);
- iStat += EqnTestInt(_T("2*(const1 | const2)"), 6, true);
- iStat += EqnTestInt(_T("2*(const1 | const2)"), 7, false);
- iStat += EqnTestInt(_T("const1 < const2"), 1, true);
- iStat += EqnTestInt(_T("const2 > const1"), 1, true);
- iStat += EqnTestInt(_T("const1 <= 1"), 1, true);
- iStat += EqnTestInt(_T("const2 >= 2"), 1, true);
- iStat += EqnTestInt(_T("2*(const1 + const2)"), 6, true);
- iStat += EqnTestInt(_T("2*(const1 - const2)"), -2, true);
-
- iStat += EqnTestInt(_T("a != b"), 1, true);
- iStat += EqnTestInt(_T("a != b"), 0, false);
- iStat += EqnTestInt(_T("a == b"), 0, true);
- iStat += EqnTestInt(_T("a == 1"), 1, true);
- iStat += EqnTestInt(_T("10*(a == 1)"), 10, true);
- iStat += EqnTestInt(_T("2*(a | b)"), 6, true);
- iStat += EqnTestInt(_T("2*(a | b)"), 7, false);
- iStat += EqnTestInt(_T("a < b"), 1, true);
- iStat += EqnTestInt(_T("b > a"), 1, true);
- iStat += EqnTestInt(_T("a <= 1"), 1, true);
- iStat += EqnTestInt(_T("b >= 2"), 1, true);
- iStat += EqnTestInt(_T("2*(a + b)"), 6, true);
- iStat += EqnTestInt(_T("2*(a - b)"), -2, true);
- iStat += EqnTestInt(_T("a + (a << b)"), 5, true);
- iStat += EqnTestInt(_T("-2^2"), -4, true);
-// incorrect: '^' is yor here, not power
-// iStat += EqnTestInt("-(1+2)^2", -9, true);
-// iStat += EqnTestInt("-1^3", -1, true);
-
- // Test precedence
- // a=1, b=2, c=3
- iStat += EqnTestInt(_T("a + b * c"), 7, true);
- iStat += EqnTestInt(_T("a * b + c"), 5, true);
- iStat += EqnTestInt(_T("a<b && b>10"), 0, true);
- iStat += EqnTestInt(_T("a<b && b<10"), 1, true);
-
- iStat += EqnTestInt(_T("a + b << c"), 17, true);
- iStat += EqnTestInt(_T("a << b + c"), 7, true);
- iStat += EqnTestInt(_T("c * b < a"), 0, true);
- iStat += EqnTestInt(_T("c * b == 6 * a"), 1, true);
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check muParser name restriction enforcement. */
- int ParserTester::TestNames()
- {
- int iStat= 0,
- iErr = 0;
-
- mu::console() << "testing name restriction enforcement...";
-
- Parser p;
-
- #define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \
- iErr = 0; \
- ParserTester::c_iCount++; \
- try \
- { \
- p.Define##DOMAIN(EXPR, ARG); \
- } \
- catch(Parser::exception_type&) \
- { \
- iErr = (FAIL==false) ? 0 : 1; \
- } \
- iStat += iErr;
-
- // constant names
- PARSER_THROWCHECK(Const, false, _T("0a"), 1)
- PARSER_THROWCHECK(Const, false, _T("9a"), 1)
- PARSER_THROWCHECK(Const, false, _T("+a"), 1)
- PARSER_THROWCHECK(Const, false, _T("-a"), 1)
- PARSER_THROWCHECK(Const, false, _T("a-"), 1)
- PARSER_THROWCHECK(Const, false, _T("a*"), 1)
- PARSER_THROWCHECK(Const, false, _T("a?"), 1)
- PARSER_THROWCHECK(Const, true, _T("a"), 1)
- PARSER_THROWCHECK(Const, true, _T("a_min"), 1)
- PARSER_THROWCHECK(Const, true, _T("a_min0"), 1)
- PARSER_THROWCHECK(Const, true, _T("a_min9"), 1)
- // variable names
- value_type a;
- p.ClearConst();
- PARSER_THROWCHECK(Var, false, _T("123abc"), &a)
- PARSER_THROWCHECK(Var, false, _T("9a"), &a)
- PARSER_THROWCHECK(Var, false, _T("0a"), &a)
- PARSER_THROWCHECK(Var, false, _T("+a"), &a)
- PARSER_THROWCHECK(Var, false, _T("-a"), &a)
- PARSER_THROWCHECK(Var, false, _T("?a"), &a)
- PARSER_THROWCHECK(Var, false, _T("!a"), &a)
- PARSER_THROWCHECK(Var, false, _T("a+"), &a)
- PARSER_THROWCHECK(Var, false, _T("a-"), &a)
- PARSER_THROWCHECK(Var, false, _T("a*"), &a)
- PARSER_THROWCHECK(Var, false, _T("a?"), &a)
- PARSER_THROWCHECK(Var, true, _T("a"), &a)
- PARSER_THROWCHECK(Var, true, _T("a_min"), &a)
- PARSER_THROWCHECK(Var, true, _T("a_min0"), &a)
- PARSER_THROWCHECK(Var, true, _T("a_min9"), &a)
- PARSER_THROWCHECK(Var, false, _T("a_min9"), 0)
- // Postfix operators
- // fail
- PARSER_THROWCHECK(PostfixOprt, false, _T("(k"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, false, _T("9+"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, false, _T("+"), 0)
- // pass
- PARSER_THROWCHECK(PostfixOprt, true, _T("-a"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("?a"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("_"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("#"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("&&"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("||"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("&"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("|"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("++"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("--"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("?>"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("?<"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("**"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("xor"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("and"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("or"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("not"), f1of1)
- PARSER_THROWCHECK(PostfixOprt, true, _T("!"), f1of1)
- // Binary operator
- // The following must fail with builtin operators activated
- // p.EnableBuiltInOp(true); -> this is the default
- PARSER_THROWCHECK(Oprt, false, _T("+"), f1of2)
- PARSER_THROWCHECK(Oprt, false, _T("-"), f1of2)
- PARSER_THROWCHECK(Oprt, false, _T("*"), f1of2)
- PARSER_THROWCHECK(Oprt, false, _T("/"), f1of2)
- // without activated built in operators it should work
- p.EnableBuiltInOprt(false);
- PARSER_THROWCHECK(Oprt, true, _T("+"), f1of2)
- PARSER_THROWCHECK(Oprt, true, _T("-"), f1of2)
- PARSER_THROWCHECK(Oprt, true, _T("*"), f1of2)
- PARSER_THROWCHECK(Oprt, true, _T("/"), f1of2)
- #undef PARSER_THROWCHECK
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
- //---------------------------------------------------------------------------
- int ParserTester::TestSyntax()
- {
- int iStat = 0;
- mu::console() << _T("testing syntax engine...");
-
- iStat += EqnTest(_T("(1+ 2*a)"), 3, true); // Spaces within formula
- iStat += EqnTest(_T("(2+"), 0, false); // missing closing bracket
- iStat += EqnTest(_T("2++4"), 0, false); // unexpected operator
- iStat += EqnTest(_T("2+-4"), 0, false); // unexpected operator
- iStat += EqnTest(_T("(2+)"), 0, false); // unexpected closing bracket
- iStat += EqnTest(_T("--2"), 0, false); // double sign
- iStat += EqnTest(_T("ksdfj"), 0, false); // unknown token
- iStat += EqnTest(_T("()"), 0, false); // empty bracket
- iStat += EqnTest(_T("sin(cos)"), 0, false); // unexpected function
- iStat += EqnTest(_T("5t6"), 0, false); // unknown token
- iStat += EqnTest(_T("5 t 6"), 0, false); // unknown token
- iStat += EqnTest(_T("8*"), 0, false); // unexpected end of formula
- iStat += EqnTest(_T(",3"), 0, false); // unexpected comma
- iStat += EqnTest(_T("3,5"), 0, false); // unexpected comma
- iStat += EqnTest(_T("sin(8,8)"), 0, false); // too many function args
- iStat += EqnTest(_T("(7,8)"), 0, false); // too many function args
- iStat += EqnTest(_T("sin)"), 0, false); // unexpected closing bracket
- iStat += EqnTest(_T("a)"), 0, false); // unexpected closing bracket
- iStat += EqnTest(_T("pi)"), 0, false); // unexpected closing bracket
- iStat += EqnTest(_T("sin(())"), 0, false); // unexpected closing bracket
- iStat += EqnTest(_T("sin()"), 0, false); // unexpected closing bracket
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
- //---------------------------------------------------------------------------
- int ParserTester::TestVarConst()
- {
- int iStat = 0;
- mu::console() << _T("testing variable/constant name recognition...");
-
- // distinguish constants with same basename
- iStat += EqnTest( _T("const"), 1, true);
- iStat += EqnTest( _T("const1"), 2, true);
- iStat += EqnTest( _T("const2"), 3, true);
- iStat += EqnTest( _T("2*const"), 2, true);
- iStat += EqnTest( _T("2*const1"), 4, true);
- iStat += EqnTest( _T("2*const2"), 6, true);
- iStat += EqnTest( _T("2*const+1"), 3, true);
- iStat += EqnTest( _T("2*const1+1"), 5, true);
- iStat += EqnTest( _T("2*const2+1"), 7, true);
- iStat += EqnTest( _T("const"), 0, false);
- iStat += EqnTest( _T("const1"), 0, false);
- iStat += EqnTest( _T("const2"), 0, false);
-
- // distinguish variables with same basename
- iStat += EqnTest( _T("a"), 1, true);
- iStat += EqnTest( _T("aa"), 2, true);
- iStat += EqnTest( _T("2*a"), 2, true);
- iStat += EqnTest( _T("2*aa"), 4, true);
- iStat += EqnTest( _T("2*a-1"), 1, true);
- iStat += EqnTest( _T("2*aa-1"), 3, true);
-
- // Finally test querying of used variables
- try
- {
- int idx;
- mu::Parser p;
- mu::value_type vVarVal[] = { 1, 2, 3, 4, 5};
- p.DefineVar( _T("a"), &vVarVal[0]);
- p.DefineVar( _T("b"), &vVarVal[1]);
- p.DefineVar( _T("c"), &vVarVal[2]);
- p.DefineVar( _T("d"), &vVarVal[3]);
- p.DefineVar( _T("e"), &vVarVal[4]);
-
- // Test lookup of defined variables
- // 4 used variables
- p.SetExpr( _T("a+b+c+d") );
- mu::varmap_type UsedVar = p.GetUsedVar();
- int iCount = (int)UsedVar.size();
- if (iCount!=4) throw false;
-
- mu::varmap_type::const_iterator item = UsedVar.begin();
- for (idx=0; item!=UsedVar.end(); ++item)
- {
- if (&vVarVal[idx++]!=item->second)
- throw false;
- }
-
- // Test lookup of undefined variables
- p.SetExpr( _T("undef1+undef2+undef3") );
- UsedVar = p.GetUsedVar();
- iCount = (int)UsedVar.size();
- if (iCount!=3) throw false;
-
- for (item = UsedVar.begin(); item!=UsedVar.end(); ++item)
- {
- if (item->second!=0)
- throw false; // all pointers to undefined variables must be null
- }
-
- // 1 used variables
- p.SetExpr( _T("a+b") );
- UsedVar = p.GetUsedVar();
- iCount = (int)UsedVar.size();
- if (iCount!=2) throw false;
- item = UsedVar.begin();
- for (idx=0; item!=UsedVar.end(); ++item)
- if (&vVarVal[idx++]!=item->second) throw false;
-
- }
- catch(...)
- {
- iStat += 1;
- }
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
- //---------------------------------------------------------------------------
- int ParserTester::TestMultiArg()
- {
- int iStat = 0;
- mu::console() << _T("testing multiarg functions...");
-
- // picking the right argument
- iStat += EqnTest( _T("f1of1(1)"), 1, true);
- iStat += EqnTest( _T("f1of2(1, 2)"), 1, true);
- iStat += EqnTest( _T("f2of2(1, 2)"), 2, true);
- iStat += EqnTest( _T("f1of3(1, 2, 3)"), 1, true);
- iStat += EqnTest( _T("f2of3(1, 2, 3)"), 2, true);
- iStat += EqnTest( _T("f3of3(1, 2, 3)"), 3, true);
- iStat += EqnTest( _T("f1of4(1, 2, 3, 4)"), 1, true);
- iStat += EqnTest( _T("f2of4(1, 2, 3, 4)"), 2, true);
- iStat += EqnTest( _T("f3of4(1, 2, 3, 4)"), 3, true);
- iStat += EqnTest( _T("f4of4(1, 2, 3, 4)"), 4, true);
- iStat += EqnTest( _T("f1of5(1, 2, 3, 4, 5)"), 1, true);
- iStat += EqnTest( _T("f2of5(1, 2, 3, 4, 5)"), 2, true);
- iStat += EqnTest( _T("f3of5(1, 2, 3, 4, 5)"), 3, true);
- iStat += EqnTest( _T("f4of5(1, 2, 3, 4, 5)"), 4, true);
- iStat += EqnTest( _T("f5of5(1, 2, 3, 4, 5)"), 5, true);
- // Too few arguments / Too many arguments
- iStat += EqnTest( _T("f1of1(1,2)"), 0, false);
- iStat += EqnTest( _T("f1of1()"), 0, false);
- iStat += EqnTest( _T("f1of2(1, 2, 3)"), 0, false);
- iStat += EqnTest( _T("f1of2(1)"), 0, false);
- iStat += EqnTest( _T("f1of3(1, 2, 3, 4)"), 0, false);
- iStat += EqnTest( _T("f1of3(1)"), 0, false);
- iStat += EqnTest( _T("f1of4(1, 2, 3, 4, 5)"), 0, false);
- iStat += EqnTest( _T("f1of4(1)"), 0, false);
- iStat += EqnTest( _T("(1,2,3)"), 0, false);
- iStat += EqnTest( _T("1,2,3"), 0, false);
- iStat += EqnTest( _T("(1*a,2,3)"), 0, false);
- iStat += EqnTest( _T("1,2*a,3"), 0, false);
-
- // correct calculation of arguments
- iStat += EqnTest( _T("min(a, 1)"), 1, true);
- iStat += EqnTest( _T("min(3*2, 1)"), 1, true);
- iStat += EqnTest( _T("min(3*2, 1)"), 6, false);
- // correct calculation of arguments
- iStat += EqnTest( _T("min(3*a+1, 1)"), 1, true);
- iStat += EqnTest( _T("max(3*a+1, 1)"), 4, true);
- iStat += EqnTest( _T("max(3*a+1, 1)*2"), 8, true);
- iStat += EqnTest( _T("2*max(3*a+1, 1)+2"), 10, true);
-
- // functions with Variable argument count
- iStat += EqnTest( _T("sum(1,2,3)"), 6, true);
- iStat += EqnTest( _T("2*sum(1,2,3)"), 12, true);
- iStat += EqnTest( _T("2*sum(1,2,3)+2"), 14, true);
- iStat += EqnTest( _T("2*sum(-1,2,3)+2"), 10, true);
- iStat += EqnTest( _T("2*sum(-1,2,-(-a))+2"), 6, true);
- iStat += EqnTest( _T("2*sum(-1,10,-a)+2"), 18, true);
- iStat += EqnTest( _T("2*sum(1,2,3)*2"), 24, true);
- iStat += EqnTest( _T("sum(1,-max(1,2),3)*2"), 4, true);
- iStat += EqnTest( _T("sum(1*3, 4, a+2)"), 10, true);
- iStat += EqnTest( _T("sum(1*3, 2*sum(1,2,2), a+2)"), 16, true);
- iStat += EqnTest( _T("sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)"), 24, true);
-
- // some failures
- iStat += EqnTest( _T("sum()"), 0, false);
- iStat += EqnTest( _T("sum(,)"), 0, false);
- iStat += EqnTest( _T("sum(1,2,)"), 0, false);
- iStat += EqnTest( _T("sum(,1,2)"), 0, false);
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
-
- //---------------------------------------------------------------------------
- int ParserTester::TestInfixOprt()
- {
- int iStat = 0;
- mu::console() << "testing infix operators...";
-
- iStat += EqnTest( _T("-1"), -1, true);
- iStat += EqnTest( _T("-(-1)"), 1, true);
- iStat += EqnTest( _T("-(-1)*2"), 2, true);
- iStat += EqnTest( _T("-(-2)*sqrt(4)"), 4, true);
- iStat += EqnTest( _T("-a"), -1, true);
- iStat += EqnTest( _T("-(a)"), -1, true);
- iStat += EqnTest( _T("-(-a)"), 1, true);
- iStat += EqnTest( _T("-(-a)*2"), 2, true);
- iStat += EqnTest( _T("-(8)"), -8, true);
- iStat += EqnTest( _T("-8"), -8, true);
- iStat += EqnTest( _T("-(2+1)"), -3, true);
- iStat += EqnTest( _T("-(f1of1(1+2*3)+1*2)"), -9, true);
- iStat += EqnTest( _T("-(-f1of1(1+2*3)+1*2)"), 5, true);
- iStat += EqnTest( _T("-sin(8)"), -0.989358, true);
- iStat += EqnTest( _T("3-(-a)"), 4, true);
- iStat += EqnTest( _T("3--a"), 4, true);
-
- // Postfix / infix priorities
- iStat += EqnTest( _T("~2#"), 8, true);
- iStat += EqnTest( _T("~f1of1(2)#"), 8, true);
- iStat += EqnTest( _T("~(b)#"), 8, true);
- iStat += EqnTest( _T("(~b)#"), 12, true);
- iStat += EqnTest( _T("~(2#)"), 8, true);
- iStat += EqnTest( _T("~(f1of1(2)#)"), 8, true);
- //
- iStat += EqnTest( _T("-2^2"),-4, true);
- iStat += EqnTest( _T("-(a+b)^2"),-9, true);
- iStat += EqnTest( _T("(-3)^2"),9, true);
- iStat += EqnTest( _T("-(-2^2)"),4, true);
- iStat += EqnTest( _T("3+-3^2"),-6, true);
- // The following assumes use of sqr as postfix operator ("?") together
- // tiwth a sign operator of low priority:
- iStat += EqnTest( _T("-2?"), -4, true);
- iStat += EqnTest( _T("-(1+1)?"),-4, true);
- iStat += EqnTest( _T("2+-(1+1)?"),-2, true);
- iStat += EqnTest( _T("2+-2?"), -2, true);
- // This is the classic behaviour of the infix sign operator (here: "$") which is
- // now deprecated:
- iStat += EqnTest( _T("$2^2"),4, true);
- iStat += EqnTest( _T("$(a+b)^2"),9, true);
- iStat += EqnTest( _T("($3)^2"),9, true);
- iStat += EqnTest( _T("$($2^2)"),-4, true);
- iStat += EqnTest( _T("3+$3^2"),12, true);
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
-
- //---------------------------------------------------------------------------
- int ParserTester::TestPostFix()
- {
- int iStat = 0;
- mu::console() << _T("testing postfix operators...");
-
- // application
- iStat += EqnTest( _T("3m+5"), 5.003, true);
- iStat += EqnTest( _T("1000m"), 1, true);
- iStat += EqnTest( _T("1000 m"), 1, true);
- iStat += EqnTest( _T("(a)m"), 1e-3, true);
- iStat += EqnTest( _T("-(a)m"), -1e-3, true);
- iStat += EqnTest( _T("-2m"), -2e-3, true);
- iStat += EqnTest( _T("f1of1(1000)m"), 1, true);
- iStat += EqnTest( _T("-f1of1(1000)m"), -1, true);
- iStat += EqnTest( _T("-f1of1(-1000)m"), 1, true);
- iStat += EqnTest( _T("f4of4(0,0,0,1000)m"), 1, true);
- iStat += EqnTest( _T("2+(a*1000)m"), 3, true);
- // some incorrect results
- iStat += EqnTest( _T("1000m"), 0.1, false);
- iStat += EqnTest( _T("(a)m"), 2, false);
- // failure due to syntax checking
- iStat += EqnTest( _T("a m"), 0, false);
- iStat += EqnTest( _T("4 + m"), 0, false);
- iStat += EqnTest( _T("m4"), 0, false);
- iStat += EqnTest( _T("sin(m)"), 0, false);
- iStat += EqnTest( _T("m m"), 0, false);
- iStat += EqnTest( _T("m(8)"), 0, false);
- iStat += EqnTest( _T("4,m"), 0, false);
- iStat += EqnTest( _T("-m"), 0, false);
- iStat += EqnTest( _T("2(-m)"), 0, false);
- iStat += EqnTest( _T("2(m)"), 0, false);
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Test volatile (nonoptimizeable functions). */
- int ParserTester::TestVolatile()
- {
- int iStat = 0;
- mu::console() << "testing volatile/nonvolatile functions...";
-
- // First test with volatile flag turned on
- try
- {
- mu::Parser p;
- p.DefineFun( _T("rnd"), Rnd, false);
- p.DefineFun( _T("valueof"), RndWithString, false);
-
- // 1st test, compare results from sucessive calculations
- p.SetExpr( _T("3+rnd(8)") );
- if (p.Eval()==p.Eval()) iStat += 1;
-
- // 2nd test, force bytecode creation, compare two results both
- // calculated from bytecode
- p.SetExpr( _T("3+rnd(8)") );
- p.Eval(); //<- Force bytecode creation
- if (p.Eval()==p.Eval()) iStat += 1;
-
- p.SetExpr( _T("3*rnd(8)+3") );
- p.Eval(); //<- Force bytecode creation
- if (p.Eval()==p.Eval()) iStat += 1;
-
- p.SetExpr( _T("10+3*sin(rnd(8))-1") );
- p.Eval(); //<- Force bytecode creation
- if (p.Eval()==p.Eval()) iStat += 1;
-
- p.SetExpr( _T("3+rnd(rnd(8))*2") );
- p.Eval(); //<- Force bytecode creation
- if (p.Eval()==p.Eval()) iStat += 1;
-
- p.SetExpr( _T("valueof(\"Das ist ein Test\")") );
- p.Eval(); //<- Force bytecode creation
- if (p.Eval()==p.Eval()) iStat += 1;
- }
- catch(Parser::exception_type &e)
- {
- mu::console() << _T("\n ") << e.GetExpr() << _T(" : ") << e.GetMsg();
- iStat += 1;
- }
-
- // Second test with volatile flag turned off
- try
- {
- mu::Parser p;
- p.DefineFun( _T("rnd"), Rnd);
- p.DefineFun( _T("valueof"), RndWithString);
-
- // compare string parsing with bytecode
- p.SetExpr( _T("3+rnd(8)") );
- if (p.Eval()!=p.Eval()) iStat += 1;
-
- p.SetExpr( _T("3+rnd(8)") );
- p.Eval(); //<- Force bytecode creation
- if (p.Eval()!=p.Eval()) iStat += 1;
-
- p.SetExpr( _T("3*rnd(8)+3") );
- p.Eval(); //<- Force bytecode creation
- if (p.Eval()!=p.Eval()) iStat += 1;
-
- p.SetExpr( _T("10+3*sin(rnd(8))-1") );
- p.Eval(); //<- Force bytecode creation
- if (p.Eval()!=p.Eval()) iStat += 1;
-
- p.SetExpr( _T("3+rnd(rnd(8))*2") );
- p.Eval(); //<- Force bytecode creation
- if (p.Eval()!=p.Eval()) iStat += 1;
- }
- catch(Parser::exception_type &e)
- {
- mu::console() << _T("\n ") << e.GetExpr() << _T(" : ") << e.GetMsg();
- iStat += 1;
- }
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
- //---------------------------------------------------------------------------
- int ParserTester::TestFormula()
- {
- int iStat = 0;
- mu::console() << _T("testing sample formulas...");
-
- // operator precedencs
- iStat += EqnTest( _T("1+2-3*4/5^6"), 2.99923, true);
- iStat += EqnTest( _T("1^2/3*4-5+6"), 2.3333, true);
- iStat += EqnTest( _T("1+2*3"), 7, true);
- iStat += EqnTest( _T("1+2*3"), 7, true);
- iStat += EqnTest( _T("(1+2)*3"), 9, true);
- iStat += EqnTest( _T("(1+2)*(-3)"), -9, true);
- iStat += EqnTest( _T("2/4"), 0.5, true);
-
- iStat += EqnTest( _T("exp(ln(7))"), 7, true);
- iStat += EqnTest( _T("e^ln(7)"), 7, true);
- iStat += EqnTest( _T("e^(ln(7))"), 7, true);
- iStat += EqnTest( _T("(e^(ln(7)))"), 7, true);
- iStat += EqnTest( _T("1-(e^(ln(7)))"), -6, true);
- iStat += EqnTest( _T("2*(e^(ln(7)))"), 14, true);
- iStat += EqnTest( _T("10^log(5)"), 5, true);
- iStat += EqnTest( _T("10^log10(5)"), 5, true);
- iStat += EqnTest( _T("2^log2(4)"), 4, true);
- iStat += EqnTest( _T("-(sin(0)+1)"), -1, true);
- iStat += EqnTest( _T("-(2^1.1)"), -2.14354692, true);
-
- iStat += EqnTest( _T("(cos(2.41)/b)"), -0.372056, true);
-
-#if !defined(_UNICODE)
- // I can't translate the following two tests to unicode without loosing
- // readability.
-
- // long formula (Reference: Matlab)
- iStat += EqnTest(
- "(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))"
- "/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/"
- "((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-"
- "e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6"
- "+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e"
- "*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)", -12.23016549, true);
-
- // long formula (Reference: Matlab)
- iStat += EqnTest(
- "(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e"
- ")+a)))*2.77)", -2.16995656, true);
-#endif
-
- // long formula (Reference: Matlab)
- iStat += EqnTest( _T("1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"), -7995810.09926, true);
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
-
- //---------------------------------------------------------------------------
- int ParserTester::TestException()
- {
- int iStat = 0;
- mu::console() << _T("testing error codes...");
-
- iStat += ThrowTest(_T("3+"), ecUNEXPECTED_EOF);
- iStat += ThrowTest(_T("3+)"), ecUNEXPECTED_PARENS);
- iStat += ThrowTest(_T("sin(3,4)"), ecTOO_MANY_PARAMS);
- iStat += ThrowTest(_T("3,4"), ecUNEXPECTED_COMMA);
- iStat += ThrowTest(_T("if(3)"), ecTOO_FEW_PARAMS);
- iStat += ThrowTest(_T("(1+2"), ecMISSING_PARENS);
- iStat += ThrowTest(_T("sin(3)3"), ecUNEXPECTED_VAL);
- iStat += ThrowTest(_T("sin(3)xyz"), ecUNASSIGNABLE_TOKEN);
- iStat += ThrowTest(_T("sin(3)cos(3)"), ecUNEXPECTED_FUN);
-
- // String function related
- iStat += ThrowTest( _T("valueof(\"xxx\")"), 999, false);
- iStat += ThrowTest( _T("valueof()"), ecUNEXPECTED_PARENS);
- iStat += ThrowTest( _T("1+valueof(\"abc\""), ecMISSING_PARENS);
- iStat += ThrowTest( _T("valueof(\"abc\""), ecMISSING_PARENS);
- iStat += ThrowTest( _T("valueof(\"abc"), ecUNTERMINATED_STRING);
- iStat += ThrowTest( _T("valueof(\"abc\",3)"), ecTOO_MANY_PARAMS);
- iStat += ThrowTest( _T("valueof(3)"), ecSTRING_EXPECTED);
- iStat += ThrowTest( _T("sin(\"abc\")"), ecVAL_EXPECTED);
- iStat += ThrowTest( _T("valueof(\"\\\"abc\\\"\")"), 999, false);
- iStat += ThrowTest( _T("\"hello world\""), ecSTR_RESULT);
- iStat += ThrowTest( _T("(\"hello world\")"), ecSTR_RESULT);
- iStat += ThrowTest( _T("\"abcd\"+100"), ecOPRT_TYPE_CONFLICT);
- iStat += ThrowTest( _T("\"a\"+\"b\""), ecOPRT_TYPE_CONFLICT);
- iStat += ThrowTest( _T("strfun1(\"100\",3)"), ecTOO_MANY_PARAMS);
- iStat += ThrowTest( _T("strfun2(\"100\",3,5)"), ecTOO_MANY_PARAMS);
- iStat += ThrowTest( _T("strfun3(\"100\",3,5,6)"), ecTOO_MANY_PARAMS);
- iStat += ThrowTest( _T("strfun2(\"100\")"), ecTOO_FEW_PARAMS);
- iStat += ThrowTest( _T("strfun3(\"100\",6)"), ecTOO_FEW_PARAMS);
- iStat += ThrowTest( _T("strfun2(1,1)"), ecSTRING_EXPECTED);
- iStat += ThrowTest( _T("strfun2(a,1)"), ecSTRING_EXPECTED);
- iStat += ThrowTest( _T("strfun2(1,1,1)"), ecTOO_MANY_PARAMS);
- iStat += ThrowTest( _T("strfun2(a,1,1)"), ecTOO_MANY_PARAMS);
- iStat += ThrowTest( _T("strfun3(1,2,3)"), ecSTRING_EXPECTED);
- iStat += ThrowTest( _T("strfun3(1, \"100\",3)"), ecSTRING_EXPECTED);
- iStat += ThrowTest( _T("strfun3(\"1\", \"100\",3)"), ecVAL_EXPECTED);
- iStat += ThrowTest( _T("strfun3(\"1\", 3, \"100\")"), ecVAL_EXPECTED);
- iStat += ThrowTest( _T("strfun3(\"1\", \"100\", \"100\", \"100\")"), ecTOO_MANY_PARAMS);
-
- // assignement operator
-// iStat += ThrowTest("maxspec=0", 0, false);
- iStat += ThrowTest( _T("3=4"), ecUNEXPECTED_OPERATOR);
- iStat += ThrowTest( _T("sin(8)=4"), ecUNEXPECTED_OPERATOR);
- iStat += ThrowTest( _T("\"test\"=a"), ecUNEXPECTED_OPERATOR);
- iStat += ThrowTest( _T("sin=9"), ecUNEXPECTED_OPERATOR);
- iStat += ThrowTest( _T("(8)=5"), ecUNEXPECTED_OPERATOR);
- iStat += ThrowTest( _T("(a)=5"), ecUNEXPECTED_OPERATOR);
- iStat += ThrowTest( _T("a=\"tttt\""), ecOPRT_TYPE_CONFLICT);
-
- if (iStat==0)
- mu::console() << _T("passed") << endl;
- else
- mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;
-
- return iStat;
- }
-
-
- //---------------------------------------------------------------------------
- void ParserTester::AddTest(testfun_type a_pFun)
- {
- m_vTestFun.push_back(a_pFun);
- }
-
- //---------------------------------------------------------------------------
- void ParserTester::Run()
- {
- int iStat = 0;
- try
- {
- for (int i=0; i<(int)m_vTestFun.size(); ++i)
- iStat += (this->*m_vTestFun[i])();
- }
- catch(Parser::exception_type &e)
- {
- mu::console() << "\n" << e.GetMsg() << endl;
- mu::console() << e.GetToken() << endl;
- Abort();
- }
- catch(std::exception &e)
- {
- mu::console() << e.what() << endl;
- Abort();
- }
- catch(...)
- {
- mu::console() << "Internal error";
- Abort();
- }
-
- if (iStat==0)
- {
- mu::console() << "Test passed (" << ParserTester::c_iCount << " expressions)" << endl;
- }
- else
- {
- mu::console() << "Test failed with " << iStat
- << " errors (" << ParserTester::c_iCount
- << " expressions)" << endl;
- }
- ParserTester::c_iCount = 0;
- }
-
-
- //---------------------------------------------------------------------------
- int ParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail)
- {
- ParserTester::c_iCount++;
-
- try
- {
- double fVal=0;
- Parser p;
-
- p.DefineVar( _T("a"), &fVal);
- p.DefineFun( _T("valueof"), ValueOf);
- p.DefineFun( _T("strfun1"), StrFun1);
- p.DefineFun( _T("strfun2"), StrFun2);
- p.DefineFun( _T("strfun3"), StrFun3);
- p.SetExpr(a_str);
- p.Eval();
- }
- catch(Parser::exception_type &e)
- {
- // output the formula in case of an failed test
- if (a_bFail==true && a_iErrc!=e.GetCode() )
- {
- mu::console() << _T("\n ")
- << _T("Expression: ") << a_str
- << _T(" Code:") << e.GetCode()
- << _T(" Expected:") << a_iErrc;
- }
-
- return (a_iErrc==e.GetCode()) ? 0 : 1;
- }
-
- // if a_bFail==false no exception is expected
- bool bRet((a_bFail==false) ? 0 : 1);
- if (bRet==1)
- {
- mu::console() << _T("\n ")
- << _T("Expression: ") << a_str
- << _T(" did evaluate; Expected error:") << a_iErrc;
- }
-
- return bRet;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Evaluate a tet expression.
-
- \return 1 in case of a failure, 0 otherwise.
- */
- int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
- {
- ParserTester::c_iCount++;
- int iRet(0);
-
- try
- {
- Parser *p1, p2, p3; // three parser objects
- // they will be used for testing copy and assihnment operators
- // p1 is a pointer since i'm going to delete it in order to test if
- // parsers after copy construction still refer to members of it.
- // !! If this is the case this function will crash !!
-
- p1 = new mu::Parser();
- // Add constants
- p1->DefineConst( _T("pi"), (value_type)PARSER_CONST_PI);
- p1->DefineConst( _T("e"), (value_type)PARSER_CONST_E);
- p1->DefineConst( _T("const"), 1);
- p1->DefineConst( _T("const1"), 2);
- p1->DefineConst( _T("const2"), 3);
- // variables
- value_type vVarVal[] = { 1, 2, 3, -2};
- p1->DefineVar( _T("a"), &vVarVal[0]);
- p1->DefineVar( _T("aa"), &vVarVal[1]);
- p1->DefineVar( _T("b"), &vVarVal[1]);
- p1->DefineVar( _T("c"), &vVarVal[2]);
- p1->DefineVar( _T("d"), &vVarVal[3]);
- // functions
- p1->DefineFun( _T("f1of1"), f1of1); // one parameter
- p1->DefineFun( _T("f1of2"), f1of2); // two parameter
- p1->DefineFun( _T("f2of2"), f2of2);
- p1->DefineFun( _T("f1of3"), f1of3); // three parameter
- p1->DefineFun( _T("f2of3"), f2of3);
- p1->DefineFun( _T("f3of3"), f3of3);
- p1->DefineFun( _T("f1of4"), f1of4); // four parameter
- p1->DefineFun( _T("f2of4"), f2of4);
- p1->DefineFun( _T("f3of4"), f3of4);
- p1->DefineFun( _T("f4of4"), f4of4);
- p1->DefineFun( _T("f1of5"), f1of5); // five parameter
- p1->DefineFun( _T("f2of5"), f2of5);
- p1->DefineFun( _T("f3of5"), f3of5);
- p1->DefineFun( _T("f4of5"), f4of5);
- p1->DefineFun( _T("f5of5"), f5of5);
- // sample functions
- p1->DefineFun( _T("min"), Min);
- p1->DefineFun( _T("max"), Max);
- p1->DefineFun( _T("sum"), Sum);
- p1->DefineFun( _T("valueof"), ValueOf);
- p1->DefineFun( _T("atof"), StrToFloat);
- p1->DefineFun( _T("strfun1"), StrFun1);
- p1->DefineFun( _T("strfun2"), StrFun2);
- p1->DefineFun( _T("strfun3"), StrFun3);
-
- // infix / postfix operator
- // (identifiers used here do not have any meaning or make any sense at all)
- p1->DefineInfixOprt( _T("$"), sign, prPOW+1); // sign with high priority
- p1->DefineInfixOprt( _T("~"), plus2); // high priority
- p1->DefinePostfixOprt( _T("m"), Milli);
- p1->DefinePostfixOprt( _T("#"), times3);
- p1->DefinePostfixOprt( _T("?"), sqr); //
- p1->SetExpr(a_str);
-
- // Test bytecode integrity
- // String parsing and bytecode parsing must yield the same result
- value_type fVal[4] = {-999, -998, -997, -996}; // initially should be different
- fVal[0] = p1->Eval(); // result from stringparsing
- fVal[1] = p1->Eval(); // result from bytecode
- if (fVal[0]!=fVal[1])
- throw Parser::exception_type( _T("Bytecode corrupt.") );
-
- // Test copy and assignement operators
- try
- {
- // Test copy constructor
- std::vector<mu::Parser> vParser;
- vParser.push_back(*p1);
- mu::Parser p2 = vParser[0]; // take parser from vector
-
- // destroy the originals from p2
- vParser.clear(); // delete the vector
- delete p1; // delete the original
- p1 = 0;
-
- fVal[2] = p2.Eval();
-
- // Test assignement operator
- // additionally disable Optimizer this time
- mu::Parser p3;
- p3 = p2;
- p3.EnableOptimizer(false);
- fVal[3] = p3.Eval();
- }
- catch(std::exception &e)
- {
- mu::console() << _T("\n ") << e.what() << _T("\n");
- }
-
- // limited floating point accuracy requires the following test
- bool bCloseEnough(true);
- for (int i=0; i<4; ++i)
- {
- bCloseEnough &= (fabs(a_fRes-fVal[i]) <= fabs(fVal[i]*0.0001));
- }
-
- iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;
- if (iRet==1)
- {
- mu::console() << "\n fail: " << a_str.c_str()
- << " (incorrect result; expected: " << a_fRes
- << " ;calculated: " << fVal[0]<< ").";
- }
- }
- catch(Parser::exception_type &e)
- {
- if (a_fPass)
- {
- mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")");
- return 1;
- }
- }
- catch(std::exception &e)
- {
- mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.what() << _T(")");
- return 1; // always return a failure since this exception is not expected
- }
- catch(...)
- {
- mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (unexpected exception)");
- return 1; // exceptions other than ParserException are not allowed
- }
-
- return iRet;
- }
-
- //---------------------------------------------------------------------------
- int ParserTester::EqnTestInt(const string_type &a_str, double a_fRes, bool a_fPass)
- {
- ParserTester::c_iCount++;
-
- value_type vVarVal[] = {1, 2, 3}; // variable values
- value_type fVal[2] = {-99, -999}; // results: initially should be different
- int iRet(0);
-
- try
- {
- ParserInt p;
- p.DefineConst( _T("const1"), 1);
- p.DefineConst( _T("const2"), 2);
- p.DefineVar( _T("a"), &vVarVal[0]);
- p.DefineVar( _T("b"), &vVarVal[1]);
- p.DefineVar( _T("c"), &vVarVal[2]);
-
- p.SetExpr(a_str);
- fVal[0] = p.Eval(); // result from stringparsing
- fVal[1] = p.Eval(); // result from bytecode
-
- if (fVal[0]!=fVal[1])
- throw Parser::exception_type( _T("Bytecode corrupt.") );
-
- iRet = ( (a_fRes==fVal[0] && a_fPass) ||
- (a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1;
- if (iRet==1)
- {
- mu::console() << _T("\n fail: ") << a_str.c_str()
- << _T(" (incorrect result; expected: ") << a_fRes
- << _T(" ;calculated: ") << fVal[0]<< _T(").");
- }
- }
- catch(Parser::exception_type &e)
- {
- if (a_fPass)
- mu::console() << _T("\n ") << e.GetExpr() << _T(" : ") << e.GetMsg();
- }
- catch(...)
- {
- mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)";
- return 1; // exceptions other than ParserException are not allowed
- }
-
- return iRet;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Internal error in test class Test is going to be aborted. */
- void ParserTester::Abort() const
- {
- mu::console() << _T("Test failed (internal error in test class)") << endl;
- while (!getchar());
- exit(-1);
- }
- } // namespace test
-} // namespace mu
-
-
-
diff --git a/muparser/muParserTest.h b/muparser/muParserTest.h deleted file mode 100644 index fe9bfdd..0000000 --- a/muparser/muParserTest.h +++ /dev/null @@ -1,176 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef MU_PARSER_TEST_H
-#define MU_PARSER_TEST_H
-
-#include <string>
-#include <numeric> // for accumulate
-#include "muParser.h"
-#include "muParserInt.h"
-
-
-namespace mu
-{
- /** \brief Namespace for test cases. */
- namespace Test
- {
- //------------------------------------------------------------------------------
- /** \brief Test cases for unit testing.
-
- (C) 2004-2006 Ingo Berg
- */
- class ParserTester // final
- {
- private:
- // Multiarg callbacks
- static value_type f1of1(value_type v) { return v;};
-
- static value_type f1of2(value_type v, value_type ) {return v;};
- static value_type f2of2(value_type , value_type v) {return v;};
-
- static value_type f1of3(value_type v, value_type , value_type ) {return v;};
- static value_type f2of3(value_type , value_type v, value_type ) {return v;};
- static value_type f3of3(value_type , value_type , value_type v) {return v;};
-
- static value_type f1of4(value_type v, value_type, value_type , value_type ) {return v;}
- static value_type f2of4(value_type , value_type v, value_type , value_type ) {return v;}
- static value_type f3of4(value_type , value_type, value_type v, value_type ) {return v;}
- static value_type f4of4(value_type , value_type, value_type , value_type v) {return v;}
-
- static value_type f1of5(value_type v, value_type, value_type , value_type , value_type ) { return v; }
- static value_type f2of5(value_type , value_type v, value_type , value_type , value_type ) { return v; }
- static value_type f3of5(value_type , value_type, value_type v, value_type , value_type ) { return v; }
- static value_type f4of5(value_type , value_type, value_type , value_type v, value_type ) { return v; }
- static value_type f5of5(value_type , value_type, value_type , value_type , value_type v) { return v; }
-
- static value_type Min(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1<a_fVal2) ? a_fVal1 : a_fVal2; }
- static value_type Max(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1>a_fVal2) ? a_fVal1 : a_fVal2; }
-
- static value_type plus2(value_type v1) { return v1+2; }
- static value_type times3(value_type v1) { return v1*3; }
- static value_type sqr(value_type v1) { return v1*v1; }
-
- static value_type sign(value_type v) { return -v; }
-
- static value_type Sum(const value_type* a_afArg, int a_iArgc)
- {
- if (!a_iArgc)
- throw mu::Parser::exception_type( _T("too few arguments for function sum.") );
-
- value_type fRes=0;
- for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
- return fRes;
- }
-
- static value_type Rnd(value_type v)
- {
- return (value_type)(1+(v*std::rand()/(RAND_MAX+1.0)));
- }
-
- static value_type RndWithString(const char_type*)
- {
- return (value_type)( 1 + (1000.0f * std::rand() / (RAND_MAX + 1.0) ) );
- }
-
- static value_type ValueOf(const char_type*)
- {
- return 123;
- }
-
- static value_type StrFun1(const char_type* v1)
- {
- int val(0);
- stringstream_type(v1) >> val;
- return val;
- }
-
- static value_type StrFun2(const char_type* v1, value_type v2)
- {
- int val(0);
- stringstream_type(v1) >> val;
- return val + v2;
- }
-
- static value_type StrFun3(const char_type* v1, value_type v2, value_type v3)
- {
- int val(0);
- stringstream_type(v1) >> val;
- return val + v2 + v3;
- }
-
- static value_type StrToFloat(const char_type* a_szMsg)
- {
- double val(0);
- stringstream_type(a_szMsg) >> val;
- return val;
-
-// using namespace std; // atof is for some compilers in std for some not...
-// return atof(a_szMsg);
- }
-
- // postfix operator callback
- static value_type Milli(value_type v) { return v/(value_type)1e3; }
-
- static int c_iCount;
-
- int TestNames();
- int TestSyntax();
- int TestMultiArg();
- int TestVolatile();
- int TestPostFix();
- int TestFormula();
- int TestInfixOprt();
- int TestBinOprt();
- int TestVarConst();
- int TestInterface();
- int TestException();
- int TestStrArg();
-
- void Abort() const;
-
- public:
- typedef int (ParserTester::*testfun_type)();
-
- ParserTester();
- void Run();
-
- private:
- std::vector<testfun_type> m_vTestFun;
- void AddTest(testfun_type a_pFun);
-
- // Test Double Parser
- int EqnTest(const string_type& a_str, double a_fRes, bool a_fPass);
- int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true);
-
- // Test Int Parser
- int EqnTestInt(const string_type& a_str, double a_fRes, bool a_fPass);
- };
- } // namespace Test
-} // namespace mu
-
-#endif
-
-
diff --git a/muparser/muParserToken.h b/muparser/muParserToken.h deleted file mode 100644 index b4c7e54..0000000 --- a/muparser/muParserToken.h +++ /dev/null @@ -1,464 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef MU_PARSER_TOKEN_H
-#define MU_PARSER_TOKEN_H
-
-#include <cassert>
-#include <string>
-#include <stack>
-#include <vector>
-#include <memory>
-
-#include "muParserError.h"
-#include "muParserCallback.h"
-
-
-namespace mu
-{
-
-/** \brief Encapsulation of the data for a single formula token.
-
- Formula token implementation. Part of the Math Parser Package.
- Formula tokens can be either one of the following:
- <ul>
- <li>value</li>
- <li>variable</li>
- <li>function with numerical arguments</li>
- <li>functions with a string as argument</li>
- <li>prefix operators</li>
- <li>infix operators</li>
- <li>binary operator</li>
- </ul>
-
- \author (C) 2004 Ingo Berg
-*/
-template<typename TBase, typename TString>
-class ParserToken
-{
-public:
- /** \brief Additional token flags. */
- enum ETokFlags
- {
- flVOLATILE = 1 ///< Mark a token that depends on a variable or a function that is not conservative
- };
-
-private:
- ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode.
- ETypeCode m_iType;
- void *m_pTok; ///< Stores Token pointer; not applicable for all tokens
- int m_iFlags; ///< Additional flags for the token.
- int m_iIdx; ///< An otional index to an external buffer storing the token data
- TString m_strTok; ///< Token string
- TString m_strVal; ///< Value for string variables
- value_type m_fVal;
- std::auto_ptr<ParserCallback> m_pCallback;
-
-public:
-
- //---------------------------------------------------------------------------
- /** \brief Constructor (default).
-
- Sets token to an neutral state of type cmUNKNOWN.
- \throw nothrow
- \sa ECmdCode
- */
- ParserToken()
- :m_iCode(cmUNKNOWN)
- ,m_iType(tpVOID)
- ,m_pTok(0)
- ,m_iFlags(0)
- ,m_iIdx(-1)
- ,m_strTok()
- ,m_pCallback()
- {}
-
- //------------------------------------------------------------------------------
- /** \brief Create token from another one.
-
- Implemented by calling Assign(...)
- \throw nothrow
- \post m_iType==cmUNKNOWN
- \sa #Assign
- */
- ParserToken(const ParserToken &a_Tok)
- {
- Assign(a_Tok);
- }
-
- //------------------------------------------------------------------------------
- /** \brief Assignement operator.
-
- Copy token state from another token and return this.
- Implemented by calling Assign(...).
- \throw nothrow
- */
- ParserToken& operator=(const ParserToken &a_Tok)
- {
- Assign(a_Tok);
- return *this;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Copy token information from argument.
-
- \throw nothrow
- */
- void Assign(const ParserToken &a_Tok)
- {
- m_iCode = a_Tok.m_iCode;
- m_pTok = a_Tok.m_pTok;
- m_iFlags = a_Tok.m_iFlags;
- m_strTok = a_Tok.m_strTok;
- m_iIdx = a_Tok.m_iIdx;
- m_strVal = a_Tok.m_strVal;
- m_iType = a_Tok.m_iType;
- m_fVal = a_Tok.m_fVal;
- // create new callback object if a_Tok has one
- m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0);
- }
-
- //------------------------------------------------------------------------------
- /** \brief Add additional flags to the token.
-
- Flags are currently used to mark volatile (non optimizeable) functions.
- \sa m_iFlags, ETokFlags
- */
- void AddFlags(int a_iFlags)
- {
- m_iFlags |= a_iFlags;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Check if a certain flag ist set.
-
- \throw nothrow
- */
- bool IsFlagSet(int a_iFlags) const
- {
- #if defined(_MSC_VER)
- #pragma warning( disable : 4800 )
- #endif
-
- return (bool)(m_iFlags & a_iFlags);
-
- #if defined(_MSC_VER)
- #pragma warning( default : 4800 ) // int: Variable set to boolean value (may degrade performance)
- #endif
- }
-
- //------------------------------------------------------------------------------
- /** \brief Assign a token type.
-
- Token may not be of type value, variable or function. Those have seperate set functions.
-
- \pre [assert] a_iType!=cmVAR
- \pre [assert] a_iType!=cmVAL
- \pre [assert] a_iType!=cmFUNC
- \post m_fVal = 0
- \post m_pTok = 0
- */
- ParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString())
- {
- // The following types cant be set this way, they have special Set functions
- assert(a_iType!=cmVAR);
- assert(a_iType!=cmVAL);
- assert(a_iType!=cmFUNC);
-
- m_iCode = a_iType;
- m_iType = tpVOID;
- m_pTok = 0;
- m_iFlags = 0;
- m_strTok = a_strTok;
- m_iIdx = -1;
-
- return *this;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Set Callback type. */
- ParserToken& Set(const ParserCallback &a_pCallback, const TString &a_sTok)
- {
- assert(a_pCallback.GetAddr());
-
- m_iCode = a_pCallback.GetCode();
- m_iType = tpVOID;
- m_strTok = a_sTok;
- m_pCallback.reset(new ParserCallback(a_pCallback));
-
- m_pTok = 0;
- m_iFlags = 0;
- m_iIdx = -1;
-
- if (!m_pCallback->IsOptimizable())
- AddFlags(flVOLATILE);
-
- return *this;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Make this token a value token.
-
- Member variables not necessary for value tokens will be invalidated.
- \throw nothrow
- */
- ParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString())
- {
- m_iCode = cmVAL;
- m_iType = tpDBL;
- m_fVal = a_fVal;
- m_iFlags = 0;
- m_strTok = a_strTok;
- m_iIdx = -1;
-
- m_pTok = 0;
- m_pCallback.reset(0);
-
- return *this;
- }
-
- //------------------------------------------------------------------------------
- /** \brief make this token a variable token.
-
- Member variables not necessary for variable tokens will be invalidated.
- \throw nothrow
- */
- ParserToken& SetVar(TBase *a_pVar, const TString &a_strTok)
- {
- m_iCode = cmVAR;
- m_iType = tpDBL;
- m_iFlags = 0;
- m_strTok = a_strTok;
- m_iIdx = -1;
- m_pTok = (void*)a_pVar;
- m_pCallback.reset(0);
-
- AddFlags(ParserToken::flVOLATILE);
- return *this;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Make this token a variable token.
-
- Member variables not necessary for variable tokens will be invalidated.
- \throw nothrow
- */
- ParserToken& SetString(const TString &a_strTok, std::size_t a_iSize)
- {
- m_iCode = cmSTRING; // cmSTRVAR;
- m_iType = tpSTR;
- m_iFlags = 0;
- m_strTok = a_strTok;
- m_iIdx = static_cast<int>(a_iSize);
-
- m_pTok = 0;
- m_pCallback.reset(0);
-
- AddFlags(ParserToken::flVOLATILE);
- return *this;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Make token a string token.
-
- String tokens are used to store the value of string function arguments.
- \param a_strTok the string content.
- \post #m_iType==cmSTRING, #m_strTok==a_strTok
- \throw nothrow
- */
- ParserToken& SetString(const string_type &a_strTok)
- {
- m_iCode = cmSTRING;
- m_iType = tpSTR;
- m_iFlags = 0;
- m_iIdx = -1;
-
- m_pTok = 0;
- m_pCallback.reset(0);
-
- m_strTok = a_strTok;
-
- return *this;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Set an index associated with the token related data.
-
- In cmSTRFUNC - This is the index to a string table in the main parser.
- \param a_iIdx The index the string function result will take in the bytecode parser.
- \throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING
- */
- void SetIdx(int a_iIdx)
- {
- if (m_iCode!=cmSTRING || a_iIdx<0)
- throw ParserError(ecINTERNAL_ERROR);
-
- m_iIdx = a_iIdx;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Return Index associated with the token related data.
-
- In cmSTRFUNC - This is the index to a string table in the main parser.
-
- \throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING
- \return The index the result will take in the Bytecode calculatin array (#m_iIdx).
- */
- int GetIdx() const
- {
- if (m_iIdx<0 || m_iCode!=cmSTRING )
- throw ParserError(ecINTERNAL_ERROR);
-
- return m_iIdx;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Return the token type.
-
- \return #m_iType
- \throw nothrow
- */
- ECmdCode GetCode() const
- {
- if (m_pCallback.get())
- {
- return m_pCallback->GetCode();
- }
- else
- {
- return m_iCode;
- }
- }
-
- //------------------------------------------------------------------------------
- ETypeCode GetType() const
- {
- if (m_pCallback.get())
- {
- return m_pCallback->GetType();
- }
- else
- {
- return m_iType;
- }
- }
-
- //------------------------------------------------------------------------------
- int GetPri() const
- {
- if ( !m_pCallback.get())
- throw ParserError(ecINTERNAL_ERROR);
-
- if ( m_pCallback->GetCode()!=cmOPRT_BIN && m_pCallback->GetCode()!=cmOPRT_INFIX)
- throw ParserError(ecINTERNAL_ERROR);
-
- return m_pCallback->GetPri();
- }
-
- //------------------------------------------------------------------------------
- /** \brief Return the address of the callback function assoziated with
- function and operator tokens.
-
- \return The pointer stored in #m_pTok.
- \throw exception_type if token type is non of:
- <ul>
- <li>cmFUNC</li>
- <li>cmSTRFUNC</li>
- <li>cmPOSTOP</li>
- <li>cmINFIXOP</li>
- <li>cmOPRT_BIN</li>
- </ul>
- \sa ECmdCode
- */
- void* GetFuncAddr() const
- {
- return (m_pCallback.get()) ? m_pCallback->GetAddr() : 0;
- }
-
- //------------------------------------------------------------------------------
- /** \biref Get value of the token.
-
- Only applicable to variable and value tokens.
- \throw exception_type if token is no value/variable token.
- */
- TBase GetVal() const
- {
- switch (m_iCode)
- {
- case cmVAL: return m_fVal;
- case cmVAR: return *((TBase*)m_pTok);
- default: throw ParserError(ecVAL_EXPECTED);
- }
- }
-
- //------------------------------------------------------------------------------
- /** \brief Get address of a variable token.
-
- Valid only if m_iType==CmdVar.
- \throw exception_type if token is no variable token.
- */
- TBase* GetVar() const
- {
- if (m_iCode!=cmVAR)
- throw ParserError(ecINTERNAL_ERROR);
-
- return (TBase*)m_pTok;
- }
-
- //------------------------------------------------------------------------------
- /** \brief Return the number of function arguments.
-
- Valid only if m_iType==CmdFUNC.
- */
- int GetArgCount() const
- {
- assert(m_pCallback.get());
-
- if (!m_pCallback->GetAddr())
- throw ParserError(ecINTERNAL_ERROR);
-
- return m_pCallback->GetArgc();
- }
-
- //------------------------------------------------------------------------------
- /** \brief Return the token identifier.
-
- If #m_iType is cmSTRING the token identifier is the value of the string argument
- for a string function.
- \return #m_strTok
- \throw nothrow
- \sa m_strTok
- */
- const TString& GetAsString() const
- {
- return m_strTok;
- }
-};
-
-} // namespace mu
-
-#endif
-
-
diff --git a/muparser/muParserTokenReader.cpp b/muparser/muParserTokenReader.cpp deleted file mode 100644 index 99c0a0a..0000000 --- a/muparser/muParserTokenReader.cpp +++ /dev/null @@ -1,822 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include <cassert>
-#include <cstdio>
-#include <cstring>
-#include <map>
-#include <stack>
-#include <string>
-
-#include "muParserTokenReader.h"
-#include "muParserBase.h"
-
-
-namespace mu
-{
-
- // Forward declaration
- class ParserBase;
-
- //---------------------------------------------------------------------------
- /** \brief Copy constructor.
-
- \sa Assign
- \throw nothrow
- */
- ParserTokenReader::ParserTokenReader(const ParserTokenReader &a_Reader)
- {
- Assign(a_Reader);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Assignement operator.
-
- Self assignement will be suppressed otherwise #Assign is called.
-
- \param a_Reader Object to copy to this token reader.
- \throw nothrow
- */
- ParserTokenReader& ParserTokenReader::operator=(const ParserTokenReader &a_Reader)
- {
- if (&a_Reader!=this)
- Assign(a_Reader);
-
- return *this;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Assign state of a token reader to this token reader.
-
- \param a_Reader Object from which the state should be copied.
- \throw nothrow
- */
- void ParserTokenReader::Assign(const ParserTokenReader &a_Reader)
- {
- m_pParser = a_Reader.m_pParser;
- m_strFormula = a_Reader.m_strFormula;
- m_iPos = a_Reader.m_iPos;
- m_iSynFlags = a_Reader.m_iSynFlags;
-
- m_UsedVar = a_Reader.m_UsedVar;
- m_pFunDef = a_Reader.m_pFunDef;
- m_pConstDef = a_Reader.m_pConstDef;
- m_pVarDef = a_Reader.m_pVarDef;
- m_pStrVarDef = a_Reader.m_pStrVarDef;
- m_pPostOprtDef = a_Reader.m_pPostOprtDef;
- m_pInfixOprtDef = a_Reader.m_pInfixOprtDef;
- m_pOprtDef = a_Reader.m_pOprtDef;
- m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar;
- m_vIdentFun = a_Reader.m_vIdentFun;
- m_pFactory = a_Reader.m_pFactory;
- m_pFactoryData = a_Reader.m_pFactoryData;
- m_iBrackets = a_Reader.m_iBrackets;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Constructor.
-
- Create a Token reader and bind it to a parser object.
-
- \pre [assert] a_pParser may not be NULL
- \post #m_pParser==a_pParser
- \param a_pParent Parent parser object of the token reader.
- */
- ParserTokenReader::ParserTokenReader(ParserBase *a_pParent)
- :m_pParser(a_pParent)
- ,m_strFormula()
- ,m_iPos(0)
- ,m_iSynFlags(0)
- ,m_bIgnoreUndefVar(false)
- ,m_pFunDef(NULL)
- ,m_pPostOprtDef(NULL)
- ,m_pInfixOprtDef(NULL)
- ,m_pOprtDef(NULL)
- ,m_pConstDef(NULL)
- ,m_pStrVarDef(NULL)
- ,m_pVarDef(NULL)
- ,m_pFactory(NULL)
- ,m_pFactoryData(NULL)
- ,m_vIdentFun()
- ,m_UsedVar()
- ,m_fZero(0)
- ,m_iBrackets(0)
- {
- assert(m_pParser);
- SetParent(m_pParser);
- }
-
- //---------------------------------------------------------------------------
- /** \brief Destructor (trivial).
-
- \throw nothrow
- */
- ParserTokenReader::~ParserTokenReader()
- {}
-
- //---------------------------------------------------------------------------
- /** \brief Create instance of a ParserTokenReader identical with this
- and return its pointer.
-
- This is a factory method the calling function must take care of the object destruction.
-
- \return A new ParserTokenReader object.
- \throw nothrow
- */
- ParserTokenReader* ParserTokenReader::Clone(ParserBase *a_pParent) const
- {
- std::auto_ptr<ParserTokenReader> ptr(new ParserTokenReader(*this));
- ptr->SetParent(a_pParent);
- return ptr.release();
- }
-
- //---------------------------------------------------------------------------
- void ParserTokenReader::AddValIdent(identfun_type a_pCallback)
- {
- m_vIdentFun.push_back(a_pCallback);
- }
-
- //---------------------------------------------------------------------------
- void ParserTokenReader::SetVarCreator(facfun_type a_pFactory, void *pUserData)
- {
- m_pFactory = a_pFactory;
- m_pFactoryData = pUserData;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Return the current position of the token reader in the formula string.
-
- \return #m_iPos
- \throw nothrow
- */
- int ParserTokenReader::GetPos() const
- {
- return m_iPos;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Return a reference to the formula.
-
- \return #m_strFormula
- \throw nothrow
- */
- const string_type& ParserTokenReader::GetFormula() const
- {
- return m_strFormula;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Return a map containing the used variables only. */
- const varmap_type& ParserTokenReader::GetUsedVar() const
- {
- return m_UsedVar;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Initialize the token Reader.
-
- Sets the formula position index to zero and set Syntax flags to default for initial formula parsing.
- \pre [assert] triggered if a_szFormula==0
- */
- void ParserTokenReader::SetFormula(const string_type &a_strFormula)
- {
- m_strFormula = a_strFormula;
- ReInit();
- }
-
- //---------------------------------------------------------------------------
- void ParserTokenReader::SetDefs( const funmap_type *a_pFunDef,
- const funmap_type *a_pOprtDef,
- const funmap_type *a_pInfixOprtDef,
- const funmap_type *a_pPostOprtDef,
- varmap_type *a_pVarDef,
- const strmap_type *a_pStrVarDef,
- const valmap_type *a_pConstDef )
- {
- m_pFunDef = a_pFunDef;
- m_pOprtDef = a_pOprtDef;
- m_pInfixOprtDef = a_pInfixOprtDef;
- m_pPostOprtDef = a_pPostOprtDef;
- m_pVarDef = a_pVarDef;
- m_pStrVarDef = a_pStrVarDef;
- m_pConstDef = a_pConstDef;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Set Flag that contronls behaviour in case of undefined variables beeing found.
-
- If true, the parser does not throw an exception if an undefined variable is found.
- otherwise it does. This variable is used internally only!
- It supresses a "undefined variable" exception in GetUsedVar().
- Those function should return a complete list of variables including
- those the are not defined by the time of it's call.
- */
- void ParserTokenReader::IgnoreUndefVar(bool bIgnore)
- {
- m_bIgnoreUndefVar = bIgnore;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Reset the token reader to the start of the formula.
-
- The syntax flags will be reset to a value appropriate for the
- start of a formula.
- \post #m_iPos==0, #m_iSynFlags = noOPT | noBC | noPOSTOP | noSTR
- \throw nothrow
- \sa ESynCodes
- */
- void ParserTokenReader::ReInit()
- {
- m_iPos = 0;
- m_iSynFlags = noOPT | noBC | noPOSTOP | noASSIGN;
- m_iBrackets = 0;
- m_UsedVar.clear();
- }
-
- //---------------------------------------------------------------------------
- /** \brief Read the next token from the string. */
- ParserTokenReader::token_type ParserTokenReader::ReadNextToken()
- {
- assert(m_pParser);
-
- std::stack<int> FunArgs;
- const char_type *szFormula = m_strFormula.c_str();
- token_type tok;
-
- while (szFormula[m_iPos]==' ')
- ++m_iPos;
-
- if ( IsEOF(tok) ) return tok; // Check for end of formula
- if ( IsOprt(tok) ) return tok; // Check for user defined binary operator
- if ( IsBuiltIn(tok) ) return tok; // Check built in operators / tokens
- if ( IsFunTok(tok) ) return tok; // Check for function token
- if ( IsValTok(tok) ) return tok; // Check for values / constant tokens
- if ( IsVarTok(tok) ) return tok; // Check for variable tokens
- if ( IsStrVarTok(tok) ) return tok; // Check for string variables
- if ( IsString(tok) ) return tok; // Check for String tokens
- if ( IsInfixOpTok(tok) ) return tok; // Check for unary operators
- if ( IsPostOpTok(tok) ) return tok; // Check for unary operators
-
- // Check String for undefined variable token. Done only if a
- // flag is set indicating to ignore undefined variables.
- // This is a way to conditionally avoid an error if
- // undefined variables occur.
- // The GetUsedVar function must supress the error for
- // undefined variables in order to collect all variable
- // names including the undefined ones.
- if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) ) return tok;
-
- // Check for unknown token
- //
- // !!! From this point on there is no exit without an exception possible...
- //
- string_type strTok;
- int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
- if (iEnd!=m_iPos)
- Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok);
-
- Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.substr(m_iPos));
- return token_type(); // never reached
- }
-
- //---------------------------------------------------------------------------
- void ParserTokenReader::SetParent(ParserBase *a_pParent)
- {
- m_pParser = a_pParent;
- m_pFunDef = &a_pParent->m_FunDef;
- m_pOprtDef = &a_pParent->m_OprtDef;
- m_pInfixOprtDef = &a_pParent->m_InfixOprtDef;
- m_pPostOprtDef = &a_pParent->m_PostOprtDef;
- m_pVarDef = &a_pParent->m_VarDef;
- m_pStrVarDef = &a_pParent->m_StrVarDef;
- m_pConstDef = &a_pParent->m_ConstDef;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Extract all characters that belong to a certain charset.
-
- \param a_szCharSet [in] Const char array of the characters allowed in the token.
- \param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet.
- \param a_iPos [in] Position in the string from where to start reading.
- \return The Position of the first character not listed in a_szCharSet.
- \throw nothrow
- */
- int ParserTokenReader::ExtractToken( const char_type *a_szCharSet,
- string_type &a_sTok, int a_iPos ) const
- {
- int iEnd = (int)m_strFormula.find_first_not_of(a_szCharSet, a_iPos);
-
- if (iEnd==(int)string_type::npos)
- iEnd = (int)m_strFormula.length();
-
- a_sTok = string_type( m_strFormula.begin()+a_iPos, m_strFormula.begin()+iEnd);
- a_iPos = iEnd;
- return iEnd;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check if a built in operator or other token can be found
- \param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token.
- \return true if an operator token has been found.
- */
- bool ParserTokenReader::IsBuiltIn(token_type &a_Tok)
- {
- const char_type **pOprtDef = m_pParser->GetOprtDef();
- const char_type* szFormula = m_strFormula.c_str();
-
- // Compare token with function and operator strings
- // check string for operator/function
- for (int i=0; pOprtDef[i]; i++)
- {
-#if !defined _UNICODE
- std::size_t len = std::strlen( pOprtDef[i] );
- if ( !std::strncmp(&szFormula[m_iPos], pOprtDef[i], len) )
-#else
- // this would work for both UNICODE and char but it's so god damn ugly!!
- // apart from this this cant be fast
- std::size_t len( std::char_traits<char_type>::length(pOprtDef[i]) );
- if ( string_type(pOprtDef[i]) == string_type(szFormula + m_iPos, szFormula + m_iPos + len) )
-#endif
- {
- switch(i)
- {
- case cmAND:
- case cmOR:
- case cmXOR:
- case cmLT:
- case cmGT:
- case cmLE:
- case cmGE:
- case cmNEQ:
- case cmEQ:
- case cmADD:
- case cmSUB:
- case cmMUL:
- case cmDIV:
- case cmPOW:
- case cmASSIGN:
- // The assignement operator need special treatment
- if (i==cmASSIGN && m_iSynFlags & noASSIGN)
- Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]);
-
- if (!m_pParser->HasBuiltInOprt()) continue;
- if (m_iSynFlags & noOPT)
- {
- // Maybe its an infix operator not an operator
- // Both operator types can share characters in
- // their identifiers
- if ( IsInfixOpTok(a_Tok) )
- return true;
-
- Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]);
- }
-
- m_iSynFlags = noBC | noOPT | noCOMMA | noPOSTOP | noASSIGN;
- m_iSynFlags |= ( (i != cmEND) && ( i != cmBC) ) ? noEND : 0;
- break;
-
- case cmCOMMA:
- if (m_iSynFlags & noCOMMA)
- Error(ecUNEXPECTED_COMMA, m_iPos, pOprtDef[i]);
-
- m_iSynFlags = noBC | noOPT | noEND | noCOMMA | noPOSTOP | noASSIGN;
- break;
-
- case cmBO:
- if (m_iSynFlags & noBO)
- Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);
-
- m_iSynFlags = noBC | noOPT | noEND | noCOMMA | noPOSTOP | noASSIGN;
- ++m_iBrackets;
- break;
-
- case cmBC:
- if (m_iSynFlags & noBC)
- Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);
-
- m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN;
-
- if (--m_iBrackets<0)
- Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);
- break;
-
- default: // The operator is listed in c_DefaultOprt, but not here. This is a bad thing...
- Error(ecINTERNAL_ERROR);
- } // switch operator id
-
- m_iPos += (int)len;
- a_Tok.Set( (ECmdCode)i, pOprtDef[i] );
- return true;
- } // if operator string found
- } // end of for all operator strings
-
- return false;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check for End of Formula.
-
- \return true if an end of formula is found false otherwise.
- \param a_Tok [out] If an eof is found the corresponding token will be stored there.
- \throw nothrow
- \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok
- */
- bool ParserTokenReader::IsEOF(token_type &a_Tok)
- {
- const char_type* szFormula = m_strFormula.c_str();
-
- // check for EOF
- if ( !szFormula[m_iPos] || szFormula[m_iPos] == '\n')
- {
- if ( m_iSynFlags & noEND )
- Error(ecUNEXPECTED_EOF, m_iPos);
-
- if (m_iBrackets>0)
- Error(ecMISSING_PARENS, m_iPos, _T(")"));
-
- m_iSynFlags = 0;
- a_Tok.Set(cmEND);
- return true;
- }
-
- return false;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check if a string position contains a unary infix operator.
- \return true if a function token has been found false otherwise.
- */
- bool ParserTokenReader::IsInfixOpTok(token_type &a_Tok)
- {
- string_type sTok;
- int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos);
- if (iEnd==m_iPos)
- return false;
-
- funmap_type::const_iterator item = m_pInfixOprtDef->find(sTok);
- if (item==m_pInfixOprtDef->end())
- return false;
-
- a_Tok.Set(item->second, sTok);
- m_iPos = (int)iEnd;
-
- if (m_iSynFlags & noINFIXOP)
- Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString());
-
- m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN;
- return true;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check whether the token at a given position is a function token.
- \param a_Tok [out] If a value token is found it will be placed here.
- \throw ParserException if Syntaxflags do not allow a function at a_iPos
- \return true if a function token has been found false otherwise.
- \pre [assert] m_pParser!=0
- */
- bool ParserTokenReader::IsFunTok(token_type &a_Tok)
- {
- string_type strTok;
- int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
- if (iEnd==m_iPos)
- return false;
-
- funmap_type::const_iterator item = m_pFunDef->find(strTok);
- if (item==m_pFunDef->end())
- return false;
-
- a_Tok.Set(item->second, strTok);
-
- m_iPos = (int)iEnd;
- if (m_iSynFlags & noFUN)
- Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString());
-
- m_iSynFlags = noANY ^ noBO;
- return true;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check if a string position contains a binary operator.
- \param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token.
- \return true if an operator token has been found.
- */
- bool ParserTokenReader::IsOprt(token_type &a_Tok)
- {
- string_type strTok;
- int iEnd = ExtractToken(m_pParser->ValidOprtChars(), strTok, m_iPos);
- if (iEnd==m_iPos)
- return false;
-
- funmap_type::const_iterator item = m_pOprtDef->find(strTok);
- if (item==m_pOprtDef->end())
- return false;
-
- a_Tok.Set(item->second, strTok);
-
- if (m_iSynFlags & noOPT)
- {
- // An operator was found but is not expected to occur at
- // this position of the formula, maybe it is an infix
- // operator, not a binary operator. Both operator types
- // can share characters in their identifiers.
- if ( IsInfixOpTok(a_Tok) ) return true;
- // nope, no infix operator
- Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString());
- }
-
- m_iPos = (int)iEnd;
- m_iSynFlags = noBC | noOPT | noCOMMA | noPOSTOP | noEND | noBC | noASSIGN;
- return true;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check if a string position contains a unary post value operator. */
- bool ParserTokenReader::IsPostOpTok(token_type &a_Tok)
- {
- // Tricky problem with equations like "3m+5":
- // m is a postfix operator, + is a valid sign for postfix operators and
- // for binary operators parser detects "m+" as operator string and
- // finds no matching postfix operator.
- //
- // This is a special case so this routine slightly differs from the other
- // token readers.
-
- // Test if there could be a postfix operator
- string_type sTok;
- int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos);
- if (iEnd==m_iPos)
- return false;
-
- // iteraterate over all postfix operator strings
- funmap_type::const_iterator item = m_pPostOprtDef->begin();
- for (item=m_pPostOprtDef->begin(); item!=m_pPostOprtDef->end(); ++item)
- {
- if (sTok.find(item->first)!=0)
- continue;
-
- a_Tok.Set(item->second, sTok);
- m_iPos += (int)item->first.length();
-
- if (m_iSynFlags & noPOSTOP)
- Error(ecUNEXPECTED_OPERATOR, m_iPos-(int)item->first.length(), item->first);
-
- m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN;
- return true;
- }
-
- return false;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check whether the token at a given position is a value token.
-
- Value tokens are either values or constants.
-
- \param a_Tok [out] If a value token is found it will be placed here.
- \return true if a value token has been found.
- */
- bool ParserTokenReader::IsValTok(token_type &a_Tok)
- {
- assert(m_pConstDef);
- assert(m_pParser);
-
- #if defined(_MSC_VER)
- #pragma warning( disable : 4244 )
- #endif
-
- string_type strTok;
- value_type fVal(0);
- int iEnd(0);
-
- // 2.) Check for user defined constant
- // Read everything that could be a constant name
- iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
- if (iEnd!=m_iPos)
- {
- valmap_type::const_iterator item = m_pConstDef->find(strTok);
- if (item!=m_pConstDef->end())
- {
- m_iPos = iEnd;
- a_Tok.SetVal(item->second, strTok);
-
- if (m_iSynFlags & noVAL)
- Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);
-
- m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
- return true;
- }
- }
-
- // 3.call the value recognition functions provided by the user
- // Call user defined value recognition functions
- std::vector<identfun_type>::const_iterator item = m_vIdentFun.begin();
- for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item)
- {
- int iStart = m_iPos;
- if ( (*item)(m_strFormula.c_str() + m_iPos, m_iPos, fVal) )
- {
- strTok.assign(m_strFormula.c_str(), iStart, m_iPos);
- if (m_iSynFlags & noVAL)
- Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);
-
- a_Tok.SetVal(fVal, strTok);
- m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
- return true;
- }
- }
-
- return false;
-
- #if defined(_MSC_VER)
- #pragma warning( default : 4244 )
- #endif
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check wheter a token at a given position is a variable token.
- \param a_Tok [out] If a variable token has been found it will be placed here.
- \return true if a variable token has been found.
- */
- bool ParserTokenReader::IsVarTok(token_type &a_Tok)
- {
- if (!m_pVarDef->size())
- return false;
-
- string_type strTok;
- int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
- if (iEnd==m_iPos)
- return false;
-
- varmap_type::const_iterator item = m_pVarDef->find(strTok);
- if (item==m_pVarDef->end())
- return false;
-
- if (m_iSynFlags & noVAR)
- Error(ecUNEXPECTED_VAR, m_iPos, strTok);
-
- m_iPos = iEnd;
- a_Tok.SetVar(item->second, strTok);
- m_UsedVar[item->first] = item->second; // Add variable to used-var-list
-
- m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR;
- return true;
- }
-
- //---------------------------------------------------------------------------
- bool ParserTokenReader::IsStrVarTok(token_type &a_Tok)
- {
- if (!m_pStrVarDef || !m_pStrVarDef->size())
- return false;
-
- string_type strTok;
- int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
- if (iEnd==m_iPos)
- return false;
-
- strmap_type::const_iterator item = m_pStrVarDef->find(strTok);
- if (item==m_pStrVarDef->end())
- return false;
-
- if (m_iSynFlags & noSTR)
- Error(ecUNEXPECTED_VAR, m_iPos, strTok);
-
- m_iPos = iEnd;
- if (!m_pParser->m_vStringVarBuf.size())
- Error(ecINTERNAL_ERROR);
-
- a_Tok.SetString(m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size() );
-
- m_iSynFlags = m_iSynFlags = noANY ^ ( noBC | noOPT | noEND | noCOMMA);
- return true;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check wheter a token at a given position is an undefined variable.
-
- \param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here.
- \return true if a variable token has been found.
- \throw nothrow
- */
- bool ParserTokenReader::IsUndefVarTok(token_type &a_Tok)
- {
- string_type strTok;
- int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
- if (iEnd==m_iPos)
- return false;
-
- if (m_iSynFlags & noVAR)
- {
- // <ibg/> 20061021 added token string strTok instead of a_Tok.GetAsString() as the
- // token identifier.
- Error(ecUNEXPECTED_VAR, m_iPos - (int)a_Tok.GetAsString().length(), strTok);
- }
-
- // If a factory is available implicitely create new variables
- if (m_pFactory)
- {
- value_type *fVar = m_pFactory(strTok.c_str(), m_pFactoryData);
- a_Tok.SetVar(fVar, strTok );
-
- // Do not use m_pParser->DefineVar( strTok, fVar );
- // in order to define the new variable, it will clear the
- // m_UsedVar array which will kill previousely defined variables
- // from the list
- // This is safe because the new variable can never override an existing one
- // because they are checked first!
- (*m_pVarDef)[strTok] = fVar;
- m_UsedVar[strTok] = fVar; // Add variable to used-var-list
- }
- else
- {
- a_Tok.SetVar((value_type*)&m_fZero, strTok);
- m_UsedVar[strTok] = 0; // Add variable to used-var-list
- }
-
- m_iPos = iEnd;
-
- // Call the variable factory in order to let it define a new parser variable
- m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR;
- return true;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Check wheter a token at a given position is a string.
-
- \param a_Tok [out] If a variable token has been found it will be placed here.
- \return true if a string token has been found.
- \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok
- \throw nothrow
- */
- bool ParserTokenReader::IsString(token_type &a_Tok)
- {
- if (m_strFormula[m_iPos]!='"')
- return false;
-
- string_type strBuf(&m_strFormula[m_iPos+1]);
- std::size_t iEnd(0), iSkip(0);
-
- // parser over escaped '\"' end replace them with '"'
- for(iEnd=(int)strBuf.find( _T("\"") ); iEnd!=string_type::npos; iEnd=(int)strBuf.find( _T("\""), iEnd))
- {
- if (strBuf[iEnd-1]!='\\') break;
- strBuf.replace(iEnd-1, 2, _T("\"") );
- iSkip++;
- }
-
- if (iEnd==string_type::npos)
- Error(ecUNTERMINATED_STRING, m_iPos, _T("\"") );
-
- string_type strTok(strBuf.begin(), strBuf.begin()+iEnd);
-
- if (m_iSynFlags & noSTR)
- Error(ecUNEXPECTED_STR, m_iPos, strTok);
-
- m_pParser->m_vStringBuf.push_back(strTok); // Store string in internal buffer
- a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size());
-
- m_iPos += (int)strTok.length() + 2 + (int)iSkip; // +2 wg Anführungszeichen; +iSkip für entfernte escape zeichen
- m_iSynFlags = m_iSynFlags = noANY ^ ( noCOMMA | noBC | noOPT | noEND );
-
- return true;
- }
-
- //---------------------------------------------------------------------------
- /** \brief Create an error containing the parse error position.
-
- This function will create an Parser Exception object containing the error text and its position.
-
- \param a_iErrc [in] The error code of type #EErrorCodes.
- \param a_iPos [in] The position where the error was detected.
- \param a_strTok [in] The token string representation associated with the error.
- \throw ParserException always throws thats the only purpose of this function.
- */
- void ParserTokenReader::Error( EErrorCodes a_iErrc,
- int a_iPos,
- const string_type &a_sTok) const
- {
- m_pParser->Error(a_iErrc, a_iPos, a_sTok);
- }
-} // namespace mu
-
diff --git a/muparser/muParserTokenReader.h b/muparser/muParserTokenReader.h deleted file mode 100644 index 122586e..0000000 --- a/muparser/muParserTokenReader.h +++ /dev/null @@ -1,156 +0,0 @@ -/*
- __________
- _____ __ __\______ \_____ _______ ______ ____ _______
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
- \/ \/ \/ \/
- Copyright (C) 2004-2006 Ingo Berg
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef MU_PARSER_TOKEN_READER_H
-#define MU_PARSER_TOKEN_READER_H
-
-#include <cassert>
-#include <cstdio>
-#include <cstring>
-#include <map>
-#include <memory>
-#include <stack>
-#include <string>
-
-#include "muParserDef.h"
-#include "muParserToken.h"
-
-
-namespace mu
-{
-
- // Forward declaration
- class ParserBase;
-
- /** \brief Token reader for the ParserBase class.
-
- */
- class ParserTokenReader
- {
- private:
- typedef ParserToken<value_type, string_type> token_type;
-
- private:
- ParserBase *m_pParser;
- string_type m_strFormula;
- int m_iPos;
- int m_iSynFlags;
- bool m_bIgnoreUndefVar;
-
- const funmap_type *m_pFunDef;
- const funmap_type *m_pPostOprtDef;
- const funmap_type *m_pInfixOprtDef;
- const funmap_type *m_pOprtDef;
- const valmap_type *m_pConstDef;
- const strmap_type *m_pStrVarDef;
- varmap_type *m_pVarDef; ///< The only non const pointer to parser internals
- facfun_type m_pFactory;
- void *m_pFactoryData;
- std::vector<identfun_type> m_vIdentFun; ///< Value token identification function
- varmap_type m_UsedVar;
- value_type m_fZero; ///< Dummy value of zero, referenced by undefined variables
- int m_iBrackets;
-
- //
- // private Functions
- //
- private:
-
- /** \brief Syntax codes.
-
- The syntax codes control the syntax check done during the first time parsing of
- the expression string. They are flags that indicate which tokens are allowed next
- if certain tokens are identified.
- */
- enum ESynCodes
- {
- noBO = 1 << 0, ///< to avoid i.e. "cos(7)("
- noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()"
- noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14"
- noVAR = 1 << 3, ///< to avoid i.e. "sin a" or "sin(8)a"
- noCOMMA = 1 << 4, ///< to avoid i.e. ",," or "+," ...
- noFUN = 1 << 5, ///< to avoid i.e. "sqrt cos" or "(1)sin"
- noOPT = 1 << 6, ///< to avoid i.e. "(+)"
- noPOSTOP = 1 << 7, ///< to avoid i.e. "(5!!)" "sin!"
- noINFIXOP = 1 << 8, ///< to avoid i.e. "++4" "!!4"
- noEND = 1 << 9, ///< to avoid unexpected end of formula
- noSTR = 1 << 10, ///< to block numeric arguments on string functions
- noASSIGN = 1 << 11, ///< to block assignement to constant i.e. "4=7"
- noANY = ~0 ///< All of he above flags set
- };
-
- ParserTokenReader(const ParserTokenReader &a_Reader);
- ParserTokenReader& operator=(const ParserTokenReader &a_Reader);
- void Assign(const ParserTokenReader &a_Reader);
-
- public:
- ParserTokenReader(ParserBase *a_pParent);
- ~ParserTokenReader();
- ParserTokenReader* Clone(ParserBase *a_pParent) const;
-
- void AddValIdent(identfun_type a_pCallback);
- void SetVarCreator(facfun_type a_pFactory, void *pUserData);
- int GetPos() const;
- const string_type& GetFormula() const;
- const varmap_type& GetUsedVar() const;
- void SetFormula(const string_type &a_strFormula);
- void SetDefs( const funmap_type *a_pFunDef,
- const funmap_type *a_pOprtDef,
- const funmap_type *a_pInfixOprtDef,
- const funmap_type *a_pPostOprtDef,
- varmap_type *a_pVarDef,
- const strmap_type *a_pStrVarDef,
- const valmap_type *a_pConstDef );
- void IgnoreUndefVar(bool bIgnore);
- void ReInit();
- token_type ReadNextToken();
-
- //
- // private functions
- //
- private:
-
- void SetParent(ParserBase *a_pParent);
- int ExtractToken( const char_type *a_szCharSet,
- string_type &a_strTok, int a_iPos ) const;
- bool IsBuiltIn(token_type &a_Tok);
- bool IsEOF(token_type &a_Tok);
- bool IsInfixOpTok(token_type &a_Tok);
- bool IsFunTok(token_type &a_Tok);
- bool IsPostOpTok(token_type &a_Tok);
- bool IsOprt(token_type &a_Tok);
- bool IsValTok(token_type &a_Tok);
- bool IsVarTok(token_type &a_Tok);
- bool IsStrVarTok(token_type &a_Tok);
- bool IsUndefVarTok(token_type &a_Tok);
- bool IsString(token_type &a_Tok);
- void Error( EErrorCodes a_iErrc, int a_iPos = -1,
- const string_type &a_sTok = string_type() ) const;
- };
-} // namespace mu
-
-#endif
-
-
|