Apply project code style.
--HG-- branch : feature
This commit is contained in:
parent
0b49785255
commit
2c77a73343
|
@ -24,322 +24,366 @@
|
|||
#include <QtMath>
|
||||
#include <QtGlobal>
|
||||
|
||||
//--- Standard includes ------------------------------------------------------------------------
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/** \file
|
||||
\brief Implementation of the standard floating point QmuParser.
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* @brief Implementation of the standard floating point QmuParser.
|
||||
*/
|
||||
|
||||
/** \brief Namespace for mathematical applications. */
|
||||
/**
|
||||
* @brief Namespace for mathematical applications.
|
||||
*/
|
||||
namespace qmu
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Trigonometric function
|
||||
qreal QmuParser::Sinh(qreal v) { return sinh(v); }
|
||||
qreal QmuParser::Cosh(qreal v) { return cosh(v); }
|
||||
qreal QmuParser::Tanh(qreal v) { return tanh(v); }
|
||||
qreal QmuParser::ASinh(qreal v) { return log(v + qSqrt(v * v + 1)); }
|
||||
qreal QmuParser::ACosh(qreal v) { return log(v + qSqrt(v * v - 1)); }
|
||||
qreal QmuParser::ATanh(qreal v) { return ((qreal)0.5 * log((1 + v) / (1 - v))); }
|
||||
// Trigonometric function
|
||||
qreal QmuParser::Sinh(qreal v)
|
||||
{
|
||||
return sinh(v);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Logarithm functions
|
||||
qreal QmuParser::Cosh(qreal v)
|
||||
{
|
||||
return cosh(v);
|
||||
}
|
||||
|
||||
// Logarithm base 2
|
||||
qreal QmuParser::Log2(qreal v)
|
||||
{
|
||||
#ifdef MUP_MATH_EXCEPTIONS
|
||||
if (v<=0)
|
||||
throw QmuParserError(ecDOMAIN_ERROR, "Log2");
|
||||
#endif
|
||||
qreal QmuParser::Tanh(qreal v)
|
||||
{
|
||||
return tanh(v);
|
||||
}
|
||||
|
||||
return log(v)/log((qreal)2);
|
||||
}
|
||||
qreal QmuParser::ASinh(qreal v)
|
||||
{
|
||||
return log(v + qSqrt(v * v + 1));
|
||||
}
|
||||
|
||||
// Logarithm base 10
|
||||
qreal QmuParser::Log10(qreal v)
|
||||
{
|
||||
#ifdef MUP_MATH_EXCEPTIONS
|
||||
if (v<=0)
|
||||
throw QmuParserError(ecDOMAIN_ERROR, "Log10");
|
||||
#endif
|
||||
qreal QmuParser::ACosh(qreal v)
|
||||
{
|
||||
return log(v + qSqrt(v * v - 1));
|
||||
}
|
||||
|
||||
return log10(v);
|
||||
}
|
||||
qreal QmuParser::ATanh(qreal v)
|
||||
{
|
||||
return ((qreal)0.5 * log((1 + v) / (1 - v)));
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Logarithm functions
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// misc
|
||||
qreal QmuParser::Abs(qreal v) { return qAbs(v); }
|
||||
qreal QmuParser::Rint(qreal v) { return qFloor(v + (qreal)0.5); }
|
||||
qreal QmuParser::Sign(qreal v) { return (qreal)((v<0) ? -1 : (v>0) ? 1 : 0); }
|
||||
// Logarithm base 2
|
||||
qreal QmuParser::Log2(qreal v)
|
||||
{
|
||||
#ifdef MUP_MATH_EXCEPTIONS
|
||||
if (v<=0)
|
||||
{
|
||||
throw QmuParserError(ecDOMAIN_ERROR, "Log2");
|
||||
}
|
||||
#endif
|
||||
return log(v)/log((qreal)2);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Callback for the unary minus operator.
|
||||
\param v The value to negate
|
||||
\return -v
|
||||
*/
|
||||
qreal QmuParser::UnaryMinus(qreal v)
|
||||
{
|
||||
return -v;
|
||||
}
|
||||
// Logarithm base 10
|
||||
qreal QmuParser::Log10(qreal v)
|
||||
{
|
||||
#ifdef MUP_MATH_EXCEPTIONS
|
||||
if (v<=0)
|
||||
{
|
||||
throw QmuParserError(ecDOMAIN_ERROR, "Log10");
|
||||
}
|
||||
#endif
|
||||
return log10(v);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Callback for adding multiple values.
|
||||
\param [in] a_afArg Vector with the function arguments
|
||||
\param [in] a_iArgc The size of a_afArg
|
||||
*/
|
||||
qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc)
|
||||
{
|
||||
if (!a_iArgc)
|
||||
throw exception_type("too few arguments for function sum.");
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// misc
|
||||
qreal QmuParser::Abs(qreal v)
|
||||
{
|
||||
return qAbs(v);
|
||||
}
|
||||
|
||||
qreal fRes=0;
|
||||
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
|
||||
return fRes;
|
||||
}
|
||||
qreal QmuParser::Rint(qreal v)
|
||||
{
|
||||
return qFloor(v + (qreal)0.5);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Callback for averaging multiple values.
|
||||
\param [in] a_afArg Vector with the function arguments
|
||||
\param [in] a_iArgc The size of a_afArg
|
||||
*/
|
||||
qreal QmuParser::Avg(const qreal *a_afArg, int a_iArgc)
|
||||
{
|
||||
if (!a_iArgc)
|
||||
throw exception_type("too few arguments for function sum.");
|
||||
qreal QmuParser::Sign(qreal v)
|
||||
{
|
||||
return (qreal)((v<0) ? -1 : (v>0) ? 1 : 0);
|
||||
}
|
||||
|
||||
qreal fRes=0;
|
||||
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
|
||||
return fRes/(qreal)a_iArgc;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Callback for the unary minus operator.
|
||||
* @param v The value to negate
|
||||
* @return -v
|
||||
*/
|
||||
qreal QmuParser::UnaryMinus(qreal v)
|
||||
{
|
||||
return -v;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Callback for adding multiple values.
|
||||
* @param [in] a_afArg Vector with the function arguments
|
||||
* @param [in] a_iArgc The size of a_afArg
|
||||
*/
|
||||
qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc)
|
||||
{
|
||||
if (!a_iArgc)
|
||||
{
|
||||
throw exception_type("too few arguments for function sum.");
|
||||
}
|
||||
qreal fRes=0;
|
||||
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
|
||||
return fRes;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Callback for determining the minimum value out of a vector.
|
||||
\param [in] a_afArg Vector with the function arguments
|
||||
\param [in] a_iArgc The size of a_afArg
|
||||
*/
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Callback for averaging multiple values.
|
||||
* @param [in] a_afArg Vector with the function arguments
|
||||
* @param [in] a_iArgc The size of a_afArg
|
||||
*/
|
||||
qreal QmuParser::Avg(const qreal *a_afArg, int a_iArgc)
|
||||
{
|
||||
if (!a_iArgc)
|
||||
{
|
||||
throw exception_type("too few arguments for function sum.");
|
||||
}
|
||||
qreal fRes=0;
|
||||
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
|
||||
return fRes/(qreal)a_iArgc;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Callback for determining the minimum value out of a vector.
|
||||
* @param [in] a_afArg Vector with the function arguments
|
||||
* @param [in] a_iArgc The size of a_afArg
|
||||
*/
|
||||
qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc)
|
||||
{
|
||||
if (!a_iArgc)
|
||||
{
|
||||
throw exception_type("too few arguments for function min.");
|
||||
}
|
||||
|
||||
qreal fRes=a_afArg[0];
|
||||
for (int i=0; i<a_iArgc; ++i)
|
||||
{
|
||||
fRes = qMin(fRes, a_afArg[i]);
|
||||
}
|
||||
return fRes;
|
||||
if (!a_iArgc)
|
||||
{
|
||||
throw exception_type("too few arguments for function min.");
|
||||
}
|
||||
qreal fRes=a_afArg[0];
|
||||
for (int i=0; i<a_iArgc; ++i)
|
||||
{
|
||||
fRes = qMin(fRes, a_afArg[i]);
|
||||
}
|
||||
return fRes;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Callback for determining the maximum value out of a vector.
|
||||
\param [in] a_afArg Vector with the function arguments
|
||||
\param [in] a_iArgc The size of a_afArg
|
||||
*/
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Callback for determining the maximum value out of a vector.
|
||||
* @param [in] a_afArg Vector with the function arguments
|
||||
* @param [in] a_iArgc The size of a_afArg
|
||||
*/
|
||||
qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
|
||||
{
|
||||
if (!a_iArgc)
|
||||
{
|
||||
throw exception_type("too few arguments for function min.");
|
||||
}
|
||||
|
||||
qreal fRes=a_afArg[0];
|
||||
for (int i=0; i<a_iArgc; ++i)
|
||||
{
|
||||
fRes = qMax(fRes, a_afArg[i]);
|
||||
}
|
||||
return fRes;
|
||||
if (!a_iArgc)
|
||||
{
|
||||
throw exception_type("too few arguments for function min.");
|
||||
}
|
||||
qreal fRes=a_afArg[0];
|
||||
for (int i=0; i<a_iArgc; ++i)
|
||||
{
|
||||
fRes = qMax(fRes, a_afArg[i]);
|
||||
}
|
||||
return fRes;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Default value recognition callback.
|
||||
* @param [in] a_szExpr Pointer to the expression
|
||||
* @param [in, out] a_iPos Pointer to an index storing the current position within the expression
|
||||
* @param [out] a_fVal Pointer where the value should be stored in case one is found.
|
||||
* @return 1 if a value was found 0 otherwise.
|
||||
*/
|
||||
int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal)
|
||||
{
|
||||
qreal fVal(0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Default value recognition callback.
|
||||
\param [in] a_szExpr Pointer to the expression
|
||||
\param [in, out] a_iPos Pointer to an index storing the current position within the expression
|
||||
\param [out] a_fVal Pointer where the value should be stored in case one is found.
|
||||
\return 1 if a value was found 0 otherwise.
|
||||
*/
|
||||
int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal)
|
||||
{
|
||||
qreal fVal(0);
|
||||
#if defined(_UNICODE)
|
||||
std::wstring a_szExprStd = a_szExpr.toStdWString();
|
||||
#else
|
||||
std::string a_szExprStd = a_szExpr.toStdString();
|
||||
#endif
|
||||
stringstream_type stream(a_szExprStd);
|
||||
stream.seekg(0); // todo: check if this really is necessary
|
||||
stream.imbue(QmuParser::s_locale);
|
||||
stream >> fVal;
|
||||
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
|
||||
|
||||
#if defined(_UNICODE)
|
||||
std::wstring a_szExprStd = a_szExpr.toStdWString();
|
||||
#else
|
||||
std::string a_szExprStd = a_szExpr.toStdString();
|
||||
#endif
|
||||
stringstream_type stream(a_szExprStd);
|
||||
stream.seekg(0); // todo: check if this really is necessary
|
||||
stream.imbue(QmuParser::s_locale);
|
||||
stream >> fVal;
|
||||
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
|
||||
if (iEnd==(stringstream_type::pos_type)-1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iEnd==(stringstream_type::pos_type)-1)
|
||||
return 0;
|
||||
*a_iPos += (int)iEnd;
|
||||
*a_fVal = fVal;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*a_iPos += (int)iEnd;
|
||||
*a_fVal = fVal;
|
||||
return 1;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Constructor.
|
||||
*
|
||||
* Call QmuParserBase class constructor and trigger Function, Operator and Constant initialization.
|
||||
*/
|
||||
QmuParser::QmuParser():QmuParserBase()
|
||||
{
|
||||
AddValIdent(IsVal);
|
||||
|
||||
InitCharSets();
|
||||
InitFun();
|
||||
InitConst();
|
||||
InitOprt();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Constructor.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Define the character sets.
|
||||
* @sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars
|
||||
*
|
||||
* This function is used for initializing the default character sets that define
|
||||
* the characters to be useable in function and variable names and operators.
|
||||
*/
|
||||
void QmuParser::InitCharSets()
|
||||
{
|
||||
DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
|
||||
DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" );
|
||||
DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" );
|
||||
}
|
||||
|
||||
Call QmuParserBase class constructor and trigger Function, Operator and Constant initialization.
|
||||
*/
|
||||
QmuParser::QmuParser()
|
||||
:QmuParserBase()
|
||||
{
|
||||
AddValIdent(IsVal);
|
||||
|
||||
InitCharSets();
|
||||
InitFun();
|
||||
InitConst();
|
||||
InitOprt();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Define the character sets.
|
||||
\sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars
|
||||
|
||||
This function is used for initializing the default character sets that define
|
||||
the characters to be useable in function and variable names and operators.
|
||||
*/
|
||||
void QmuParser::InitCharSets()
|
||||
{
|
||||
DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
|
||||
DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" );
|
||||
DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Initialize the default functions. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Initialize the default functions.
|
||||
*/
|
||||
void QmuParser::InitFun()
|
||||
{
|
||||
// trigonometric functions
|
||||
DefineFun("sin", qSin);
|
||||
DefineFun("cos", qCos);
|
||||
DefineFun("tan", qTan);
|
||||
// arcus functions
|
||||
DefineFun("asin", qAsin);
|
||||
DefineFun("acos", qAcos);
|
||||
DefineFun("atan", qAtan);
|
||||
DefineFun("atan2", qAtan2);
|
||||
// hyperbolic functions
|
||||
DefineFun("sinh", Sinh);
|
||||
DefineFun("cosh", Cosh);
|
||||
DefineFun("tanh", Tanh);
|
||||
// arcus hyperbolic functions
|
||||
DefineFun("asinh", ASinh);
|
||||
DefineFun("acosh", ACosh);
|
||||
DefineFun("atanh", ATanh);
|
||||
// Logarithm functions
|
||||
DefineFun("log2", Log2);
|
||||
DefineFun("log10", Log10);
|
||||
DefineFun("log", Log10);
|
||||
DefineFun("ln", qLn);
|
||||
// misc
|
||||
DefineFun("exp", qExp);
|
||||
DefineFun("sqrt", qSqrt);
|
||||
DefineFun("sign", Sign);
|
||||
DefineFun("rint", Rint);
|
||||
DefineFun("abs", Abs);
|
||||
// Functions with variable number of arguments
|
||||
DefineFun("sum", Sum);
|
||||
DefineFun("avg", Avg);
|
||||
DefineFun("min", Min);
|
||||
DefineFun("max", Max);
|
||||
// trigonometric functions
|
||||
DefineFun("sin", qSin);
|
||||
DefineFun("cos", qCos);
|
||||
DefineFun("tan", qTan);
|
||||
// arcus functions
|
||||
DefineFun("asin", qAsin);
|
||||
DefineFun("acos", qAcos);
|
||||
DefineFun("atan", qAtan);
|
||||
DefineFun("atan2", qAtan2);
|
||||
// hyperbolic functions
|
||||
DefineFun("sinh", Sinh);
|
||||
DefineFun("cosh", Cosh);
|
||||
DefineFun("tanh", Tanh);
|
||||
// arcus hyperbolic functions
|
||||
DefineFun("asinh", ASinh);
|
||||
DefineFun("acosh", ACosh);
|
||||
DefineFun("atanh", ATanh);
|
||||
// Logarithm functions
|
||||
DefineFun("log2", Log2);
|
||||
DefineFun("log10", Log10);
|
||||
DefineFun("log", Log10);
|
||||
DefineFun("ln", qLn);
|
||||
// misc
|
||||
DefineFun("exp", qExp);
|
||||
DefineFun("sqrt", qSqrt);
|
||||
DefineFun("sign", Sign);
|
||||
DefineFun("rint", Rint);
|
||||
DefineFun("abs", Abs);
|
||||
// Functions with variable number of arguments
|
||||
DefineFun("sum", Sum);
|
||||
DefineFun("avg", Avg);
|
||||
DefineFun("min", Min);
|
||||
DefineFun("max", Max);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Initialize constants.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Initialize constants.
|
||||
*
|
||||
* By default the QmuParser recognizes two constants. Pi ("pi") and the eulerian
|
||||
* number ("_e").
|
||||
*/
|
||||
void QmuParser::InitConst()
|
||||
{
|
||||
DefineConst("_pi", (qreal)M_PI);
|
||||
DefineConst("_e", (qreal)M_E);
|
||||
}
|
||||
|
||||
By default the QmuParser recognizes two constants. Pi ("pi") and the eulerian
|
||||
number ("_e").
|
||||
*/
|
||||
void QmuParser::InitConst()
|
||||
{
|
||||
DefineConst("_pi", (qreal)M_PI);
|
||||
DefineConst("_e", (qreal)M_E);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Initialize operators.
|
||||
*
|
||||
* By default only the unary minus operator is added.
|
||||
*/
|
||||
void QmuParser::InitOprt()
|
||||
{
|
||||
DefineInfixOprt("-", UnaryMinus);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Initialize operators.
|
||||
|
||||
By default only the unary minus operator is added.
|
||||
*/
|
||||
void QmuParser::InitOprt()
|
||||
{
|
||||
DefineInfixOprt("-", UnaryMinus);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void QmuParser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
|
||||
{
|
||||
// this is just sample code to illustrate modifying variable names on the fly.
|
||||
// I'm not sure anyone really needs such a feature...
|
||||
/*
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
|
||||
{
|
||||
// this is just sample code to illustrate modifying variable names on the fly.
|
||||
// I'm not sure anyone really needs such a feature...
|
||||
/*
|
||||
|
||||
|
||||
string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd);
|
||||
string sRepl = std::string("_") + sVar + "_";
|
||||
string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd);
|
||||
string sRepl = std::string("_") + sVar + "_";
|
||||
|
||||
int nOrigVarEnd = nEnd;
|
||||
cout << "variable detected!\n";
|
||||
cout << " Expr: " << *pExpr << "\n";
|
||||
cout << " Start: " << nStart << "\n";
|
||||
cout << " End: " << nEnd << "\n";
|
||||
cout << " Var: \"" << sVar << "\"\n";
|
||||
cout << " Repl: \"" << sRepl << "\"\n";
|
||||
nEnd = nStart + sRepl.length();
|
||||
cout << " End: " << nEnd << "\n";
|
||||
pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);
|
||||
cout << " New expr: " << *pExpr << "\n";
|
||||
*/
|
||||
}
|
||||
int nOrigVarEnd = nEnd;
|
||||
cout << "variable detected!\n";
|
||||
cout << " Expr: " << *pExpr << "\n";
|
||||
cout << " Start: " << nStart << "\n";
|
||||
cout << " End: " << nEnd << "\n";
|
||||
cout << " Var: \"" << sVar << "\"\n";
|
||||
cout << " Repl: \"" << sRepl << "\"\n";
|
||||
nEnd = nStart + sRepl.length();
|
||||
cout << " End: " << nEnd << "\n";
|
||||
pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);
|
||||
cout << " New expr: " << *pExpr << "\n";
|
||||
*/
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Numerically differentiate with regard to a variable.
|
||||
\param [in] a_Var Pointer to the differentiation variable.
|
||||
\param [in] a_fPos Position at which the differentiation should take place.
|
||||
\param [in] a_fEpsilon Epsilon used for the numerical differentiation.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Numerically differentiate with regard to a variable.
|
||||
* @param [in] a_Var Pointer to the differentiation variable.
|
||||
* @param [in] a_fPos Position at which the differentiation should take place.
|
||||
* @param [in] a_fEpsilon Epsilon used for the numerical differentiation.
|
||||
*
|
||||
* Numerical differentiation uses a 5 point operator yielding a 4th order
|
||||
* formula. The default value for epsilon is 0.00074 which is
|
||||
* numeric_limits<double>::epsilon() ^ (1/5) as suggested in the muQmuParser
|
||||
* forum:
|
||||
*
|
||||
* http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843
|
||||
*/
|
||||
qreal QmuParser::Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon) const
|
||||
{
|
||||
qreal fRes(0),
|
||||
fBuf(*a_Var),
|
||||
f[4] = {0,0,0,0},
|
||||
fEpsilon(a_fEpsilon);
|
||||
|
||||
Numerical differentiation uses a 5 point operator yielding a 4th order
|
||||
formula. The default value for epsilon is 0.00074 which is
|
||||
numeric_limits<double>::epsilon() ^ (1/5) as suggested in the muQmuParser
|
||||
forum:
|
||||
// Backwards compatible calculation of epsilon inc case the user doesnt provide
|
||||
// his own epsilon
|
||||
if (fEpsilon==0)
|
||||
{
|
||||
fEpsilon = (a_fPos==0) ? (qreal)1e-10 : (qreal)1e-7 * a_fPos;
|
||||
}
|
||||
|
||||
http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843
|
||||
*/
|
||||
qreal QmuParser::Diff(qreal *a_Var,
|
||||
qreal a_fPos,
|
||||
qreal a_fEpsilon) const
|
||||
{
|
||||
qreal fRes(0),
|
||||
fBuf(*a_Var),
|
||||
f[4] = {0,0,0,0},
|
||||
fEpsilon(a_fEpsilon);
|
||||
*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
|
||||
|
||||
// Backwards compatible calculation of epsilon inc case the user doesnt provide
|
||||
// his own epsilon
|
||||
if (fEpsilon==0)
|
||||
fEpsilon = (a_fPos==0) ? (qreal)1e-10 : (qreal)1e-7 * a_fPos;
|
||||
|
||||
*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;
|
||||
}
|
||||
fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon);
|
||||
return fRes;
|
||||
}
|
||||
} // namespace qmu
|
||||
|
|
|
@ -24,67 +24,63 @@
|
|||
#define QMUPARSER_H
|
||||
|
||||
#include "qmuparser_global.h"
|
||||
|
||||
//--- Parser includes --------------------------------------------------------------------------
|
||||
#include "qmuparserbase.h"
|
||||
|
||||
/** \file
|
||||
\brief Definition of the standard floating point parser.
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* @brief Definition of the standard floating point parser.
|
||||
*/
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
/** \brief Mathematical expressions parser.
|
||||
|
||||
Standard implementation of the mathematical expressions parser.
|
||||
Can be used as a reference implementation for subclassing the parser.
|
||||
|
||||
<small>
|
||||
(C) 2011 Ingo Berg<br>
|
||||
muparser(at)gmx.de
|
||||
</small>
|
||||
*/
|
||||
/* final */ class QMUPARSERSHARED_EXPORT QmuParser : public QmuParserBase
|
||||
{
|
||||
|
||||
public:
|
||||
QmuParser();
|
||||
virtual void InitCharSets();
|
||||
virtual void InitFun();
|
||||
virtual void InitConst();
|
||||
virtual void InitOprt();
|
||||
virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);
|
||||
|
||||
qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const;
|
||||
protected:
|
||||
// Trigonometric functions
|
||||
static qreal Tan2(qreal, qreal);
|
||||
// hyperbolic functions
|
||||
static qreal Sinh(qreal);
|
||||
static qreal Cosh(qreal);
|
||||
static qreal Tanh(qreal);
|
||||
// arcus hyperbolic functions
|
||||
static qreal ASinh(qreal);
|
||||
static qreal ACosh(qreal);
|
||||
static qreal ATanh(qreal);
|
||||
// Logarithm functions
|
||||
static qreal Log2(qreal); // Logarithm Base 2
|
||||
static qreal Log10(qreal); // Logarithm Base 10
|
||||
// misc
|
||||
static qreal Abs(qreal);
|
||||
static qreal Rint(qreal);
|
||||
static qreal Sign(qreal);
|
||||
// Prefix operators
|
||||
// !!! Unary Minus is a MUST if you want to use negative signs !!!
|
||||
static qreal UnaryMinus(qreal);
|
||||
// Functions with variable number of arguments
|
||||
static qreal Sum(const qreal*, int); // sum
|
||||
static qreal Avg(const qreal*, int); // mean value
|
||||
static qreal Min(const qreal*, int); // minimum
|
||||
static qreal Max(const qreal*, int); // maximum
|
||||
|
||||
static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal);
|
||||
};
|
||||
/** @brief Mathematical expressions parser.
|
||||
*
|
||||
* Standard implementation of the mathematical expressions parser.
|
||||
* Can be used as a reference implementation for subclassing the parser.
|
||||
*
|
||||
* <small>
|
||||
* (C) 2011 Ingo Berg<br>
|
||||
* muparser(at)gmx.de
|
||||
* </small>
|
||||
*/
|
||||
/* final */ class QMUPARSERSHARED_EXPORT QmuParser : public QmuParserBase
|
||||
{
|
||||
public:
|
||||
QmuParser();
|
||||
virtual void InitCharSets();
|
||||
virtual void InitFun();
|
||||
virtual void InitConst();
|
||||
virtual void InitOprt();
|
||||
virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);
|
||||
qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const;
|
||||
protected:
|
||||
static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal);
|
||||
// Trigonometric functions
|
||||
static qreal Tan2(qreal, qreal);
|
||||
// hyperbolic functions
|
||||
static qreal Sinh(qreal);
|
||||
static qreal Cosh(qreal);
|
||||
static qreal Tanh(qreal);
|
||||
// arcus hyperbolic functions
|
||||
static qreal ASinh(qreal);
|
||||
static qreal ACosh(qreal);
|
||||
static qreal ATanh(qreal);
|
||||
// Logarithm functions
|
||||
static qreal Log2(qreal); // Logarithm Base 2
|
||||
static qreal Log10(qreal); // Logarithm Base 10
|
||||
// misc
|
||||
static qreal Abs(qreal);
|
||||
static qreal Rint(qreal);
|
||||
static qreal Sign(qreal);
|
||||
// Prefix operators
|
||||
// !!! Unary Minus is a MUST if you want to use negative signs !!!
|
||||
static qreal UnaryMinus(qreal);
|
||||
// Functions with variable number of arguments
|
||||
static qreal Sum(const qreal*, int); // sum
|
||||
static qreal Avg(const qreal*, int); // mean value
|
||||
static qreal Min(const qreal*, int); // minimum
|
||||
static qreal Max(const qreal*, int); // maximum
|
||||
};
|
||||
|
||||
} // namespace qmu
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,18 +23,10 @@
|
|||
#ifndef QMUQPARSERBASE_H
|
||||
#define QMUQPARSERBASE_H
|
||||
|
||||
//--- Standard includes ------------------------------------------------------------------------
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <locale>
|
||||
#include <QStack>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
//--- Parser includes --------------------------------------------------------------------------
|
||||
#include "qmuparserdef.h"
|
||||
#include "qmuparsertokenreader.h"
|
||||
#include "qmuparserbytecode.h"
|
||||
|
@ -43,261 +35,227 @@
|
|||
|
||||
namespace qmu
|
||||
{
|
||||
/** \file
|
||||
\brief This file contains the class definition of the qmuparser engine.
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* @brief This file contains the class definition of the qmuparser engine.
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/** \brief Mathematical expressions parser (base parser engine).
|
||||
\author (C) 2013 Ingo Berg
|
||||
|
||||
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.
|
||||
*/
|
||||
class QmuParserBase
|
||||
{
|
||||
friend class QmuParserTokenReader;
|
||||
|
||||
private:
|
||||
|
||||
/** \brief Typedef for the parse functions.
|
||||
|
||||
The parse function do the actual work. The parser exchanges
|
||||
the function pointer to the parser function depending on
|
||||
which state it is in. (i.e. bytecode parser vs. string parser)
|
||||
*/
|
||||
typedef qreal (QmuParserBase::*ParseFunction)() const;
|
||||
|
||||
/** \brief Type used for storing an array of values. */
|
||||
typedef QVector<qreal> valbuf_type;
|
||||
|
||||
/** \brief Type for a vector of strings. */
|
||||
typedef QVector<QString> stringbuf_type;
|
||||
|
||||
/** \brief Typedef for the token reader. */
|
||||
typedef QmuParserTokenReader token_reader_type;
|
||||
|
||||
/** \brief Type used for parser tokens. */
|
||||
typedef QmuParserToken<qreal, QString> token_type;
|
||||
|
||||
/** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */
|
||||
static const int s_MaxNumOpenMPThreads = 4;
|
||||
|
||||
public:
|
||||
|
||||
/** \brief Type of the error class.
|
||||
|
||||
Included for backwards compatibility.
|
||||
*/
|
||||
typedef QmuParserError exception_type;
|
||||
|
||||
static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
|
||||
|
||||
QmuParserBase();
|
||||
QmuParserBase(const QmuParserBase &a_Parser);
|
||||
QmuParserBase& operator=(const QmuParserBase &a_Parser);
|
||||
|
||||
virtual ~QmuParserBase();
|
||||
|
||||
qreal Eval() const;
|
||||
qreal* Eval(int &nStackSize) const;
|
||||
void Eval(qreal *results, int nBulkSize);
|
||||
|
||||
int GetNumResults() const;
|
||||
|
||||
void SetExpr(const QString &a_sExpr);
|
||||
void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
|
||||
|
||||
void SetDecSep(char_type cDecSep);
|
||||
void SetThousandsSep(char_type cThousandsSep = 0);
|
||||
void ResetLocale();
|
||||
|
||||
void EnableOptimizer(bool a_bIsOn=true);
|
||||
void EnableBuiltInOprt(bool a_bIsOn=true);
|
||||
|
||||
bool HasBuiltInOprt() const;
|
||||
void AddValIdent(identfun_type a_pCallback);
|
||||
|
||||
/** \fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true)
|
||||
\brief Define a parser function without arguments.
|
||||
\param a_strName Name of the function
|
||||
\param a_pFun Pointer to the callback function
|
||||
\param a_bAllowOpt A flag indicating this function may be optimized
|
||||
*/
|
||||
template<typename T>
|
||||
void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true)
|
||||
{
|
||||
AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
|
||||
}
|
||||
|
||||
void DefineOprt(const QString &a_strName,
|
||||
fun_type2 a_pFun,
|
||||
unsigned a_iPri=0,
|
||||
EOprtAssociativity a_eAssociativity = oaLEFT,
|
||||
bool a_bAllowOpt = false);
|
||||
void DefineConst(const QString &a_sName, qreal a_fVal);
|
||||
void DefineStrConst(const QString &a_sName, const QString &a_strVal);
|
||||
void DefineVar(const QString &a_sName, qreal *a_fVar);
|
||||
void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
|
||||
void DefineInfixOprt(const QString &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 QString &a_strVarName);
|
||||
const varmap_type& GetUsedVar() const;
|
||||
const varmap_type& GetVar() const;
|
||||
const valmap_type& GetConst() const;
|
||||
const QString &GetExpr() const;
|
||||
const funmap_type& GetFunDef() const;
|
||||
string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const;
|
||||
|
||||
const QStringList &GetOprtDef() const;
|
||||
void DefineNameChars(const QString &a_szCharset);
|
||||
void DefineOprtChars(const QString &a_szCharset);
|
||||
void DefineInfixOprtChars(const QString &a_szCharset);
|
||||
|
||||
const QString& ValidNameChars() const;
|
||||
const QString &ValidOprtChars() const;
|
||||
const QString &ValidInfixOprtChars() const;
|
||||
|
||||
void SetArgSep(char_type cArgSep);
|
||||
QChar GetArgSep() const;
|
||||
|
||||
void Error(EErrorCodes a_iErrc,
|
||||
int a_iPos = -1,
|
||||
const QString &a_strTok = QString() ) const;
|
||||
|
||||
protected:
|
||||
|
||||
void Init();
|
||||
|
||||
virtual void InitCharSets() = 0;
|
||||
virtual void InitFun() = 0;
|
||||
virtual void InitConst() = 0;
|
||||
virtual void InitOprt() = 0;
|
||||
|
||||
virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd);
|
||||
|
||||
static const QStringList c_DefaultOprt;
|
||||
static std::locale s_locale; ///< The locale used by the parser
|
||||
static bool g_DbgDumpCmdCode;
|
||||
static bool g_DbgDumpStack;
|
||||
|
||||
/** \brief A facet class used to change decimal and thousands separator. */
|
||||
template<class TChar>
|
||||
class change_dec_sep : public std::numpunct<TChar>
|
||||
/**
|
||||
* @brief Mathematical expressions parser (base parser engine).
|
||||
* @author (C) 2013 Ingo Berg
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
class QmuParserBase
|
||||
{
|
||||
friend class QmuParserTokenReader;
|
||||
public:
|
||||
/**
|
||||
* @brief Type of the error class.
|
||||
*
|
||||
* Included for backwards compatibility.
|
||||
*/
|
||||
typedef QmuParserError exception_type;
|
||||
|
||||
explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
|
||||
:std::numpunct<TChar>()
|
||||
,m_nGroup(nGroup)
|
||||
,m_cDecPoint(cDecSep)
|
||||
,m_cThousandsSep(cThousandsSep)
|
||||
{}
|
||||
QmuParserBase();
|
||||
QmuParserBase(const QmuParserBase &a_Parser);
|
||||
QmuParserBase& operator=(const QmuParserBase &a_Parser);
|
||||
virtual ~QmuParserBase();
|
||||
|
||||
static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
|
||||
qreal Eval() const;
|
||||
qreal* Eval(int &nStackSize) const;
|
||||
void Eval(qreal *results, int nBulkSize);
|
||||
int GetNumResults() const;
|
||||
void SetExpr(const QString &a_sExpr);
|
||||
void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
|
||||
void SetDecSep(char_type cDecSep);
|
||||
void SetThousandsSep(char_type cThousandsSep = 0);
|
||||
void ResetLocale();
|
||||
void EnableOptimizer(bool a_bIsOn=true);
|
||||
void EnableBuiltInOprt(bool a_bIsOn=true);
|
||||
bool HasBuiltInOprt() const;
|
||||
void AddValIdent(identfun_type a_pCallback);
|
||||
void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0,
|
||||
EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
|
||||
void DefineConst(const QString &a_sName, qreal a_fVal);
|
||||
void DefineStrConst(const QString &a_sName, const QString &a_strVal);
|
||||
void DefineVar(const QString &a_sName, qreal *a_fVar);
|
||||
void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
|
||||
void DefineInfixOprt(const QString &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 QString &a_strVarName);
|
||||
const varmap_type& GetUsedVar() const;
|
||||
const varmap_type& GetVar() const;
|
||||
const valmap_type& GetConst() const;
|
||||
const QString& GetExpr() const;
|
||||
const funmap_type& GetFunDef() const;
|
||||
QString GetVersion(EParserVersionInfo eInfo = pviFULL) const;
|
||||
const QStringList& GetOprtDef() const;
|
||||
void DefineNameChars(const QString &a_szCharset);
|
||||
void DefineOprtChars(const QString &a_szCharset);
|
||||
void DefineInfixOprtChars(const QString &a_szCharset);
|
||||
const QString& ValidNameChars() const;
|
||||
const QString& ValidOprtChars() const;
|
||||
const QString& ValidInfixOprtChars() const;
|
||||
void SetArgSep(char_type cArgSep);
|
||||
QChar GetArgSep() const;
|
||||
void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const;
|
||||
/**
|
||||
* @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun,
|
||||
* bool a_bAllowOpt = true)
|
||||
* @brief Define a parser function without arguments.
|
||||
* @param a_strName Name of the function
|
||||
* @param a_pFun Pointer to the callback function
|
||||
* @param a_bAllowOpt A flag indicating this function may be optimized
|
||||
*/
|
||||
template<typename T>
|
||||
void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true)
|
||||
{
|
||||
AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
|
||||
}
|
||||
protected:
|
||||
static const QStringList c_DefaultOprt;
|
||||
static std::locale s_locale; ///< The locale used by the parser
|
||||
static bool g_DbgDumpCmdCode;
|
||||
static bool g_DbgDumpStack;
|
||||
void Init();
|
||||
virtual void InitCharSets() = 0;
|
||||
virtual void InitFun() = 0;
|
||||
virtual void InitConst() = 0;
|
||||
virtual void InitOprt() = 0;
|
||||
virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd);
|
||||
/**
|
||||
* @brief A facet class used to change decimal and thousands separator.
|
||||
*/
|
||||
template<class TChar>
|
||||
class change_dec_sep : public std::numpunct<TChar>
|
||||
{
|
||||
public:
|
||||
explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
|
||||
:std::numpunct<TChar>(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep)
|
||||
{}
|
||||
protected:
|
||||
virtual char_type do_decimal_point() const
|
||||
{
|
||||
return m_cDecPoint;
|
||||
}
|
||||
|
||||
virtual char_type do_decimal_point() const
|
||||
{
|
||||
return m_cDecPoint;
|
||||
}
|
||||
|
||||
virtual char_type do_thousands_sep() const
|
||||
{
|
||||
return m_cThousandsSep;
|
||||
}
|
||||
|
||||
virtual std::string do_grouping() const
|
||||
{
|
||||
return std::string(1, m_nGroup);
|
||||
}
|
||||
virtual char_type do_thousands_sep() const
|
||||
{
|
||||
return m_cThousandsSep;
|
||||
}
|
||||
|
||||
virtual std::string do_grouping() const
|
||||
{
|
||||
return std::string(1, m_nGroup);
|
||||
}
|
||||
private:
|
||||
int m_nGroup;
|
||||
char_type m_cDecPoint;
|
||||
char_type m_cThousandsSep;
|
||||
};
|
||||
private:
|
||||
/**
|
||||
* @brief Typedef for the parse functions.
|
||||
*
|
||||
* The parse function do the actual work. The parser exchanges
|
||||
* the function pointer to the parser function depending on
|
||||
* which state it is in. (i.e. bytecode parser vs. string parser)
|
||||
*/
|
||||
typedef qreal (QmuParserBase::*ParseFunction)() const;
|
||||
|
||||
int m_nGroup;
|
||||
char_type m_cDecPoint;
|
||||
char_type m_cThousandsSep;
|
||||
/**
|
||||
* @brief Type used for storing an array of values.
|
||||
*/
|
||||
typedef QVector<qreal> valbuf_type;
|
||||
|
||||
/**
|
||||
* @brief Type for a vector of strings.
|
||||
*/
|
||||
typedef QVector<QString> stringbuf_type;
|
||||
|
||||
/**
|
||||
* @brief Typedef for the token reader.
|
||||
*/
|
||||
typedef QmuParserTokenReader token_reader_type;
|
||||
|
||||
/**
|
||||
* @brief Type used for parser tokens.
|
||||
*/
|
||||
typedef QmuParserToken<qreal, QString> token_type;
|
||||
|
||||
/**
|
||||
* @brief Maximum number of threads spawned by OpenMP when using the bulk mode.
|
||||
*/
|
||||
static const int s_MaxNumOpenMPThreads = 4;
|
||||
|
||||
/**
|
||||
* @brief Pointer to the parser function.
|
||||
*
|
||||
* Eval() calls the function whose address is stored there.
|
||||
*/
|
||||
mutable ParseFunction m_pParseFormula;
|
||||
mutable QmuParserByteCode m_vRPN; ///< The Bytecode class.
|
||||
mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
|
||||
stringbuf_type m_vStringVarBuf;
|
||||
|
||||
std::auto_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
|
||||
|
||||
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_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
|
||||
|
||||
QString m_sNameChars; ///< Charset for names
|
||||
QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens
|
||||
QString m_sInfixOprtChars; ///< Charset for infix operator tokens
|
||||
|
||||
mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses
|
||||
|
||||
// items merely used for caching state information
|
||||
mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
|
||||
mutable int m_nFinalResultIdx;
|
||||
|
||||
void Assign(const QmuParserBase &a_Parser);
|
||||
void InitTokenReader();
|
||||
void ReInit() const;
|
||||
void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback,
|
||||
funmap_type &a_Storage, const QString &a_szCharSet );
|
||||
void ApplyRemainingOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||
void ApplyBinOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||
void ApplyIfElse(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||
void ApplyFunc(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal, int iArgCount) const;
|
||||
token_type ApplyStrFunc(const token_type &a_FunTok, const QVector<token_type> &a_vArg) const;
|
||||
int GetOprtPrecedence(const token_type &a_Tok) const;
|
||||
EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const;
|
||||
void CreateRPN() const;
|
||||
qreal ParseString() const;
|
||||
qreal ParseCmdCode() const;
|
||||
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
|
||||
void CheckName(const QString &a_strName, const QString &a_CharSet) const;
|
||||
void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback,
|
||||
const QString &a_szCharSet) const;
|
||||
void StackDump(const QStack<token_type > &a_stVal, const QStack<token_type > &a_stOprt) const;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void Assign(const QmuParserBase &a_Parser);
|
||||
void InitTokenReader();
|
||||
void ReInit() const;
|
||||
|
||||
void AddCallback(const QString &a_strName,
|
||||
const QmuParserCallback &a_Callback,
|
||||
funmap_type &a_Storage,
|
||||
const QString &a_szCharSet );
|
||||
|
||||
void ApplyRemainingOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||
void ApplyBinOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||
void ApplyIfElse(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||
void ApplyFunc(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal, int iArgCount) const;
|
||||
|
||||
token_type ApplyStrFunc(const token_type &a_FunTok,
|
||||
const QVector<token_type> &a_vArg) const;
|
||||
|
||||
int GetOprtPrecedence(const token_type &a_Tok) const;
|
||||
EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const;
|
||||
|
||||
void CreateRPN() const;
|
||||
|
||||
qreal ParseString() const;
|
||||
qreal ParseCmdCode() const;
|
||||
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
|
||||
|
||||
void CheckName(const QString &a_strName, const QString &a_CharSet) const;
|
||||
void CheckOprt(const QString &a_sName,
|
||||
const QmuParserCallback &a_Callback,
|
||||
const QString &a_szCharSet) const;
|
||||
|
||||
void StackDump(const QStack<token_type > &a_stVal,
|
||||
const QStack<token_type > &a_stOprt) const;
|
||||
|
||||
/** \brief Pointer to the parser function.
|
||||
|
||||
Eval() calls the function whose address is stored there.
|
||||
*/
|
||||
mutable ParseFunction m_pParseFormula;
|
||||
mutable QmuParserByteCode m_vRPN; ///< The Bytecode class.
|
||||
mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
|
||||
stringbuf_type m_vStringVarBuf;
|
||||
|
||||
std::auto_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
|
||||
|
||||
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_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
|
||||
|
||||
QString m_sNameChars; ///< Charset for names
|
||||
QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens
|
||||
QString m_sInfixOprtChars; ///< Charset for infix operator tokens
|
||||
|
||||
mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses
|
||||
|
||||
// items merely used for caching state information
|
||||
mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
|
||||
mutable int m_nFinalResultIdx;
|
||||
};
|
||||
|
||||
} // namespace qmu
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,116 +23,104 @@
|
|||
#ifndef QMUPARSERBYTECODE_H
|
||||
#define QMUPARSERBYTECODE_H
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <stack>
|
||||
|
||||
#include "qmuparserdef.h"
|
||||
#include "qmuparsererror.h"
|
||||
#include "qmuparsertoken.h"
|
||||
|
||||
/** \file
|
||||
\brief Definition of the parser bytecode class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Definition of the parser bytecode class.
|
||||
*/
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
struct SToken
|
||||
{
|
||||
ECmdCode Cmd;
|
||||
int StackPos;
|
||||
struct SToken
|
||||
{
|
||||
ECmdCode Cmd;
|
||||
int StackPos;
|
||||
|
||||
union
|
||||
{
|
||||
struct //SValData
|
||||
{
|
||||
qreal *ptr;
|
||||
qreal data;
|
||||
qreal data2;
|
||||
} Val;
|
||||
union
|
||||
{
|
||||
struct //SValData
|
||||
{
|
||||
qreal *ptr;
|
||||
qreal data;
|
||||
qreal data2;
|
||||
} Val;
|
||||
|
||||
struct //SFunData
|
||||
{
|
||||
// Note: generic_fun_type is merely a placeholder. The real type could be
|
||||
// anything between gun_type1 and fun_type9. I can't use a void
|
||||
// pointer due to constraints in the ANSI standard which allows
|
||||
// data pointers and function pointers to differ in size.
|
||||
generic_fun_type ptr;
|
||||
int argc;
|
||||
int idx;
|
||||
} Fun;
|
||||
struct //SFunData
|
||||
{
|
||||
// Note: generic_fun_type is merely a placeholder. The real type could be
|
||||
// anything between gun_type1 and fun_type9. I can't use a void
|
||||
// pointer due to constraints in the ANSI standard which allows
|
||||
// data pointers and function pointers to differ in size.
|
||||
generic_fun_type ptr;
|
||||
int argc;
|
||||
int idx;
|
||||
} Fun;
|
||||
|
||||
struct //SOprtData
|
||||
{
|
||||
qreal *ptr;
|
||||
int offset;
|
||||
} Oprt;
|
||||
};
|
||||
};
|
||||
struct //SOprtData
|
||||
{
|
||||
qreal *ptr;
|
||||
int offset;
|
||||
} Oprt;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/** \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-2013 Ingo Berg
|
||||
*/
|
||||
/**
|
||||
* @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-2013 Ingo Berg
|
||||
*/
|
||||
class QmuParserByteCode
|
||||
{
|
||||
private:
|
||||
|
||||
/** \brief Token type for internal use only. */
|
||||
/** @brief Token type for internal use only. */
|
||||
typedef QmuParserToken<qreal, string_type> token_type;
|
||||
|
||||
/** \brief Token vector for storing the RPN. */
|
||||
/** @brief Token vector for storing the RPN. */
|
||||
typedef QVector<SToken> rpn_type;
|
||||
|
||||
/** \brief Position in the Calculation array. */
|
||||
/** @brief Position in the Calculation array. */
|
||||
unsigned m_iStackPos;
|
||||
|
||||
/** \brief Maximum size needed for the stack. */
|
||||
/** @brief Maximum size needed for the stack. */
|
||||
std::size_t m_iMaxStackSize;
|
||||
|
||||
/** \brief The actual rpn storage. */
|
||||
/** @brief The actual rpn storage. */
|
||||
rpn_type m_vRPN;
|
||||
|
||||
bool m_bEnableOptimizer;
|
||||
|
||||
void ConstantFolding(ECmdCode a_Oprt);
|
||||
|
||||
public:
|
||||
|
||||
QmuParserByteCode();
|
||||
QmuParserByteCode(const QmuParserByteCode &a_ByteCode);
|
||||
QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode);
|
||||
void Assign(const QmuParserByteCode &a_ByteCode);
|
||||
|
||||
void AddVar(qreal *a_pVar);
|
||||
void AddVal(qreal a_fVal);
|
||||
void AddOp(ECmdCode a_Oprt);
|
||||
void AddIfElse(ECmdCode a_Oprt);
|
||||
void AddAssignOp(qreal *a_pVar);
|
||||
void AddFun(generic_fun_type a_pFun, int a_iArgc);
|
||||
void AddBulkFun(generic_fun_type a_pFun, int a_iArgc);
|
||||
void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx);
|
||||
|
||||
void EnableOptimizer(bool bStat);
|
||||
|
||||
void Finalize();
|
||||
void clear();
|
||||
std::size_t GetMaxStackSize() const;
|
||||
std::size_t GetSize() const;
|
||||
|
||||
void Assign(const QmuParserByteCode &a_ByteCode);
|
||||
void AddVar(qreal *a_pVar);
|
||||
void AddVal(qreal a_fVal);
|
||||
void AddOp(ECmdCode a_Oprt);
|
||||
void AddIfElse(ECmdCode a_Oprt);
|
||||
void AddAssignOp(qreal *a_pVar);
|
||||
void AddFun(generic_fun_type a_pFun, int a_iArgc);
|
||||
void AddBulkFun(generic_fun_type a_pFun, int a_iArgc);
|
||||
void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx);
|
||||
void EnableOptimizer(bool bStat);
|
||||
void Finalize();
|
||||
void clear();
|
||||
std::size_t GetMaxStackSize() const;
|
||||
std::size_t GetSize() const;
|
||||
const SToken* GetBase() const;
|
||||
void AsciiDump();
|
||||
void AsciiDump();
|
||||
};
|
||||
|
||||
} // namespace qmu
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -22,439 +22,301 @@
|
|||
|
||||
#include "qmuparsercallback.h"
|
||||
|
||||
/** \file
|
||||
\brief Implementation of the parser callback class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Implementation of the parser callback class.
|
||||
*/
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(fun_type0 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(0)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( fun_type0 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(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_eOprtAsct(oaNONE)
|
||||
,m_iCode(a_iCode)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( 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_eOprtAsct ( oaNONE ), m_iCode ( a_iCode ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Constructor for constructing funcstion callbacks taking two arguments.
|
||||
\throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(2)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Constructor for constructing funcstion callbacks taking two arguments.
|
||||
* @throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Constructor for constructing binary operator callbacks.
|
||||
\param a_pFun Pointer to a static function taking two arguments
|
||||
\param a_bAllowOpti A flag indicating this funcation can be optimized
|
||||
\param a_iPrec The operator precedence
|
||||
\param a_eOprtAsct The operators associativity
|
||||
\throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback(fun_type2 a_pFun,
|
||||
bool a_bAllowOpti,
|
||||
int a_iPrec,
|
||||
EOprtAssociativity a_eOprtAsct)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(2)
|
||||
,m_iPri(a_iPrec)
|
||||
,m_eOprtAsct(a_eOprtAsct)
|
||||
,m_iCode(cmOPRT_BIN)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Constructor for constructing binary operator callbacks.
|
||||
* @param a_pFun Pointer to a static function taking two arguments
|
||||
* @param a_bAllowOpti A flag indicating this funcation can be optimized
|
||||
* @param a_iPrec The operator precedence
|
||||
* @param a_eOprtAsct The operators associativity
|
||||
* @throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec,
|
||||
EOprtAssociativity a_eOprtAsct )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ),
|
||||
m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(fun_type3 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(3)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( fun_type3 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(fun_type4 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(4)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( fun_type4 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(fun_type5 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(5)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( fun_type5 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(fun_type6 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(6)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( fun_type6 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(fun_type7 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(7)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( fun_type7 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(fun_type8 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(8)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( fun_type8 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(fun_type9 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(9)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( fun_type9 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(fun_type10 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(10)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( fun_type10 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(0)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type0 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(1)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Constructor for constructing funcstion callbacks taking two arguments.
|
||||
* @throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type2 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Constructor for constructing funcstion callbacks taking two arguments.
|
||||
\throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(2)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type3 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(3)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type4 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type5 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(4)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type6 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type7 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(5)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type8 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(6)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type9 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(7)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( bulkfun_type10 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(8)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( multfun_type a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(9)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( strfun_type1 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(10)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_BULK)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( strfun_type2 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ),
|
||||
m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback ( strfun_type3 a_pFun, bool a_bAllowOpti )
|
||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ),
|
||||
m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(multfun_type a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(-1)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC)
|
||||
,m_iType(tpDBL)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Default constructor.
|
||||
* @throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback()
|
||||
: m_pFun ( 0 ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ),
|
||||
m_bAllowOpti ( 0 )
|
||||
{}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Copy constructor.
|
||||
* @throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback ( const QmuParserCallback &ref )
|
||||
{
|
||||
m_pFun = ref.m_pFun;
|
||||
m_iArgc = ref.m_iArgc;
|
||||
m_bAllowOpti = ref.m_bAllowOpti;
|
||||
m_iCode = ref.m_iCode;
|
||||
m_iType = ref.m_iType;
|
||||
m_iPri = ref.m_iPri;
|
||||
m_eOprtAsct = ref.m_eOprtAsct;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(0)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_STR)
|
||||
,m_iType(tpSTR)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Clone this instance and return a pointer to the new instance.
|
||||
*/
|
||||
QmuParserCallback* QmuParserCallback::Clone() const
|
||||
{
|
||||
return new QmuParserCallback ( *this );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return tru if the function is conservative.
|
||||
*
|
||||
* Conservative functions return always the same result for the same argument.
|
||||
* @throw nothrow
|
||||
*/
|
||||
bool QmuParserCallback::IsOptimizable() const
|
||||
{
|
||||
return m_bAllowOpti;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(1)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_STR)
|
||||
,m_iType(tpSTR)
|
||||
,m_bAllowOpti(a_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* QmuParserCallback::GetAddr() const
|
||||
{
|
||||
return m_pFun;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return the callback code.
|
||||
*/
|
||||
ECmdCode QmuParserCallback::GetCode() const
|
||||
{
|
||||
return m_iCode;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserCallback::QmuParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti)
|
||||
:m_pFun((void*)a_pFun)
|
||||
,m_iArgc(2)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmFUNC_STR)
|
||||
,m_iType(tpSTR)
|
||||
,m_bAllowOpti(a_bAllowOpti)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
ETypeCode QmuParserCallback::GetType() const
|
||||
{
|
||||
return m_iType;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return the operator precedence.
|
||||
* @throw nothrown
|
||||
*
|
||||
* Only valid if the callback token is an operator token (binary or infix).
|
||||
*/
|
||||
int QmuParserCallback::GetPri() const
|
||||
{
|
||||
return m_iPri;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Default constructor.
|
||||
\throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback()
|
||||
:m_pFun(0)
|
||||
,m_iArgc(0)
|
||||
,m_iPri(-1)
|
||||
,m_eOprtAsct(oaNONE)
|
||||
,m_iCode(cmUNKNOWN)
|
||||
,m_iType(tpVOID)
|
||||
,m_bAllowOpti(0)
|
||||
{}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return the operators associativity.
|
||||
* @throw nothrown
|
||||
*
|
||||
* Only valid if the callback token is a binary operator token.
|
||||
*/
|
||||
EOprtAssociativity QmuParserCallback::GetAssociativity() const
|
||||
{
|
||||
return m_eOprtAsct;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Copy constructor.
|
||||
\throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback(const QmuParserCallback &ref)
|
||||
{
|
||||
m_pFun = ref.m_pFun;
|
||||
m_iArgc = ref.m_iArgc;
|
||||
m_bAllowOpti = ref.m_bAllowOpti;
|
||||
m_iCode = ref.m_iCode;
|
||||
m_iType = ref.m_iType;
|
||||
m_iPri = ref.m_iPri;
|
||||
m_eOprtAsct = ref.m_eOprtAsct;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Clone this instance and return a pointer to the new instance. */
|
||||
QmuParserCallback* QmuParserCallback::Clone() const
|
||||
{
|
||||
return new QmuParserCallback(*this);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Return tru if the function is conservative.
|
||||
|
||||
Conservative functions return always the same result for the same argument.
|
||||
\throw nothrow
|
||||
*/
|
||||
bool QmuParserCallback::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* QmuParserCallback::GetAddr() const
|
||||
{
|
||||
return m_pFun;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Return the callback code. */
|
||||
ECmdCode QmuParserCallback::GetCode() const
|
||||
{
|
||||
return m_iCode;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
ETypeCode QmuParserCallback::GetType() const
|
||||
{
|
||||
return m_iType;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Return the operator precedence.
|
||||
\throw nothrown
|
||||
|
||||
Only valid if the callback token is an operator token (binary or infix).
|
||||
*/
|
||||
int QmuParserCallback::GetPri() const
|
||||
{
|
||||
return m_iPri;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Return the operators associativity.
|
||||
\throw nothrown
|
||||
|
||||
Only valid if the callback token is a binary operator token.
|
||||
*/
|
||||
EOprtAssociativity QmuParserCallback::GetAssociativity() const
|
||||
{
|
||||
return m_eOprtAsct;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Returns the number of function Arguments. */
|
||||
int QmuParserCallback::GetArgc() const
|
||||
{
|
||||
return m_iArgc;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Returns the number of function Arguments.
|
||||
*/
|
||||
int QmuParserCallback::GetArgc() const
|
||||
{
|
||||
return m_iArgc;
|
||||
}
|
||||
} // namespace qmu
|
||||
|
|
|
@ -25,25 +25,24 @@
|
|||
|
||||
#include "qmuparserdef.h"
|
||||
|
||||
/** \file
|
||||
\brief Definition of the parser callback class.
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* @brief Definition of the parser callback class.
|
||||
*/
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
|
||||
/** \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.
|
||||
|
||||
\author (C) 2004-2011 Ingo Berg
|
||||
*/
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @author (C) 2004-2011 Ingo Berg
|
||||
*/
|
||||
class QmuParserCallback
|
||||
{
|
||||
public:
|
||||
|
@ -80,23 +79,22 @@ public:
|
|||
QmuParserCallback(const QmuParserCallback &a_Fun);
|
||||
|
||||
QmuParserCallback* Clone() const;
|
||||
|
||||
bool IsOptimizable() const;
|
||||
void* GetAddr() const;
|
||||
ECmdCode GetCode() const;
|
||||
ETypeCode GetType() const;
|
||||
int GetPri() const;
|
||||
bool IsOptimizable() const;
|
||||
void* GetAddr() const;
|
||||
ECmdCode GetCode() const;
|
||||
ETypeCode GetType() const;
|
||||
int GetPri() const;
|
||||
EOprtAssociativity GetAssociativity() const;
|
||||
int GetArgc() 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.
|
||||
*/
|
||||
/**
|
||||
* @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.
|
||||
EOprtAssociativity m_eOprtAsct; ///< Operator associativity; Valid only for binary operators
|
||||
|
@ -105,8 +103,10 @@ private:
|
|||
bool m_bAllowOpti; ///< Flag indication optimizeability
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Container for Callback objects. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Container for Callback objects.
|
||||
*/
|
||||
typedef std::map<QString, QmuParserCallback> funmap_type;
|
||||
|
||||
} // namespace qmu
|
||||
|
|
|
@ -23,17 +23,13 @@
|
|||
#ifndef QMUPDEF_H
|
||||
#define QMUPDEF_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
#include "qmuparserfixes.h"
|
||||
|
||||
/** \file
|
||||
\brief This file contains standard definitions used by the parser.
|
||||
/** @file
|
||||
@brief This file contains standard definitions used by the parser.
|
||||
*/
|
||||
|
||||
#define QMUP_VERSION "2.2.3"
|
||||
|
@ -41,32 +37,32 @@
|
|||
|
||||
#define QMUP_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
/** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */
|
||||
/** @brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */
|
||||
//#define QMUP_MATH_EXCEPTIONS
|
||||
|
||||
/** \brief Activate this option in order to compile with OpenMP support.
|
||||
/** @brief Activate this option in order to compile with OpenMP support.
|
||||
|
||||
OpenMP is used only in the bulk mode it may increase the performance a bit.
|
||||
*/
|
||||
//#define MUP_USE_OPENMP
|
||||
|
||||
#if defined(_UNICODE)
|
||||
/** \brief Definition of the basic parser string type. */
|
||||
#define QMUP_STRING_TYPE std::wstring
|
||||
/** @brief Definition of the basic parser string type. */
|
||||
#define QMUP_STRING_TYPE std::wstring
|
||||
#else
|
||||
/** \brief Definition of the basic parser string type. */
|
||||
#define QMUP_STRING_TYPE std::string
|
||||
/** @brief Definition of the basic parser string type. */
|
||||
#define QMUP_STRING_TYPE std::string
|
||||
#endif
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Bytecode values.
|
||||
//------------------------------------------------------------------------------
|
||||
/** @brief Bytecode values.
|
||||
|
||||
\attention The order of the operator entries must match the order in ParserBase::c_DefaultOprt!
|
||||
*/
|
||||
enum ECmdCode
|
||||
{
|
||||
\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.
|
||||
|
@ -110,38 +106,38 @@ namespace qmu
|
|||
cmOPRT_INFIX, ///< code for infix operators
|
||||
cmEND, ///< end of formula
|
||||
cmUNKNOWN ///< uninitialized item
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Types internally used by the parser.
|
||||
*/
|
||||
enum ETypeCode
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
/** @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.
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
enum EParserVersionInfo
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
enum EParserVersionInfo
|
||||
{
|
||||
pviBRIEF,
|
||||
pviFULL
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Parser operator precedence values. */
|
||||
enum EOprtAssociativity
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
/** @brief Parser operator precedence values. */
|
||||
enum EOprtAssociativity
|
||||
{
|
||||
oaLEFT = 0,
|
||||
oaRIGHT = 1,
|
||||
oaNONE = 2
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Parser operator precedence values. */
|
||||
enum EOprtPrecedence
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
/** @brief Parser operator precedence values. */
|
||||
enum EOprtPrecedence
|
||||
{
|
||||
// binary operators
|
||||
prLOR = 1,
|
||||
prLAND = 2,
|
||||
|
@ -154,127 +150,125 @@ namespace qmu
|
|||
// infix operators
|
||||
prINFIX = 6, ///< Signs have a higher priority than ADD_SUB, but lower than power operator
|
||||
prPOSTFIX = 6 ///< Postfix operator priority (currently unused)
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// basic types
|
||||
//------------------------------------------------------------------------------
|
||||
// basic types
|
||||
|
||||
/** \brief The stringtype used by the parser.
|
||||
/** @brief The stringtype used by the parser.
|
||||
|
||||
Depends on wether UNICODE is used or not.
|
||||
*/
|
||||
typedef QMUP_STRING_TYPE string_type;
|
||||
Depends on wether UNICODE is used or not.
|
||||
*/
|
||||
typedef QMUP_STRING_TYPE string_type;
|
||||
|
||||
/** \brief The character type used by the parser.
|
||||
/** @brief The character type used by the parser.
|
||||
|
||||
Depends on wether UNICODE is used or not.
|
||||
*/
|
||||
typedef string_type::value_type char_type;
|
||||
Depends on wether UNICODE is used or not.
|
||||
*/
|
||||
typedef string_type::value_type char_type;
|
||||
|
||||
/** \brief Typedef for easily using stringstream that respect the parser stringtype. */
|
||||
typedef std::basic_stringstream<char_type,
|
||||
std::char_traits<char_type>,
|
||||
std::allocator<char_type> > stringstream_type;
|
||||
/** @brief Typedef for easily using stringstream that respect the parser stringtype. */
|
||||
typedef std::basic_stringstream < char_type, std::char_traits<char_type>, std::allocator<char_type> > stringstream_type;
|
||||
|
||||
// Data container types
|
||||
// Data container types
|
||||
|
||||
/** \brief Type used for storing variables. */
|
||||
typedef std::map<QString, qreal*> varmap_type;
|
||||
/** @brief Type used for storing variables. */
|
||||
typedef std::map<QString, qreal*> varmap_type;
|
||||
|
||||
/** \brief Type used for storing constants. */
|
||||
typedef std::map<QString, qreal> valmap_type;
|
||||
/** @brief Type used for storing constants. */
|
||||
typedef std::map<QString, qreal> valmap_type;
|
||||
|
||||
/** \brief Type for assigning a string name to an index in the internal string table. */
|
||||
typedef std::map<QString, int> strmap_type;
|
||||
/** @brief Type for assigning a string name to an index in the internal string table. */
|
||||
typedef std::map<QString, int> strmap_type;
|
||||
|
||||
// Parser callbacks
|
||||
// Parser callbacks
|
||||
|
||||
/** \brief Callback type used for functions without arguments. */
|
||||
typedef qreal (*generic_fun_type)();
|
||||
/** @brief Callback type used for functions without arguments. */
|
||||
typedef qreal ( *generic_fun_type ) ();
|
||||
|
||||
/** \brief Callback type used for functions without arguments. */
|
||||
typedef qreal (*fun_type0)();
|
||||
/** @brief Callback type used for functions without arguments. */
|
||||
typedef qreal ( *fun_type0 ) ();
|
||||
|
||||
/** \brief Callback type used for functions with a single arguments. */
|
||||
typedef qreal (*fun_type1)(qreal);
|
||||
/** @brief Callback type used for functions with a single arguments. */
|
||||
typedef qreal ( *fun_type1 ) ( qreal );
|
||||
|
||||
/** \brief Callback type used for functions with two arguments. */
|
||||
typedef qreal (*fun_type2)(qreal, qreal);
|
||||
/** @brief Callback type used for functions with two arguments. */
|
||||
typedef qreal ( *fun_type2 ) ( qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with three arguments. */
|
||||
typedef qreal (*fun_type3)(qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with three arguments. */
|
||||
typedef qreal ( *fun_type3 ) ( qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with four arguments. */
|
||||
typedef qreal (*fun_type4)(qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with four arguments. */
|
||||
typedef qreal ( *fun_type4 ) ( qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*fun_type5)(qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *fun_type5 ) ( qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*fun_type6)(qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *fun_type6 ) ( qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*fun_type7)(qreal, qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *fun_type7 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*fun_type8)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *fun_type8 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*fun_type9)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *fun_type9 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*fun_type10)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *fun_type10 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions without arguments. */
|
||||
typedef qreal (*bulkfun_type0)(int, int);
|
||||
/** @brief Callback type used for functions without arguments. */
|
||||
typedef qreal ( *bulkfun_type0 ) ( int, int );
|
||||
|
||||
/** \brief Callback type used for functions with a single arguments. */
|
||||
typedef qreal (*bulkfun_type1)(int, int, qreal);
|
||||
/** @brief Callback type used for functions with a single arguments. */
|
||||
typedef qreal ( *bulkfun_type1 ) ( int, int, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with two arguments. */
|
||||
typedef qreal (*bulkfun_type2)(int, int, qreal, qreal);
|
||||
/** @brief Callback type used for functions with two arguments. */
|
||||
typedef qreal ( *bulkfun_type2 ) ( int, int, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with three arguments. */
|
||||
typedef qreal (*bulkfun_type3)(int, int, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with three arguments. */
|
||||
typedef qreal ( *bulkfun_type3 ) ( int, int, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with four arguments. */
|
||||
typedef qreal (*bulkfun_type4)(int, int, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with four arguments. */
|
||||
typedef qreal ( *bulkfun_type4 ) ( int, int, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*bulkfun_type5)(int, int, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *bulkfun_type5 ) ( int, int, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*bulkfun_type6)(int, int, qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *bulkfun_type6 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*bulkfun_type7)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *bulkfun_type7 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*bulkfun_type8)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *bulkfun_type8 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*bulkfun_type9)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *bulkfun_type9 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with five arguments. */
|
||||
typedef qreal (*bulkfun_type10)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
|
||||
/** @brief Callback type used for functions with five arguments. */
|
||||
typedef qreal ( *bulkfun_type10 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with a variable argument list. */
|
||||
typedef qreal (*multfun_type)(const qreal*, int);
|
||||
/** @brief Callback type used for functions with a variable argument list. */
|
||||
typedef qreal ( *multfun_type ) ( const qreal*, int );
|
||||
|
||||
/** \brief Callback type used for functions taking a string as an argument. */
|
||||
typedef qreal (*strfun_type1)(const QString &);
|
||||
/** @brief Callback type used for functions taking a string as an argument. */
|
||||
typedef qreal ( *strfun_type1 ) ( const QString & );
|
||||
|
||||
/** \brief Callback type used for functions taking a string and a value as arguments. */
|
||||
typedef qreal (*strfun_type2)(const QString &, qreal);
|
||||
/** @brief Callback type used for functions taking a string and a value as arguments. */
|
||||
typedef qreal ( *strfun_type2 ) ( const QString &, qreal );
|
||||
|
||||
/** \brief Callback type used for functions taking a string and two values as arguments. */
|
||||
typedef qreal (*strfun_type3)(const QString &, qreal, qreal);
|
||||
/** @brief Callback type used for functions taking a string and two values as arguments. */
|
||||
typedef qreal ( *strfun_type3 ) ( const QString &, qreal, qreal );
|
||||
|
||||
/** \brief Callback used for functions that identify values in a string. */
|
||||
typedef int (*identfun_type)(const QString &sExpr, int *nPos, qreal *fVal);
|
||||
/** @brief Callback used for functions that identify values in a string. */
|
||||
typedef int ( *identfun_type ) ( const QString &sExpr, int *nPos, qreal *fVal );
|
||||
|
||||
/** \brief Callback used for variable creation factory functions. */
|
||||
typedef qreal* (*facfun_type)(const QString &, void*);
|
||||
/** @brief Callback used for variable creation factory functions. */
|
||||
typedef qreal* ( *facfun_type ) ( const QString &, void* );
|
||||
} // end of namespace
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,303 +24,306 @@
|
|||
|
||||
#include <QTextStream>
|
||||
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
const QmuParserErrorMsg QmuParserErrorMsg::m_Instance;
|
||||
const QmuParserErrorMsg QmuParserErrorMsg::m_Instance;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const QmuParserErrorMsg& QmuParserErrorMsg::Instance()
|
||||
{
|
||||
return m_Instance;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString QmuParserErrorMsg::operator[](unsigned a_iIdx) const
|
||||
{
|
||||
return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : QString();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserErrorMsg::~QmuParserErrorMsg()
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Assignement operator is deactivated.
|
||||
*/
|
||||
QmuParserErrorMsg& QmuParserErrorMsg::operator=(const QmuParserErrorMsg& )
|
||||
{
|
||||
assert(false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserErrorMsg::QmuParserErrorMsg(const QmuParserErrorMsg&)
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
QmuParserErrorMsg::QmuParserErrorMsg()
|
||||
:m_vErrMsg(0)
|
||||
{
|
||||
m_vErrMsg.resize(ecCOUNT);
|
||||
|
||||
m_vErrMsg[ecUNASSIGNABLE_TOKEN] = "Unexpected token \"$TOK$\" found at position $POS$.";
|
||||
m_vErrMsg[ecINTERNAL_ERROR] = "Internal error";
|
||||
m_vErrMsg[ecINVALID_NAME] = "Invalid function-, variable- or constant name: \"$TOK$\".";
|
||||
m_vErrMsg[ecINVALID_BINOP_IDENT] = "Invalid binary operator identifier: \"$TOK$\".";
|
||||
m_vErrMsg[ecINVALID_INFIX_IDENT] = "Invalid infix operator identifier: \"$TOK$\".";
|
||||
m_vErrMsg[ecINVALID_POSTFIX_IDENT] = "Invalid postfix operator identifier: \"$TOK$\".";
|
||||
m_vErrMsg[ecINVALID_FUN_PTR] = "Invalid pointer to callback function.";
|
||||
m_vErrMsg[ecEMPTY_EXPRESSION] = "Expression is empty.";
|
||||
m_vErrMsg[ecINVALID_VAR_PTR] = "Invalid pointer to variable.";
|
||||
m_vErrMsg[ecUNEXPECTED_OPERATOR] = "Unexpected operator \"$TOK$\" found at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_EOF] = "Unexpected end of expression at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_ARG_SEP] = "Unexpected argument separator at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_PARENS] = "Unexpected parenthesis \"$TOK$\" at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_FUN] = "Unexpected function \"$TOK$\" at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_VAL] = "Unexpected value \"$TOK$\" found at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_VAR] = "Unexpected variable \"$TOK$\" found at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_ARG] = "Function arguments used without a function (position: $POS$)";
|
||||
m_vErrMsg[ecMISSING_PARENS] = "Missing parenthesis";
|
||||
m_vErrMsg[ecTOO_MANY_PARAMS] = "Too many parameters for function \"$TOK$\" at expression position $POS$";
|
||||
m_vErrMsg[ecTOO_FEW_PARAMS] = "Too few parameters for function \"$TOK$\" at expression position $POS$";
|
||||
m_vErrMsg[ecDIV_BY_ZERO] = "Divide by zero";
|
||||
m_vErrMsg[ecDOMAIN_ERROR] = "Domain error";
|
||||
m_vErrMsg[ecNAME_CONFLICT] = "Name conflict";
|
||||
m_vErrMsg[ecOPT_PRI] = "Invalid value for operator priority (must be greater or equal to zero).";
|
||||
m_vErrMsg[ecBUILTIN_OVERLOAD] = "user defined binary operator \"$TOK$\" conflicts with a built in operator.";
|
||||
m_vErrMsg[ecUNEXPECTED_STR] = "Unexpected string token found at position $POS$.";
|
||||
m_vErrMsg[ecUNTERMINATED_STRING] = "Unterminated string starting at position $POS$.";
|
||||
m_vErrMsg[ecSTRING_EXPECTED] = "String function called with a non string type of argument.";
|
||||
m_vErrMsg[ecVAL_EXPECTED] = "String value used where a numerical argument is expected.";
|
||||
m_vErrMsg[ecOPRT_TYPE_CONFLICT] = "No suitable overload for operator \"$TOK$\" at position $POS$.";
|
||||
m_vErrMsg[ecSTR_RESULT] = "Function result is a string.";
|
||||
m_vErrMsg[ecGENERIC] = "Parser error.";
|
||||
m_vErrMsg[ecLOCALE] = "Decimal separator is identic to function argument separator.";
|
||||
m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = "The \"$TOK$\" operator must be preceeded by a closing bracket.";
|
||||
m_vErrMsg[ecMISSING_ELSE_CLAUSE] = "If-then-else operator is missing an else clause";
|
||||
m_vErrMsg[ecMISPLACED_COLON] = "Misplaced colon at position $POS$";
|
||||
|
||||
#if defined(_DEBUG)
|
||||
for (int i=0; i<ecCOUNT; ++i)
|
||||
if (!m_vErrMsg[i].length())
|
||||
assert(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// QParserError class
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/** \brief Default constructor. */
|
||||
QmuParserError::QmuParserError()
|
||||
:m_strMsg()
|
||||
,m_strFormula()
|
||||
,m_strTok()
|
||||
,m_iPos(-1)
|
||||
,m_iErrc(ecUNDEFINED)
|
||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief This Constructor is used for internal exceptions only.
|
||||
|
||||
It does not contain any information but the error code.
|
||||
*/
|
||||
QmuParserError::QmuParserError(EErrorCodes a_iErrc)
|
||||
:m_strMsg()
|
||||
,m_strFormula()
|
||||
,m_strTok()
|
||||
,m_iPos(-1)
|
||||
,m_iErrc(a_iErrc)
|
||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||
{
|
||||
m_strMsg = m_ErrMsg[m_iErrc];
|
||||
ReplaceSubString(m_strMsg, "$POS$", QString().setNum(m_iPos));
|
||||
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Construct an error from a message text. */
|
||||
QmuParserError::QmuParserError(const QString &sMsg)
|
||||
:m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||
{
|
||||
Reset();
|
||||
m_strMsg = sMsg;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Construct an error object.
|
||||
\param [in] a_iErrc the error code.
|
||||
\param [in] sTok The token string related to this error.
|
||||
\param [in] sExpr The expression related to the error.
|
||||
\param [in] a_iPos the position in the expression where the error occured.
|
||||
*/
|
||||
QmuParserError::QmuParserError(EErrorCodes iErrc,
|
||||
const QString &sTok,
|
||||
const QString &sExpr,
|
||||
int iPos )
|
||||
:m_strMsg()
|
||||
,m_strFormula(sExpr)
|
||||
,m_strTok(sTok)
|
||||
,m_iPos(iPos)
|
||||
,m_iErrc(iErrc)
|
||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||
{
|
||||
m_strMsg = m_ErrMsg[m_iErrc];
|
||||
ReplaceSubString(m_strMsg, "$POS$", QString().setNum(m_iPos));
|
||||
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Construct an error object.
|
||||
\param [in] iErrc the error code.
|
||||
\param [in] iPos the position in the expression where the error occured.
|
||||
\param [in] sTok The token string related to this error.
|
||||
*/
|
||||
QmuParserError::QmuParserError(EErrorCodes iErrc, int iPos, const QString &sTok)
|
||||
:m_strMsg()
|
||||
,m_strFormula()
|
||||
,m_strTok(sTok)
|
||||
,m_iPos(iPos)
|
||||
,m_iErrc(iErrc)
|
||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||
{
|
||||
m_strMsg = m_ErrMsg[m_iErrc];
|
||||
ReplaceSubString(m_strMsg, "$POS$", QString().setNum(m_iPos));
|
||||
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Construct an error object.
|
||||
\param [in] szMsg The error message text.
|
||||
\param [in] iPos the position related to the error.
|
||||
\param [in] sTok The token string related to this error.
|
||||
*/
|
||||
QmuParserError::QmuParserError(const QString &szMsg, int iPos, const QString &sTok)
|
||||
:m_strMsg(szMsg)
|
||||
,m_strFormula()
|
||||
,m_strTok(sTok)
|
||||
,m_iPos(iPos)
|
||||
,m_iErrc(ecGENERIC)
|
||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||
{
|
||||
ReplaceSubString(m_strMsg, "$POS$", QString().setNum(m_iPos));
|
||||
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Copy constructor. */
|
||||
QmuParserError::QmuParserError(const QmuParserError &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(QmuParserErrorMsg::Instance())
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Assignment operator. */
|
||||
QmuParserError& QmuParserError::operator=(const QmuParserError &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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QmuParserError::~QmuParserError()
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Replace all ocuurences of a substring with another string.
|
||||
\param strFind The string that shall be replaced.
|
||||
\param strReplaceWith The string that should be inserted instead of strFind
|
||||
*/
|
||||
void QmuParserError::ReplaceSubString( QString &strSource, const QString &strFind, const QString &strReplaceWith)
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
const QmuParserErrorMsg& QmuParserErrorMsg::Instance()
|
||||
{
|
||||
QString strResult;
|
||||
int iPos(0), iNext(0);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
iNext = strSource.indexOf(strFind, iPos);
|
||||
strResult.append(strSource.mid(iPos, iNext-iPos));
|
||||
|
||||
if( iNext==-1 )
|
||||
break;
|
||||
|
||||
strResult.append(strReplaceWith);
|
||||
iPos = iNext + strFind.length();
|
||||
}
|
||||
|
||||
strSource.swap(strResult);
|
||||
return m_Instance;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Reset the erro object. */
|
||||
void QmuParserError::Reset()
|
||||
{
|
||||
m_strMsg = "";
|
||||
m_strFormula = "";
|
||||
m_strTok = "";
|
||||
m_iPos = -1;
|
||||
m_iErrc = ecUNDEFINED;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QString QmuParserErrorMsg::operator[] ( unsigned a_iIdx ) const
|
||||
{
|
||||
return ( a_iIdx < m_vErrMsg.size() ) ? m_vErrMsg[a_iIdx] : QString();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Set the expression related to this error. */
|
||||
void QmuParserError::SetFormula(const QString &a_strFormula)
|
||||
{
|
||||
m_strFormula = a_strFormula;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserErrorMsg::~QmuParserErrorMsg()
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief gets the expression related tp this error.*/
|
||||
const QString& QmuParserError::GetExpr() const
|
||||
{
|
||||
return m_strFormula;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Assignement operator is deactivated.
|
||||
*/
|
||||
QmuParserErrorMsg& QmuParserErrorMsg::operator= ( const QmuParserErrorMsg& )
|
||||
{
|
||||
assert ( false );
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Returns the message string for this error. */
|
||||
const QString& QmuParserError::GetMsg() const
|
||||
{
|
||||
return m_strMsg;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserErrorMsg::QmuParserErrorMsg ( const QmuParserErrorMsg& )
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Return the formula position related to the error.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserErrorMsg::QmuParserErrorMsg()
|
||||
: m_vErrMsg ( 0 )
|
||||
{
|
||||
m_vErrMsg.resize ( ecCOUNT );
|
||||
|
||||
If the error is not related to a distinct position this will return -1
|
||||
m_vErrMsg[ecUNASSIGNABLE_TOKEN] = "Unexpected token \"$TOK$\" found at position $POS$.";
|
||||
m_vErrMsg[ecINTERNAL_ERROR] = "Internal error";
|
||||
m_vErrMsg[ecINVALID_NAME] = "Invalid function-, variable- or constant name: \"$TOK$\".";
|
||||
m_vErrMsg[ecINVALID_BINOP_IDENT] = "Invalid binary operator identifier: \"$TOK$\".";
|
||||
m_vErrMsg[ecINVALID_INFIX_IDENT] = "Invalid infix operator identifier: \"$TOK$\".";
|
||||
m_vErrMsg[ecINVALID_POSTFIX_IDENT] = "Invalid postfix operator identifier: \"$TOK$\".";
|
||||
m_vErrMsg[ecINVALID_FUN_PTR] = "Invalid pointer to callback function.";
|
||||
m_vErrMsg[ecEMPTY_EXPRESSION] = "Expression is empty.";
|
||||
m_vErrMsg[ecINVALID_VAR_PTR] = "Invalid pointer to variable.";
|
||||
m_vErrMsg[ecUNEXPECTED_OPERATOR] = "Unexpected operator \"$TOK$\" found at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_EOF] = "Unexpected end of expression at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_ARG_SEP] = "Unexpected argument separator at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_PARENS] = "Unexpected parenthesis \"$TOK$\" at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_FUN] = "Unexpected function \"$TOK$\" at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_VAL] = "Unexpected value \"$TOK$\" found at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_VAR] = "Unexpected variable \"$TOK$\" found at position $POS$";
|
||||
m_vErrMsg[ecUNEXPECTED_ARG] = "Function arguments used without a function (position: $POS$)";
|
||||
m_vErrMsg[ecMISSING_PARENS] = "Missing parenthesis";
|
||||
m_vErrMsg[ecTOO_MANY_PARAMS] = "Too many parameters for function \"$TOK$\" at expression position $POS$";
|
||||
m_vErrMsg[ecTOO_FEW_PARAMS] = "Too few parameters for function \"$TOK$\" at expression position $POS$";
|
||||
m_vErrMsg[ecDIV_BY_ZERO] = "Divide by zero";
|
||||
m_vErrMsg[ecDOMAIN_ERROR] = "Domain error";
|
||||
m_vErrMsg[ecNAME_CONFLICT] = "Name conflict";
|
||||
m_vErrMsg[ecOPT_PRI] = "Invalid value for operator priority (must be greater or equal to zero).";
|
||||
m_vErrMsg[ecBUILTIN_OVERLOAD] = "user defined binary operator \"$TOK$\" conflicts with a built in operator.";
|
||||
m_vErrMsg[ecUNEXPECTED_STR] = "Unexpected string token found at position $POS$.";
|
||||
m_vErrMsg[ecUNTERMINATED_STRING] = "Unterminated string starting at position $POS$.";
|
||||
m_vErrMsg[ecSTRING_EXPECTED] = "String function called with a non string type of argument.";
|
||||
m_vErrMsg[ecVAL_EXPECTED] = "String value used where a numerical argument is expected.";
|
||||
m_vErrMsg[ecOPRT_TYPE_CONFLICT] = "No suitable overload for operator \"$TOK$\" at position $POS$.";
|
||||
m_vErrMsg[ecSTR_RESULT] = "Function result is a string.";
|
||||
m_vErrMsg[ecGENERIC] = "Parser error.";
|
||||
m_vErrMsg[ecLOCALE] = "Decimal separator is identic to function argument separator.";
|
||||
m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = "The \"$TOK$\" operator must be preceeded by a closing bracket.";
|
||||
m_vErrMsg[ecMISSING_ELSE_CLAUSE] = "If-then-else operator is missing an else clause";
|
||||
m_vErrMsg[ecMISPLACED_COLON] = "Misplaced colon at position $POS$";
|
||||
|
||||
#if defined(_DEBUG)
|
||||
for ( int i = 0; i < ecCOUNT; ++i )
|
||||
{
|
||||
if ( !m_vErrMsg[i].length() )
|
||||
{
|
||||
assert ( false );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// QParserError class
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Default constructor.
|
||||
*/
|
||||
QmuParserError::QmuParserError()
|
||||
: m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ),
|
||||
m_ErrMsg ( QmuParserErrorMsg::Instance() )
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief This Constructor is used for internal exceptions only.
|
||||
*
|
||||
* It does not contain any information but the error code.
|
||||
*/
|
||||
QmuParserError::QmuParserError ( EErrorCodes a_iErrc )
|
||||
: m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ),
|
||||
m_ErrMsg ( QmuParserErrorMsg::Instance() )
|
||||
{
|
||||
m_strMsg = m_ErrMsg[m_iErrc];
|
||||
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
|
||||
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Construct an error from a message text.
|
||||
*/
|
||||
QmuParserError::QmuParserError ( const QString &sMsg )
|
||||
: m_ErrMsg ( QmuParserErrorMsg::Instance() )
|
||||
{
|
||||
Reset();
|
||||
m_strMsg = sMsg;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Construct an error object.
|
||||
* @param [in] a_iErrc the error code.
|
||||
* @param [in] sTok The token string related to this error.
|
||||
* @param [in] sExpr The expression related to the error.
|
||||
* @param [in] a_iPos the position in the expression where the error occured.
|
||||
*/
|
||||
QmuParserError::QmuParserError ( EErrorCodes iErrc,
|
||||
const QString &sTok,
|
||||
const QString &sExpr,
|
||||
int iPos )
|
||||
: m_strMsg(), m_strFormula ( sExpr ), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ),
|
||||
m_ErrMsg ( QmuParserErrorMsg::Instance() )
|
||||
{
|
||||
m_strMsg = m_ErrMsg[m_iErrc];
|
||||
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
|
||||
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Construct an error object.
|
||||
* @param [in] iErrc the error code.
|
||||
* @param [in] iPos the position in the expression where the error occured.
|
||||
* @param [in] sTok The token string related to this error.
|
||||
*/
|
||||
QmuParserError::QmuParserError ( EErrorCodes iErrc, int iPos, const QString &sTok )
|
||||
: m_strMsg(), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ),
|
||||
m_ErrMsg ( QmuParserErrorMsg::Instance() )
|
||||
{
|
||||
m_strMsg = m_ErrMsg[m_iErrc];
|
||||
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
|
||||
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/** @brief Construct an error object.
|
||||
* @param [in] szMsg The error message text.
|
||||
* @param [in] iPos the position related to the error.
|
||||
* @param [in] sTok The token string related to this error.
|
||||
*/
|
||||
std::size_t QmuParserError::GetPos() const
|
||||
{
|
||||
return m_iPos;
|
||||
}
|
||||
QmuParserError::QmuParserError ( const QString &szMsg, int iPos, const QString &sTok )
|
||||
: m_strMsg ( szMsg ), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ),
|
||||
m_ErrMsg ( QmuParserErrorMsg::Instance() )
|
||||
{
|
||||
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
|
||||
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Return string related with this token (if available). */
|
||||
const QString& QmuParserError::GetToken() const
|
||||
{
|
||||
return m_strTok;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/** @brief Copy constructor. */
|
||||
QmuParserError::QmuParserError ( const QmuParserError &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 ( QmuParserErrorMsg::Instance() )
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Return the error code. */
|
||||
EErrorCodes QmuParserError::GetCode() const
|
||||
{
|
||||
return m_iErrc;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/** @brief Assignment operator. */
|
||||
QmuParserError& QmuParserError::operator= ( const QmuParserError &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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserError::~QmuParserError()
|
||||
{}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Replace all ocuurences of a substring with another string.
|
||||
* @param strFind The string that shall be replaced.
|
||||
* @param strReplaceWith The string that should be inserted instead of strFind
|
||||
*/
|
||||
void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith )
|
||||
{
|
||||
QString strResult;
|
||||
int iPos ( 0 ), iNext ( 0 );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
iNext = strSource.indexOf ( strFind, iPos );
|
||||
strResult.append ( strSource.mid ( iPos, iNext - iPos ) );
|
||||
|
||||
if ( iNext == -1 )
|
||||
break;
|
||||
|
||||
strResult.append ( strReplaceWith );
|
||||
iPos = iNext + strFind.length();
|
||||
}
|
||||
|
||||
strSource.swap ( strResult );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Reset the erro object.
|
||||
*/
|
||||
void QmuParserError::Reset()
|
||||
{
|
||||
m_strMsg = "";
|
||||
m_strFormula = "";
|
||||
m_strTok = "";
|
||||
m_iPos = -1;
|
||||
m_iErrc = ecUNDEFINED;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Set the expression related to this error.
|
||||
*/
|
||||
void QmuParserError::SetFormula ( const QString &a_strFormula )
|
||||
{
|
||||
m_strFormula = a_strFormula;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief gets the expression related tp this error.
|
||||
*/
|
||||
const QString& QmuParserError::GetExpr() const
|
||||
{
|
||||
return m_strFormula;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Returns the message string for this error.
|
||||
*/
|
||||
const QString& QmuParserError::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 QmuParserError::GetPos() const
|
||||
{
|
||||
return m_iPos;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return string related with this token (if available).
|
||||
*/
|
||||
const QString& QmuParserError::GetToken() const
|
||||
{
|
||||
return m_strTok;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return the error code.
|
||||
*/
|
||||
EErrorCodes QmuParserError::GetCode() const
|
||||
{
|
||||
return m_iErrc;
|
||||
}
|
||||
} // namespace qmu
|
||||
|
|
|
@ -31,130 +31,126 @@
|
|||
|
||||
#include "qmuparserdef.h"
|
||||
|
||||
/** \file
|
||||
\brief This file defines the error class used by the parser.
|
||||
/** @file
|
||||
@brief This file defines the error class used by the parser.
|
||||
*/
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
|
||||
/** \brief Error codes. */
|
||||
/** @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_ARG_SEP = 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
|
||||
// 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_ARG_SEP = 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.
|
||||
ecINVALID_BINOP_IDENT = 19, ///< Invalid binary operator identifier
|
||||
ecINVALID_INFIX_IDENT = 20, ///< Invalid function, variable or constant name.
|
||||
ecINVALID_POSTFIX_IDENT = 21, ///< Invalid function, variable or constant name.
|
||||
// Invalid Parser input Parameters
|
||||
ecINVALID_NAME = 18, ///< Invalid function, variable or constant name.
|
||||
ecINVALID_BINOP_IDENT = 19, ///< Invalid binary operator identifier
|
||||
ecINVALID_INFIX_IDENT = 20, ///< Invalid function, variable or constant name.
|
||||
ecINVALID_POSTFIX_IDENT = 21, ///< Invalid function, variable or constant name.
|
||||
|
||||
ecBUILTIN_OVERLOAD = 22, ///< Trying to overload builtin operator
|
||||
ecINVALID_FUN_PTR = 23, ///< Invalid callback function pointer
|
||||
ecINVALID_VAR_PTR = 24, ///< Invalid variable pointer
|
||||
ecEMPTY_EXPRESSION = 25, ///< The Expression is empty
|
||||
ecNAME_CONFLICT = 26, ///< Name conflict
|
||||
ecOPT_PRI = 27, ///< Invalid operator priority
|
||||
//
|
||||
ecDOMAIN_ERROR = 28, ///< catch division by zero, sqrt(-1), log(0) (currently unused)
|
||||
ecDIV_BY_ZERO = 29, ///< Division by zero (currently unused)
|
||||
ecGENERIC = 30, ///< Generic error
|
||||
ecLOCALE = 31, ///< Conflict with current locale
|
||||
ecBUILTIN_OVERLOAD = 22, ///< Trying to overload builtin operator
|
||||
ecINVALID_FUN_PTR = 23, ///< Invalid callback function pointer
|
||||
ecINVALID_VAR_PTR = 24, ///< Invalid variable pointer
|
||||
ecEMPTY_EXPRESSION = 25, ///< The Expression is empty
|
||||
ecNAME_CONFLICT = 26, ///< Name conflict
|
||||
ecOPT_PRI = 27, ///< Invalid operator priority
|
||||
//
|
||||
ecDOMAIN_ERROR = 28, ///< catch division by zero, sqrt(-1), log(0) (currently unused)
|
||||
ecDIV_BY_ZERO = 29, ///< Division by zero (currently unused)
|
||||
ecGENERIC = 30, ///< Generic error
|
||||
ecLOCALE = 31, ///< Conflict with current locale
|
||||
|
||||
ecUNEXPECTED_CONDITIONAL = 32,
|
||||
ecMISSING_ELSE_CLAUSE = 33,
|
||||
ecMISPLACED_COLON = 34,
|
||||
ecUNEXPECTED_CONDITIONAL = 32,
|
||||
ecMISSING_ELSE_CLAUSE = 33,
|
||||
ecMISPLACED_COLON = 34,
|
||||
|
||||
// internal errors
|
||||
ecINTERNAL_ERROR = 35, ///< Internal error of any kind.
|
||||
// internal errors
|
||||
ecINTERNAL_ERROR = 35, ///< 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
|
||||
// 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
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief A class that handles the error messages.
|
||||
/** @brief A class that handles the error messages.
|
||||
*/
|
||||
class QmuParserErrorMsg
|
||||
{
|
||||
public:
|
||||
typedef QmuParserErrorMsg self_type;
|
||||
typedef QmuParserErrorMsg self_type;
|
||||
|
||||
QmuParserErrorMsg& operator=(const QmuParserErrorMsg &);
|
||||
QmuParserErrorMsg(const QmuParserErrorMsg&);
|
||||
QmuParserErrorMsg();
|
||||
QmuParserErrorMsg& operator= ( const QmuParserErrorMsg & );
|
||||
QmuParserErrorMsg ( const QmuParserErrorMsg& );
|
||||
QmuParserErrorMsg();
|
||||
~QmuParserErrorMsg();
|
||||
|
||||
~QmuParserErrorMsg();
|
||||
|
||||
static const QmuParserErrorMsg& Instance();
|
||||
QString operator[](unsigned a_iIdx) const;
|
||||
static const QmuParserErrorMsg& Instance();
|
||||
QString operator[] ( unsigned a_iIdx ) const;
|
||||
|
||||
private:
|
||||
QVector<QString> m_vErrMsg; ///< A vector with the predefined error messages
|
||||
static const self_type m_Instance; ///< The instance pointer
|
||||
QVector<QString> m_vErrMsg; ///< A vector with the predefined error messages
|
||||
static const self_type m_Instance; ///< The instance pointer
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Error class of the parser.
|
||||
\author Ingo Berg
|
||||
/** @brief Error class of the parser.
|
||||
@author Ingo Berg
|
||||
|
||||
Part of the math parser package.
|
||||
*/
|
||||
class QmuParserError
|
||||
{
|
||||
private:
|
||||
|
||||
/** \brief Replace all ocuurences of a substring with another string. */
|
||||
void ReplaceSubString(QString &strSource,
|
||||
const QString &strFind,
|
||||
const QString &strReplaceWith);
|
||||
void Reset();
|
||||
|
||||
public:
|
||||
|
||||
QmuParserError();
|
||||
explicit QmuParserError(EErrorCodes a_iErrc);
|
||||
explicit QmuParserError(const QString &sMsg);
|
||||
QmuParserError( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1);
|
||||
QmuParserError(EErrorCodes a_iErrc, int a_iPos, const QString &sTok);
|
||||
QmuParserError(const QString &a_szMsg, int a_iPos, const QString &sTok = QString());
|
||||
QmuParserError(const QmuParserError &a_Obj);
|
||||
QmuParserError& operator=(const QmuParserError &a_Obj);
|
||||
~QmuParserError();
|
||||
QmuParserError();
|
||||
explicit QmuParserError ( EErrorCodes a_iErrc );
|
||||
explicit QmuParserError ( const QString &sMsg );
|
||||
QmuParserError ( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1 );
|
||||
QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok );
|
||||
QmuParserError ( const QString &a_szMsg, int a_iPos, const QString &sTok = QString() );
|
||||
QmuParserError ( const QmuParserError &a_Obj );
|
||||
QmuParserError& operator= ( const QmuParserError &a_Obj );
|
||||
~QmuParserError();
|
||||
|
||||
void SetFormula(const QString &a_strFormula);
|
||||
const QString &GetExpr() const;
|
||||
const QString &GetMsg() const;
|
||||
std::size_t GetPos() const;
|
||||
const QString &GetToken() const;
|
||||
EErrorCodes GetCode() const;
|
||||
void SetFormula ( const QString &a_strFormula );
|
||||
const QString& GetExpr() const;
|
||||
const QString& GetMsg() const;
|
||||
std::size_t GetPos() const;
|
||||
const QString& GetToken() const;
|
||||
EErrorCodes GetCode() const;
|
||||
|
||||
private:
|
||||
QString m_strMsg; ///< The message string
|
||||
QString m_strFormula; ///< Formula string
|
||||
QString m_strTok; ///< Token related with the error
|
||||
int m_iPos; ///< Formula position related to the error
|
||||
EErrorCodes m_iErrc; ///< Error code
|
||||
const QmuParserErrorMsg &m_ErrMsg;
|
||||
QString m_strMsg; ///< The message string
|
||||
QString m_strFormula; ///< Formula string
|
||||
QString m_strTok; ///< Token related with the error
|
||||
int m_iPos; ///< Formula position related to the error
|
||||
EErrorCodes m_iErrc; ///< Error code
|
||||
const QmuParserErrorMsg &m_ErrMsg;
|
||||
/**
|
||||
* @brief Replace all ocuurences of a substring with another string.
|
||||
*/
|
||||
void ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith );
|
||||
void Reset();
|
||||
};
|
||||
|
||||
} // namespace qmu
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
#ifndef QMUPARSERFIXES_H
|
||||
#define QMUPARSERFIXES_H
|
||||
|
||||
/** \file
|
||||
\brief This file contains compatibility fixes for some platforms.
|
||||
/** @file
|
||||
@brief This file contains compatibility fixes for some platforms.
|
||||
*/
|
||||
|
||||
//
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,170 +29,272 @@
|
|||
#include "qmuparser.h"
|
||||
#include <QString>
|
||||
|
||||
/** \file
|
||||
\brief This file contains the parser test class.
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* @brief This file contains the parser test class.
|
||||
*/
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
/** \brief Namespace for test cases. */
|
||||
namespace Test
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Test cases for unit testing.
|
||||
/**
|
||||
* @brief Namespace for test cases.
|
||||
*/
|
||||
namespace Test
|
||||
{
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Test cases for unit testing.
|
||||
*
|
||||
* (C) 2004-2011 Ingo Berg
|
||||
*/
|
||||
class QmuParserTester // final
|
||||
{
|
||||
public:
|
||||
typedef int ( QmuParserTester::*testfun_type ) ();
|
||||
|
||||
(C) 2004-2011 Ingo Berg
|
||||
*/
|
||||
class QmuParserTester // final
|
||||
{
|
||||
private:
|
||||
static int c_iCount;
|
||||
QmuParserTester();
|
||||
void Run();
|
||||
private:
|
||||
QVector<testfun_type> m_vTestFun;
|
||||
static int c_iCount;
|
||||
|
||||
// Multiarg callbacks
|
||||
static qreal f1of1(qreal v) { return v;}
|
||||
void AddTest ( testfun_type a_pFun );
|
||||
|
||||
static qreal f1of2(qreal v, qreal ) {return v;}
|
||||
static qreal f2of2(qreal , qreal v) {return v;}
|
||||
// Test Double Parser
|
||||
int EqnTest ( const QString &a_str, double a_fRes, bool a_fPass );
|
||||
int EqnTestWithVarChange ( const QString &a_str, double a_fRes1, double a_fVar1, double a_fRes2, double a_fVar2 );
|
||||
int ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail = true );
|
||||
|
||||
static qreal f1of3(qreal v, qreal , qreal ) {return v;}
|
||||
static qreal f2of3(qreal , qreal v, qreal ) {return v;}
|
||||
static qreal f3of3(qreal , qreal , qreal v) {return v;}
|
||||
// Multiarg callbacks
|
||||
static qreal f1of1 ( qreal v )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal f1of4(qreal v, qreal, qreal , qreal ) {return v;}
|
||||
static qreal f2of4(qreal , qreal v, qreal , qreal ) {return v;}
|
||||
static qreal f3of4(qreal , qreal, qreal v, qreal ) {return v;}
|
||||
static qreal f4of4(qreal , qreal, qreal , qreal v) {return v;}
|
||||
static qreal f1of2 ( qreal v, qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal f1of5(qreal v, qreal, qreal , qreal , qreal ) { return v; }
|
||||
static qreal f2of5(qreal , qreal v, qreal , qreal , qreal ) { return v; }
|
||||
static qreal f3of5(qreal , qreal, qreal v, qreal , qreal ) { return v; }
|
||||
static qreal f4of5(qreal , qreal, qreal , qreal v, qreal ) { return v; }
|
||||
static qreal f5of5(qreal , qreal, qreal , qreal , qreal v) { return v; }
|
||||
static qreal f2of2 ( qreal , qreal v )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal Min(qreal a_fVal1, qreal a_fVal2) { return (a_fVal1<a_fVal2) ? a_fVal1 : a_fVal2; }
|
||||
static qreal Max(qreal a_fVal1, qreal a_fVal2) { return (a_fVal1>a_fVal2) ? a_fVal1 : a_fVal2; }
|
||||
static qreal f1of3 ( qreal v, qreal , qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal plus2(qreal v1) { return v1+2; }
|
||||
static qreal times3(qreal v1) { return v1*3; }
|
||||
static qreal sqr(qreal v1) { return v1*v1; }
|
||||
static qreal sign(qreal v) { return -v; }
|
||||
static qreal add(qreal v1, qreal v2) { return v1+v2; }
|
||||
static qreal land(qreal v1, qreal v2) { return (int)v1 & (int)v2; }
|
||||
static qreal f2of3 ( qreal , qreal v, qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal f3of3 ( qreal , qreal , qreal v )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal FirstArg(const qreal* a_afArg, int a_iArgc)
|
||||
{
|
||||
if (!a_iArgc)
|
||||
throw qmu::QmuParser::exception_type( "too few arguments for function FirstArg." );
|
||||
static qreal f1of4 ( qreal v, qreal, qreal , qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
return a_afArg[0];
|
||||
}
|
||||
static qreal f2of4 ( qreal , qreal v, qreal , qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal LastArg(const qreal* a_afArg, int a_iArgc)
|
||||
{
|
||||
if (!a_iArgc)
|
||||
throw qmu::QmuParser::exception_type( "too few arguments for function LastArg." );
|
||||
static qreal f3of4 ( qreal , qreal, qreal v, qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
return a_afArg[a_iArgc-1];
|
||||
}
|
||||
static qreal f4of4 ( qreal , qreal, qreal , qreal v )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal Sum(const qreal* a_afArg, int a_iArgc)
|
||||
{
|
||||
if (!a_iArgc)
|
||||
throw qmu::QmuParser::exception_type( "too few arguments for function sum." );
|
||||
static qreal f1of5 ( qreal v, qreal, qreal , qreal , qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
qreal fRes=0;
|
||||
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
|
||||
return fRes;
|
||||
}
|
||||
static qreal f2of5 ( qreal , qreal v, qreal , qreal , qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal Rnd(qreal v)
|
||||
{
|
||||
return (qreal)(1+(v*std::rand()/(RAND_MAX+1.0)));
|
||||
}
|
||||
static qreal f3of5 ( qreal , qreal, qreal v, qreal , qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal RndWithString(const char_type*)
|
||||
{
|
||||
return (qreal)( 1 + (1000.0f * std::rand() / (RAND_MAX + 1.0) ) );
|
||||
}
|
||||
static qreal f4of5 ( qreal , qreal, qreal , qreal v, qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal Ping()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
static qreal f5of5 ( qreal , qreal, qreal , qreal , qreal v )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal ValueOf(const QString &)
|
||||
{
|
||||
return 123;
|
||||
}
|
||||
static qreal Min ( qreal a_fVal1, qreal a_fVal2 )
|
||||
{
|
||||
return ( a_fVal1 < a_fVal2 ) ? a_fVal1 : a_fVal2;
|
||||
}
|
||||
|
||||
static qreal StrFun1(const QString & v1)
|
||||
{
|
||||
int val = v1.toInt();
|
||||
return (qreal)val;
|
||||
}
|
||||
static qreal Max ( qreal a_fVal1, qreal a_fVal2 )
|
||||
{
|
||||
return ( a_fVal1 > a_fVal2 ) ? a_fVal1 : a_fVal2;
|
||||
}
|
||||
|
||||
static qreal StrFun2(const QString & v1, qreal v2)
|
||||
{
|
||||
int val = v1.toInt();
|
||||
return (qreal)(val + v2);
|
||||
}
|
||||
static qreal plus2 ( qreal v1 )
|
||||
{
|
||||
return v1 + 2;
|
||||
}
|
||||
|
||||
static qreal StrFun3(const QString & v1, qreal v2, qreal v3)
|
||||
{
|
||||
int val = v1.toInt();
|
||||
return val + v2 + v3;
|
||||
}
|
||||
static qreal times3 ( qreal v1 )
|
||||
{
|
||||
return v1 * 3;
|
||||
}
|
||||
|
||||
static qreal StrToFloat(const QString & a_szMsg)
|
||||
{
|
||||
qreal val = a_szMsg.toDouble();
|
||||
return val;
|
||||
}
|
||||
static qreal sqr ( qreal v1 )
|
||||
{
|
||||
return v1 * v1;
|
||||
}
|
||||
|
||||
// postfix operator callback
|
||||
static qreal Mega(qreal a_fVal) { return a_fVal * (qreal)1e6; }
|
||||
static qreal Micro(qreal a_fVal) { return a_fVal * (qreal)1e-6; }
|
||||
static qreal Milli(qreal a_fVal) { return a_fVal / (qreal)1e3; }
|
||||
static qreal sign ( qreal v )
|
||||
{
|
||||
return -v;
|
||||
}
|
||||
|
||||
// Custom value recognition
|
||||
static int IsHexVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal);
|
||||
static qreal add ( qreal v1, qreal v2 )
|
||||
{
|
||||
return v1 + v2;
|
||||
}
|
||||
|
||||
int TestNames();
|
||||
int TestSyntax();
|
||||
int TestMultiArg();
|
||||
int TestPostFix();
|
||||
int TestExpression();
|
||||
int TestInfixOprt();
|
||||
int TestBinOprt();
|
||||
int TestVarConst();
|
||||
int TestInterface();
|
||||
int TestException();
|
||||
int TestStrArg();
|
||||
int TestIfThenElse();
|
||||
static qreal land ( qreal v1, qreal v2 )
|
||||
{
|
||||
return ( int ) v1 & ( int ) v2;
|
||||
}
|
||||
|
||||
void Abort() const;
|
||||
static qreal FirstArg ( const qreal* a_afArg, int a_iArgc )
|
||||
{
|
||||
if ( !a_iArgc )
|
||||
{
|
||||
throw qmu::QmuParser::exception_type ( "too few arguments for function FirstArg." );
|
||||
}
|
||||
|
||||
public:
|
||||
typedef int (QmuParserTester::*testfun_type)();
|
||||
return a_afArg[0];
|
||||
}
|
||||
|
||||
QmuParserTester();
|
||||
void Run();
|
||||
static qreal LastArg ( const qreal* a_afArg, int a_iArgc )
|
||||
{
|
||||
if ( !a_iArgc )
|
||||
{
|
||||
throw qmu::QmuParser::exception_type ( "too few arguments for function LastArg." );
|
||||
}
|
||||
|
||||
private:
|
||||
QVector<testfun_type> m_vTestFun;
|
||||
void AddTest(testfun_type a_pFun);
|
||||
return a_afArg[a_iArgc - 1];
|
||||
}
|
||||
|
||||
// Test Double Parser
|
||||
int EqnTest(const QString &a_str, double a_fRes, bool a_fPass);
|
||||
int EqnTestWithVarChange(const QString &a_str,
|
||||
double a_fRes1,
|
||||
double a_fVar1,
|
||||
double a_fRes2,
|
||||
double a_fVar2);
|
||||
int ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail = true);
|
||||
};
|
||||
} // namespace Test
|
||||
static qreal Sum ( const qreal* a_afArg, int a_iArgc )
|
||||
{
|
||||
if ( !a_iArgc )
|
||||
{
|
||||
throw qmu::QmuParser::exception_type ( "too few arguments for function sum." );
|
||||
}
|
||||
|
||||
qreal fRes = 0;
|
||||
for ( int i = 0; i < a_iArgc; ++i )
|
||||
{
|
||||
fRes += a_afArg[i];
|
||||
}
|
||||
return fRes;
|
||||
}
|
||||
|
||||
static qreal Rnd ( qreal v )
|
||||
{
|
||||
return ( qreal ) ( 1 + ( v * std::rand() / ( RAND_MAX + 1.0 ) ) );
|
||||
}
|
||||
|
||||
static qreal RndWithString ( const char_type* )
|
||||
{
|
||||
return ( qreal ) ( 1 + ( 1000.0f * std::rand() / ( RAND_MAX + 1.0 ) ) );
|
||||
}
|
||||
|
||||
static qreal Ping()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
static qreal ValueOf ( const QString & )
|
||||
{
|
||||
return 123;
|
||||
}
|
||||
|
||||
static qreal StrFun1 ( const QString & v1 )
|
||||
{
|
||||
int val = v1.toInt();
|
||||
return ( qreal ) val;
|
||||
}
|
||||
|
||||
static qreal StrFun2 ( const QString & v1, qreal v2 )
|
||||
{
|
||||
int val = v1.toInt();
|
||||
return ( qreal ) ( val + v2 );
|
||||
}
|
||||
|
||||
static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 )
|
||||
{
|
||||
int val = v1.toInt();
|
||||
return val + v2 + v3;
|
||||
}
|
||||
|
||||
static qreal StrToFloat ( const QString & a_szMsg )
|
||||
{
|
||||
qreal val = a_szMsg.toDouble();
|
||||
return val;
|
||||
}
|
||||
|
||||
// postfix operator callback
|
||||
static qreal Mega ( qreal a_fVal )
|
||||
{
|
||||
return a_fVal * ( qreal ) 1e6;
|
||||
}
|
||||
|
||||
static qreal Micro ( qreal a_fVal )
|
||||
{
|
||||
return a_fVal * ( qreal ) 1e-6;
|
||||
}
|
||||
|
||||
static qreal Milli ( qreal a_fVal )
|
||||
{
|
||||
return a_fVal / ( qreal ) 1e3;
|
||||
}
|
||||
|
||||
// Custom value recognition
|
||||
static int IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal );
|
||||
|
||||
int TestNames();
|
||||
int TestSyntax();
|
||||
int TestMultiArg();
|
||||
int TestPostFix();
|
||||
int TestExpression();
|
||||
int TestInfixOprt();
|
||||
int TestBinOprt();
|
||||
int TestVarConst();
|
||||
int TestInterface();
|
||||
int TestException();
|
||||
int TestStrArg();
|
||||
int TestIfThenElse();
|
||||
|
||||
void Abort() const;
|
||||
};
|
||||
} // namespace Test
|
||||
} // namespace qmu
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
#include "qmuparsererror.h"
|
||||
#include "qmuparsercallback.h"
|
||||
|
||||
/** \file
|
||||
\brief This file contains the parser token definition.
|
||||
/** @file
|
||||
@brief This file contains the parser token definition.
|
||||
*/
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
/** \brief Encapsulation of the data for a single formula token.
|
||||
/** @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:
|
||||
|
@ -52,7 +52,7 @@ namespace qmu
|
|||
<li>binary operator</li>
|
||||
</ul>
|
||||
|
||||
\author (C) 2004-2013 Ingo Berg
|
||||
@author (C) 2004-2013 Ingo Berg
|
||||
*/
|
||||
template<typename TBase, typename TString>
|
||||
class QmuParserToken
|
||||
|
@ -71,11 +71,11 @@ namespace qmu
|
|||
public:
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Constructor (default).
|
||||
/** @brief Constructor (default).
|
||||
|
||||
Sets token to an neutral state of type cmUNKNOWN.
|
||||
\throw nothrow
|
||||
\sa ECmdCode
|
||||
@throw nothrow
|
||||
@sa ECmdCode
|
||||
*/
|
||||
QmuParserToken()
|
||||
:m_iCode(cmUNKNOWN)
|
||||
|
@ -87,12 +87,12 @@ namespace qmu
|
|||
{}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Create token from another one.
|
||||
/** @brief Create token from another one.
|
||||
|
||||
Implemented by calling Assign(...)
|
||||
\throw nothrow
|
||||
\post m_iType==cmUNKNOWN
|
||||
\sa #Assign
|
||||
@throw nothrow
|
||||
@post m_iType==cmUNKNOWN
|
||||
@sa #Assign
|
||||
*/
|
||||
QmuParserToken(const QmuParserToken &a_Tok)
|
||||
{
|
||||
|
@ -100,11 +100,11 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Assignement operator.
|
||||
/** @brief Assignement operator.
|
||||
|
||||
Copy token state from another token and return this.
|
||||
Implemented by calling Assign(...).
|
||||
\throw nothrow
|
||||
@throw nothrow
|
||||
*/
|
||||
QmuParserToken& operator=(const QmuParserToken &a_Tok)
|
||||
{
|
||||
|
@ -113,9 +113,9 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Copy token information from argument.
|
||||
/** @brief Copy token information from argument.
|
||||
|
||||
\throw nothrow
|
||||
@throw nothrow
|
||||
*/
|
||||
void Assign(const QmuParserToken &a_Tok)
|
||||
{
|
||||
|
@ -131,15 +131,15 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Assign a token type.
|
||||
/** @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
|
||||
@post m_fVal = 0
|
||||
@post m_pTok = 0
|
||||
*/
|
||||
QmuParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString())
|
||||
{
|
||||
|
@ -158,7 +158,7 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Set Callback type. */
|
||||
/** @brief Set Callback type. */
|
||||
QmuParserToken& Set(const QmuParserCallback &a_pCallback, const TString &a_sTok)
|
||||
{
|
||||
assert(a_pCallback.GetAddr());
|
||||
|
@ -175,10 +175,10 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Make this token a value token.
|
||||
/** @brief Make this token a value token.
|
||||
|
||||
Member variables not necessary for value tokens will be invalidated.
|
||||
\throw nothrow
|
||||
@throw nothrow
|
||||
*/
|
||||
QmuParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString())
|
||||
{
|
||||
|
@ -195,10 +195,10 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief make this token a variable token.
|
||||
/** @brief make this token a variable token.
|
||||
|
||||
Member variables not necessary for variable tokens will be invalidated.
|
||||
\throw nothrow
|
||||
@throw nothrow
|
||||
*/
|
||||
QmuParserToken& SetVar(TBase *a_pVar, const TString &a_strTok)
|
||||
{
|
||||
|
@ -212,10 +212,10 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Make this token a variable token.
|
||||
/** @brief Make this token a variable token.
|
||||
|
||||
Member variables not necessary for variable tokens will be invalidated.
|
||||
\throw nothrow
|
||||
@throw nothrow
|
||||
*/
|
||||
QmuParserToken& SetString(const TString &a_strTok, std::size_t a_iSize)
|
||||
{
|
||||
|
@ -230,11 +230,11 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Set an index associated with the token related data.
|
||||
/** @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
|
||||
* @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)
|
||||
{
|
||||
|
@ -245,12 +245,12 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Return Index associated with the token related data.
|
||||
/** @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).
|
||||
@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
|
||||
{
|
||||
|
@ -261,10 +261,10 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Return the token type.
|
||||
/** @brief Return the token type.
|
||||
|
||||
\return #m_iType
|
||||
\throw nothrow
|
||||
* @return #m_iType
|
||||
@throw nothrow
|
||||
*/
|
||||
ECmdCode GetCode() const
|
||||
{
|
||||
|
@ -313,11 +313,11 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Return the address of the callback function assoziated with
|
||||
/** @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:
|
||||
* @return The pointer stored in #m_pTok.
|
||||
@throw exception_type if token type is non of:
|
||||
<ul>
|
||||
<li>cmFUNC</li>
|
||||
<li>cmSTRFUNC</li>
|
||||
|
@ -325,7 +325,7 @@ namespace qmu
|
|||
<li>cmINFIXOP</li>
|
||||
<li>cmOPRT_BIN</li>
|
||||
</ul>
|
||||
\sa ECmdCode
|
||||
@sa ECmdCode
|
||||
*/
|
||||
generic_fun_type GetFuncAddr() const
|
||||
{
|
||||
|
@ -336,7 +336,7 @@ namespace qmu
|
|||
/** \biref Get value of the token.
|
||||
|
||||
Only applicable to variable and value tokens.
|
||||
\throw exception_type if token is no value/variable token.
|
||||
@throw exception_type if token is no value/variable token.
|
||||
*/
|
||||
TBase GetVal() const
|
||||
{
|
||||
|
@ -349,10 +349,10 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Get address of a variable token.
|
||||
/** @brief Get address of a variable token.
|
||||
|
||||
Valid only if m_iType==CmdVar.
|
||||
\throw exception_type if token is no variable token.
|
||||
@throw exception_type if token is no variable token.
|
||||
*/
|
||||
TBase* GetVar() const
|
||||
{
|
||||
|
@ -363,7 +363,7 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Return the number of function arguments.
|
||||
/** @brief Return the number of function arguments.
|
||||
|
||||
Valid only if m_iType==CmdFUNC.
|
||||
*/
|
||||
|
@ -378,13 +378,13 @@ namespace qmu
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Return the token identifier.
|
||||
/** @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
|
||||
* @return #m_strTok
|
||||
@throw nothrow
|
||||
@sa m_strTok
|
||||
*/
|
||||
const TString& GetAsString() const
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,8 +35,8 @@
|
|||
#include "qmuparserdef.h"
|
||||
#include "qmuparsertoken.h"
|
||||
|
||||
/** \file
|
||||
\brief This file contains the parser token reader definition.
|
||||
/** @file
|
||||
@brief This file contains the parser token reader definition.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace qmu
|
|||
// Forward declaration
|
||||
class QmuParserBase;
|
||||
|
||||
/** \brief Token reader for the ParserBase class.
|
||||
/** @brief Token reader for the ParserBase class.
|
||||
|
||||
*/
|
||||
class QmuParserTokenReader
|
||||
|
@ -75,7 +75,7 @@ namespace qmu
|
|||
|
||||
private:
|
||||
|
||||
/** \brief Syntax codes.
|
||||
/** @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
|
||||
|
|
Loading…
Reference in New Issue
Block a user