Apply project code style.
--HG-- branch : feature
This commit is contained in:
parent
0b49785255
commit
2c77a73343
|
@ -24,29 +24,49 @@
|
|||
#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))); }
|
||||
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)));
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Logarithm functions
|
||||
|
||||
// Logarithm base 2
|
||||
|
@ -54,9 +74,10 @@ namespace qmu
|
|||
{
|
||||
#ifdef MUP_MATH_EXCEPTIONS
|
||||
if (v<=0)
|
||||
{
|
||||
throw QmuParserError(ecDOMAIN_ERROR, "Log2");
|
||||
}
|
||||
#endif
|
||||
|
||||
return log(v)/log((qreal)2);
|
||||
}
|
||||
|
||||
|
@ -65,63 +86,80 @@ namespace qmu
|
|||
{
|
||||
#ifdef MUP_MATH_EXCEPTIONS
|
||||
if (v<=0)
|
||||
{
|
||||
throw QmuParserError(ecDOMAIN_ERROR, "Log10");
|
||||
}
|
||||
#endif
|
||||
|
||||
return log10(v);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 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); }
|
||||
qreal QmuParser::Abs(qreal v)
|
||||
{
|
||||
return qAbs(v);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Callback for the unary minus operator.
|
||||
\param v The value to negate
|
||||
\return -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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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 averaging multiple values.
|
||||
\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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
|
@ -129,7 +167,6 @@ qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc)
|
|||
{
|
||||
throw exception_type("too few arguments for function min.");
|
||||
}
|
||||
|
||||
qreal fRes=a_afArg[0];
|
||||
for (int i=0; i<a_iArgc; ++i)
|
||||
{
|
||||
|
@ -138,10 +175,11 @@ qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc)
|
|||
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)
|
||||
{
|
||||
|
@ -149,7 +187,6 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
|
|||
{
|
||||
throw exception_type("too few arguments for function min.");
|
||||
}
|
||||
|
||||
qreal fRes=a_afArg[0];
|
||||
for (int i=0; i<a_iArgc; ++i)
|
||||
{
|
||||
|
@ -158,13 +195,13 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
|
|||
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.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
|
@ -182,21 +219,22 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
|
|||
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
|
||||
|
||||
if (iEnd==(stringstream_type::pos_type)-1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*a_iPos += (int)iEnd;
|
||||
*a_fVal = fVal;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Constructor.
|
||||
|
||||
Call QmuParserBase class constructor and trigger Function, Operator and Constant initialization.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Constructor.
|
||||
*
|
||||
* Call QmuParserBase class constructor and trigger Function, Operator and Constant initialization.
|
||||
*/
|
||||
QmuParser::QmuParser()
|
||||
:QmuParserBase()
|
||||
QmuParser::QmuParser():QmuParserBase()
|
||||
{
|
||||
AddValIdent(IsVal);
|
||||
|
||||
|
@ -206,12 +244,13 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
|
|||
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.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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()
|
||||
{
|
||||
|
@ -220,8 +259,10 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
|
|||
DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Initialize the default functions. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Initialize the default functions.
|
||||
*/
|
||||
void QmuParser::InitFun()
|
||||
{
|
||||
// trigonometric functions
|
||||
|
@ -259,11 +300,12 @@ void QmuParser::InitFun()
|
|||
DefineFun("max", Max);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Initialize constants.
|
||||
|
||||
By default the QmuParser recognizes two constants. Pi ("pi") and the eulerian
|
||||
number ("_e").
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Initialize constants.
|
||||
*
|
||||
* By default the QmuParser recognizes two constants. Pi ("pi") and the eulerian
|
||||
* number ("_e").
|
||||
*/
|
||||
void QmuParser::InitConst()
|
||||
{
|
||||
|
@ -271,17 +313,18 @@ void QmuParser::InitFun()
|
|||
DefineConst("_e", (qreal)M_E);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Initialize operators.
|
||||
|
||||
By default only the unary minus operator is added.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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.
|
||||
|
@ -306,22 +349,21 @@ void QmuParser::InitFun()
|
|||
*/
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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 QmuParser::Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon) const
|
||||
{
|
||||
qreal fRes(0),
|
||||
fBuf(*a_Var),
|
||||
|
@ -331,7 +373,9 @@ void QmuParser::InitFun()
|
|||
// 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();
|
||||
|
|
|
@ -24,29 +24,27 @@
|
|||
#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>
|
||||
/** @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();
|
||||
|
@ -54,9 +52,9 @@ public:
|
|||
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
|
||||
|
@ -82,8 +80,6 @@ protected:
|
|||
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);
|
||||
};
|
||||
|
||||
} // 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,108 +35,60 @@
|
|||
|
||||
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.
|
||||
/**
|
||||
* @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.
|
||||
/**
|
||||
* @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();
|
||||
|
||||
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);
|
||||
|
||||
/** \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 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);
|
||||
|
||||
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();
|
||||
|
@ -152,62 +96,58 @@ private:
|
|||
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;
|
||||
|
||||
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;
|
||||
|
||||
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:
|
||||
|
||||
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. */
|
||||
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)
|
||||
:std::numpunct<TChar>(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep)
|
||||
{}
|
||||
|
||||
protected:
|
||||
|
||||
virtual char_type do_decimal_point() const
|
||||
{
|
||||
return m_cDecPoint;
|
||||
|
@ -222,53 +162,50 @@ private:
|
|||
{
|
||||
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;
|
||||
|
||||
void Assign(const QmuParserBase &a_Parser);
|
||||
void InitTokenReader();
|
||||
void ReInit() const;
|
||||
/**
|
||||
* @brief Type used for storing an array of values.
|
||||
*/
|
||||
typedef QVector<qreal> valbuf_type;
|
||||
|
||||
void AddCallback(const QString &a_strName,
|
||||
const QmuParserCallback &a_Callback,
|
||||
funmap_type &a_Storage,
|
||||
const QString &a_szCharSet );
|
||||
/**
|
||||
* @brief Type for a vector of strings.
|
||||
*/
|
||||
typedef QVector<QString> stringbuf_type;
|
||||
|
||||
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;
|
||||
/**
|
||||
* @brief Typedef for the token reader.
|
||||
*/
|
||||
typedef QmuParserTokenReader token_reader_type;
|
||||
|
||||
token_type ApplyStrFunc(const token_type &a_FunTok,
|
||||
const QVector<token_type> &a_vArg) const;
|
||||
/**
|
||||
* @brief Type used for parser tokens.
|
||||
*/
|
||||
typedef QmuParserToken<qreal, QString> token_type;
|
||||
|
||||
int GetOprtPrecedence(const token_type &a_Tok) const;
|
||||
EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const;
|
||||
/**
|
||||
* @brief Maximum number of threads spawned by OpenMP when using the bulk mode.
|
||||
*/
|
||||
static const int s_MaxNumOpenMPThreads = 4;
|
||||
|
||||
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.
|
||||
/**
|
||||
* @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.
|
||||
|
@ -296,6 +233,27 @@ private:
|
|||
// 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;
|
||||
};
|
||||
|
||||
} // namespace qmu
|
||||
|
|
|
@ -35,31 +35,32 @@
|
|||
|
||||
namespace qmu
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Bytecode default constructor. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Bytecode default constructor.
|
||||
*/
|
||||
QmuParserByteCode::QmuParserByteCode()
|
||||
:m_iStackPos(0)
|
||||
,m_iMaxStackSize(0)
|
||||
,m_vRPN()
|
||||
,m_bEnableOptimizer(true)
|
||||
:m_iStackPos(0), m_iMaxStackSize(0), m_vRPN(), m_bEnableOptimizer(true)
|
||||
{
|
||||
m_vRPN.reserve(50);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Copy constructor.
|
||||
|
||||
Implemented in Terms of Assign(const QParserByteCode &a_ByteCode)
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Copy constructor.
|
||||
*
|
||||
* Implemented in Terms of Assign(const QParserByteCode &a_ByteCode)
|
||||
*/
|
||||
QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode)
|
||||
{
|
||||
Assign(a_ByteCode);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Assignment operator.
|
||||
|
||||
Implemented in Terms of Assign(const QParserByteCode &a_ByteCode)
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Assignment operator.
|
||||
*
|
||||
* Implemented in Terms of Assign(const QParserByteCode &a_ByteCode)
|
||||
*/
|
||||
QmuParserByteCode& QmuParserByteCode::operator=(const QmuParserByteCode &a_ByteCode)
|
||||
{
|
||||
|
@ -67,31 +68,35 @@ namespace qmu
|
|||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParserByteCode::EnableOptimizer(bool bStat)
|
||||
{
|
||||
m_bEnableOptimizer = bStat;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Copy state of another object to this.
|
||||
|
||||
\throw nowthrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Copy state of another object to this.
|
||||
*
|
||||
* @throw nowthrow
|
||||
*/
|
||||
void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode)
|
||||
{
|
||||
if (this==&a_ByteCode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_iStackPos = a_ByteCode.m_iStackPos;
|
||||
m_vRPN = a_ByteCode.m_vRPN;
|
||||
m_iMaxStackSize = a_ByteCode.m_iMaxStackSize;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add a Variable pointer to bytecode.
|
||||
\param a_pVar Pointer to be added.
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Add a Variable pointer to bytecode.
|
||||
* @param a_pVar Pointer to be added.
|
||||
* @throw nothrow
|
||||
*/
|
||||
void QmuParserByteCode::AddVar(qreal *a_pVar)
|
||||
{
|
||||
|
@ -107,18 +112,19 @@ namespace qmu
|
|||
m_vRPN.push_back(tok);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add a Variable pointer to bytecode.
|
||||
|
||||
Value entries in byte code consist of:
|
||||
<ul>
|
||||
<li>value array position of the value</li>
|
||||
<li>the operator code according to ParserToken::cmVAL</li>
|
||||
<li>the value stored in #mc_iSizeVal number of bytecode entries.</li>
|
||||
</ul>
|
||||
|
||||
\param a_pVal Value to be added.
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Add a Variable pointer to bytecode.
|
||||
*
|
||||
* Value entries in byte code consist of:
|
||||
* <ul>
|
||||
* <li>value array position of the value</li>
|
||||
* <li>the operator code according to ParserToken::cmVAL</li>
|
||||
* <li>the value stored in #mc_iSizeVal number of bytecode entries.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param a_pVal Value to be added.
|
||||
* @throw nothrow
|
||||
*/
|
||||
void QmuParserByteCode::AddVal(qreal a_fVal)
|
||||
{
|
||||
|
@ -134,7 +140,7 @@ namespace qmu
|
|||
m_vRPN.push_back(tok);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt)
|
||||
{
|
||||
std::size_t sz = m_vRPN.size();
|
||||
|
@ -142,47 +148,80 @@ namespace qmu
|
|||
&y = m_vRPN[sz-1].Val.data2;
|
||||
switch (a_Oprt)
|
||||
{
|
||||
case cmLAND: x = (int)x && (int)y; m_vRPN.pop_back(); break;
|
||||
case cmLOR: x = (int)x || (int)y; m_vRPN.pop_back(); break;
|
||||
case cmLT: x = x < y; m_vRPN.pop_back(); break;
|
||||
case cmGT: x = x > y; m_vRPN.pop_back(); break;
|
||||
case cmLE: x = x <= y; m_vRPN.pop_back(); break;
|
||||
case cmGE: x = x >= y; m_vRPN.pop_back(); break;
|
||||
case cmNEQ: x = x != y; m_vRPN.pop_back(); break;
|
||||
case cmEQ: x = x == y; m_vRPN.pop_back(); break;
|
||||
case cmADD: x = x + y; m_vRPN.pop_back(); break;
|
||||
case cmSUB: x = x - y; m_vRPN.pop_back(); break;
|
||||
case cmMUL: x = x * y; m_vRPN.pop_back(); break;
|
||||
case cmLAND:
|
||||
x = (int)x && (int)y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmLOR:
|
||||
x = (int)x || (int)y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmLT:
|
||||
x = x < y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmGT:
|
||||
x = x > y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmLE:
|
||||
x = x <= y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmGE:
|
||||
x = x >= y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmNEQ:
|
||||
x = x != y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmEQ:
|
||||
x = x == y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmADD:
|
||||
x = x + y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmSUB:
|
||||
x = x - y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmMUL:
|
||||
x = x * y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmDIV:
|
||||
|
||||
#if defined(MUP_MATH_EXCEPTIONS)
|
||||
if (y==0)
|
||||
{
|
||||
throw ParserError(ecDIV_BY_ZERO, "0");
|
||||
}
|
||||
#endif
|
||||
|
||||
x = x / y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
|
||||
case cmPOW: x = std::pow(x, y);
|
||||
case cmPOW:
|
||||
x = qPow(x, y);
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} // switch opcode
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add an operator identifier to bytecode.
|
||||
|
||||
Operator entries in byte code consist of:
|
||||
<ul>
|
||||
<li>value array position of the result</li>
|
||||
<li>the operator code according to ParserToken::ECmdCode</li>
|
||||
</ul>
|
||||
|
||||
\sa ParserToken::ECmdCode
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Add an operator identifier to bytecode.
|
||||
*
|
||||
* Operator entries in byte code consist of:
|
||||
* <ul>
|
||||
* <li>value array position of the result</li>
|
||||
* <li>the operator code according to ParserToken::ECmdCode</li>
|
||||
* </ul>
|
||||
*
|
||||
* @sa ParserToken::ECmdCode
|
||||
*/
|
||||
void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
|
||||
{
|
||||
|
@ -210,14 +249,21 @@ namespace qmu
|
|||
if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL)
|
||||
{
|
||||
if (m_vRPN[sz-1].Val.data2==2)
|
||||
{
|
||||
m_vRPN[sz-2].Cmd = cmVARPOW2;
|
||||
}
|
||||
else if (m_vRPN[sz-1].Val.data2==3)
|
||||
{
|
||||
m_vRPN[sz-2].Cmd = cmVARPOW3;
|
||||
}
|
||||
else if (m_vRPN[sz-1].Val.data2==4)
|
||||
{
|
||||
m_vRPN[sz-2].Cmd = cmVARPOW4;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
}
|
||||
m_vRPN.pop_back();
|
||||
bOptimized = true;
|
||||
}
|
||||
|
@ -231,30 +277,35 @@ namespace qmu
|
|||
(m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) )
|
||||
(m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR &&
|
||||
m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVARMUL
|
||||
&& m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR &&
|
||||
m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL &&
|
||||
m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) )
|
||||
{
|
||||
assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) ||
|
||||
(m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) ||
|
||||
(m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) );
|
||||
|
||||
m_vRPN[sz-2].Cmd = cmVARMUL;
|
||||
m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); // variable
|
||||
m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) |
|
||||
(long long)(m_vRPN[sz-1].Val.ptr)); // variable
|
||||
m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset
|
||||
m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior
|
||||
m_vRPN.pop_back();
|
||||
bOptimized = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case cmMUL:
|
||||
if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) ||
|
||||
(m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) )
|
||||
{
|
||||
m_vRPN[sz-2].Cmd = cmVARMUL;
|
||||
m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));
|
||||
m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) |
|
||||
(long long)(m_vRPN[sz-1].Val.ptr));
|
||||
m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2;
|
||||
m_vRPN[sz-2].Val.data2 = 0;
|
||||
m_vRPN.pop_back();
|
||||
|
@ -265,7 +316,8 @@ namespace qmu
|
|||
{
|
||||
// Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2
|
||||
m_vRPN[sz-2].Cmd = cmVARMUL;
|
||||
m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));
|
||||
m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) |
|
||||
(long long)(m_vRPN[sz-1].Val.ptr));
|
||||
if (m_vRPN[sz-1].Cmd == cmVAL)
|
||||
{
|
||||
m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2;
|
||||
|
@ -288,7 +340,6 @@ namespace qmu
|
|||
bOptimized = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case cmDIV:
|
||||
if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0)
|
||||
{
|
||||
|
@ -314,7 +365,7 @@ namespace qmu
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParserByteCode::AddIfElse(ECmdCode a_Oprt)
|
||||
{
|
||||
SToken tok;
|
||||
|
@ -322,16 +373,17 @@ namespace qmu
|
|||
m_vRPN.push_back(tok);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add an assignement operator
|
||||
|
||||
Operator entries in byte code consist of:
|
||||
<ul>
|
||||
<li>cmASSIGN code</li>
|
||||
<li>the pointer of the destination variable</li>
|
||||
</ul>
|
||||
|
||||
\sa ParserToken::ECmdCode
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Add an assignement operator
|
||||
*
|
||||
* Operator entries in byte code consist of:
|
||||
* <ul>
|
||||
* <li>cmASSIGN code</li>
|
||||
* <li>the pointer of the destination variable</li>
|
||||
* </ul>
|
||||
*
|
||||
* @sa ParserToken::ECmdCode
|
||||
*/
|
||||
void QmuParserByteCode::AddAssignOp(qreal *a_pVar)
|
||||
{
|
||||
|
@ -343,11 +395,12 @@ namespace qmu
|
|||
m_vRPN.push_back(tok);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add function to bytecode.
|
||||
|
||||
\param a_iArgc Number of arguments, negative numbers indicate multiarg functions.
|
||||
\param a_pFun Pointer to function callback.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Add function to bytecode.
|
||||
*
|
||||
* @param a_iArgc Number of arguments, negative numbers indicate multiarg functions.
|
||||
* @param a_pFun Pointer to function callback.
|
||||
*/
|
||||
void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc)
|
||||
{
|
||||
|
@ -369,11 +422,12 @@ namespace qmu
|
|||
m_vRPN.push_back(tok);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add a bulk function to bytecode.
|
||||
|
||||
\param a_iArgc Number of arguments, negative numbers indicate multiarg functions.
|
||||
\param a_pFun Pointer to function callback.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Add a bulk function to bytecode.
|
||||
*
|
||||
* @param a_iArgc Number of arguments, negative numbers indicate multiarg functions.
|
||||
* @param a_pFun Pointer to function callback.
|
||||
*/
|
||||
void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc)
|
||||
{
|
||||
|
@ -387,13 +441,13 @@ namespace qmu
|
|||
m_vRPN.push_back(tok);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add Strung function entry to the parser bytecode.
|
||||
\throw nothrow
|
||||
|
||||
A string function entry consists of the stack position of the return value,
|
||||
followed by a cmSTRFUNC code, the function pointer and an index into the
|
||||
string buffer maintained by the parser.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Add Strung function entry to the parser bytecode.
|
||||
* @throw nothrow
|
||||
*
|
||||
* A string function entry consists of the stack position of the return value, followed by a cmSTRFUNC code, the
|
||||
* function pointer and an index into the string buffer maintained by the parser.
|
||||
*/
|
||||
void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx)
|
||||
{
|
||||
|
@ -409,10 +463,11 @@ namespace qmu
|
|||
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add end marker to bytecode.
|
||||
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Add end marker to bytecode.
|
||||
*
|
||||
* @throw nothrow
|
||||
*/
|
||||
void QmuParserByteCode::Finalize()
|
||||
{
|
||||
|
@ -431,54 +486,57 @@ namespace qmu
|
|||
case cmIF:
|
||||
stIf.push(i);
|
||||
break;
|
||||
|
||||
case cmELSE:
|
||||
stElse.push(i);
|
||||
idx = stIf.pop();
|
||||
m_vRPN[idx].Oprt.offset = i - idx;
|
||||
break;
|
||||
|
||||
case cmENDIF:
|
||||
idx = stElse.pop();
|
||||
m_vRPN[idx].Oprt.offset = i - idx;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
const SToken* QmuParserByteCode::GetBase() const
|
||||
{
|
||||
if (m_vRPN.size()==0)
|
||||
{
|
||||
throw QmuParserError(ecINTERNAL_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
return &m_vRPN[0];
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
std::size_t QmuParserByteCode::GetMaxStackSize() const
|
||||
{
|
||||
return m_iMaxStackSize+1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Returns the number of entries in the bytecode. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Returns the number of entries in the bytecode.
|
||||
*/
|
||||
std::size_t QmuParserByteCode::GetSize() const
|
||||
{
|
||||
return m_vRPN.size();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Delete the bytecode.
|
||||
|
||||
\throw nothrow
|
||||
|
||||
The name of this function is a violation of my own coding guidelines
|
||||
but this way it's more in line with the STL functions thus more
|
||||
intuitive.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Delete the bytecode.
|
||||
*
|
||||
* @throw nothrow
|
||||
*
|
||||
* The name of this function is a violation of my own coding guidelines but this way it's more in line with the STL
|
||||
* functions thus more intuitive.
|
||||
*/
|
||||
void QmuParserByteCode::clear()
|
||||
{
|
||||
|
@ -487,8 +545,10 @@ namespace qmu
|
|||
m_iMaxStackSize = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Dump bytecode (for debugging only!). */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Dump bytecode (for debugging only!).
|
||||
*/
|
||||
void QmuParserByteCode::AsciiDump()
|
||||
{
|
||||
if (!m_vRPN.size())
|
||||
|
@ -503,62 +563,85 @@ namespace qmu
|
|||
qDebug() << i << " : \t";
|
||||
switch (m_vRPN[i].Cmd)
|
||||
{
|
||||
case cmVAL: qDebug() << "VAL \t" << "[" << m_vRPN[i].Val.data2 << "]\n";
|
||||
case cmVAL:
|
||||
qDebug() << "VAL \t" << "[" << m_vRPN[i].Val.data2 << "]\n";
|
||||
break;
|
||||
|
||||
case cmVAR: qDebug() << "VAR \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||
case cmVAR:
|
||||
qDebug() << "VAR \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||
break;
|
||||
|
||||
case cmVARPOW2: qDebug() << "VARPOW2 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||
case cmVARPOW2:
|
||||
qDebug() << "VARPOW2 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||
break;
|
||||
|
||||
case cmVARPOW3: qDebug() << "VARPOW3 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||
case cmVARPOW3:
|
||||
qDebug() << "VARPOW3 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||
break;
|
||||
|
||||
case cmVARPOW4: qDebug() << "VARPOW4 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||
case cmVARPOW4:
|
||||
qDebug() << "VARPOW4 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||
break;
|
||||
|
||||
case cmVARMUL: qDebug() << "VARMUL \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]"
|
||||
<< " * [" << m_vRPN[i].Val.data << "]" << " + [" << m_vRPN[i].Val.data2 << "]\n";
|
||||
case cmVARMUL:
|
||||
qDebug() << "VARMUL \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]" << " * ["
|
||||
<< m_vRPN[i].Val.data << "]" << " + [" << m_vRPN[i].Val.data2 << "]\n";
|
||||
break;
|
||||
|
||||
case cmFUNC: qDebug() << "CALL\t" << "[ARG:" << m_vRPN[i].Fun.argc << "]" << "[ADDR: 0x"
|
||||
<< m_vRPN[i].Fun.ptr << "]" << "\n";
|
||||
case cmFUNC:
|
||||
qDebug() << "CALL\t" << "[ARG:" << m_vRPN[i].Fun.argc << "]" << "[ADDR: 0x" << m_vRPN[i].Fun.ptr << "]"
|
||||
<< "\n";
|
||||
break;
|
||||
|
||||
case cmFUNC_STR:
|
||||
qDebug() << "CALL STRFUNC\t" << "[ARG:" << m_vRPN[i].Fun.argc << "]" << "[IDX:"
|
||||
<< m_vRPN[i].Fun.idx << "]" << "[ADDR: 0x" << m_vRPN[i].Fun.ptr
|
||||
<< "]\n";
|
||||
qDebug() << "CALL STRFUNC\t" << "[ARG:" << m_vRPN[i].Fun.argc << "]" << "[IDX:" << m_vRPN[i].Fun.idx
|
||||
<< "]" << "[ADDR: 0x" << m_vRPN[i].Fun.ptr << "]\n";
|
||||
break;
|
||||
|
||||
case cmLT: qDebug() << "LT\n"; break;
|
||||
case cmGT: qDebug() << "GT\n"; break;
|
||||
case cmLE: qDebug() << "LE\n"; break;
|
||||
case cmGE: qDebug() << "GE\n"; break;
|
||||
case cmEQ: qDebug() << "EQ\n"; break;
|
||||
case cmNEQ: qDebug() << "NEQ\n"; break;
|
||||
case cmADD: qDebug() << "ADD\n"; break;
|
||||
case cmLAND: qDebug() << "&&\n"; break;
|
||||
case cmLOR: qDebug() << "||\n"; break;
|
||||
case cmSUB: qDebug() << "SUB\n"; break;
|
||||
case cmMUL: qDebug() << "MUL\n"; break;
|
||||
case cmDIV: qDebug() << "DIV\n"; break;
|
||||
case cmPOW: qDebug() << "POW\n"; break;
|
||||
|
||||
case cmIF: qDebug() << "IF\t" << "[OFFSET:" << m_vRPN[i].Oprt.offset << "]\n";
|
||||
case cmLT:
|
||||
qDebug() << "LT\n";
|
||||
break;
|
||||
|
||||
case cmELSE: qDebug() << "ELSE\t" << "[OFFSET:" << m_vRPN[i].Oprt.offset << "]\n";
|
||||
case cmGT:
|
||||
qDebug() << "GT\n";
|
||||
break;
|
||||
|
||||
case cmENDIF: qDebug() << "ENDIF\n"; break;
|
||||
|
||||
case cmLE:
|
||||
qDebug() << "LE\n";
|
||||
break;
|
||||
case cmGE:
|
||||
qDebug() << "GE\n";
|
||||
break;
|
||||
case cmEQ:
|
||||
qDebug() << "EQ\n";
|
||||
break;
|
||||
case cmNEQ:
|
||||
qDebug() << "NEQ\n";
|
||||
break;
|
||||
case cmADD:
|
||||
qDebug() << "ADD\n";
|
||||
break;
|
||||
case cmLAND:
|
||||
qDebug() << "&&\n";
|
||||
break;
|
||||
case cmLOR:
|
||||
qDebug() << "||\n";
|
||||
break;
|
||||
case cmSUB:
|
||||
qDebug() << "SUB\n";
|
||||
break;
|
||||
case cmMUL:
|
||||
qDebug() << "MUL\n";
|
||||
break;
|
||||
case cmDIV:
|
||||
qDebug() << "DIV\n";
|
||||
break;
|
||||
case cmPOW:
|
||||
qDebug() << "POW\n";
|
||||
break;
|
||||
case cmIF:
|
||||
qDebug() << "IF\t" << "[OFFSET:" << m_vRPN[i].Oprt.offset << "]\n";
|
||||
break;
|
||||
case cmELSE:
|
||||
qDebug() << "ELSE\t" << "[OFFSET:" << m_vRPN[i].Oprt.offset << "]\n";
|
||||
break;
|
||||
case cmENDIF:
|
||||
qDebug() << "ENDIF\n"; break;
|
||||
case cmASSIGN:
|
||||
qDebug() << "ASSIGN\t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Oprt.ptr, 'f', 16) << "]\n";
|
||||
break;
|
||||
|
||||
default: qDebug() << "(unknown code: " << m_vRPN[i].Cmd << ")\n";
|
||||
default:
|
||||
qDebug() << "(unknown code: " << m_vRPN[i].Cmd << ")\n";
|
||||
break;
|
||||
} // switch cmdCode
|
||||
} // while bytecode
|
||||
|
|
|
@ -23,19 +23,15 @@
|
|||
#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
|
||||
|
@ -72,45 +68,42 @@ namespace qmu
|
|||
};
|
||||
|
||||
|
||||
/** \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);
|
||||
|
@ -119,20 +112,15 @@ public:
|
|||
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();
|
||||
};
|
||||
|
||||
} // namespace qmu
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -22,355 +22,209 @@
|
|||
|
||||
#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)
|
||||
: 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)
|
||||
: 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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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)
|
||||
: 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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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,
|
||||
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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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_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)
|
||||
: 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)
|
||||
: 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_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)
|
||||
: 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_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)
|
||||
: 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_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)
|
||||
: 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 ( 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)
|
||||
: 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 ( 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)
|
||||
: 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 ( 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)
|
||||
: 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)
|
||||
: 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 )
|
||||
{}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Default constructor.
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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)
|
||||
: 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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Copy constructor.
|
||||
* @throw nothrow
|
||||
*/
|
||||
QmuParserCallback::QmuParserCallback ( const QmuParserCallback &ref )
|
||||
{
|
||||
|
@ -383,76 +237,84 @@ namespace qmu
|
|||
m_eOprtAsct = ref.m_eOprtAsct;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Clone this instance and return a pointer to the new instance. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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).
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Returns the number of function Arguments.
|
||||
*/
|
||||
int QmuParserCallback::GetArgc() const
|
||||
{
|
||||
return m_iArgc;
|
||||
|
|
|
@ -25,24 +25,23 @@
|
|||
|
||||
#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
|
||||
{
|
||||
|
@ -80,7 +79,6 @@ public:
|
|||
QmuParserCallback(const QmuParserCallback &a_Fun);
|
||||
|
||||
QmuParserCallback* Clone() const;
|
||||
|
||||
bool IsOptimizable() const;
|
||||
void* GetAddr() const;
|
||||
ECmdCode GetCode() const;
|
||||
|
@ -88,14 +86,14 @@ public:
|
|||
int GetPri() const;
|
||||
EOprtAssociativity GetAssociativity() 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.
|
||||
|
@ -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,27 +37,27 @@
|
|||
|
||||
#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. */
|
||||
/** @brief Definition of the basic parser string type. */
|
||||
#define QMUP_STRING_TYPE std::wstring
|
||||
#else
|
||||
/** \brief Definition of the basic parser string type. */
|
||||
/** @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!
|
||||
*/
|
||||
|
@ -113,7 +109,7 @@ namespace qmu
|
|||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Types internally used by the parser.
|
||||
/** @brief Types internally used by the parser.
|
||||
*/
|
||||
enum ETypeCode
|
||||
{
|
||||
|
@ -130,7 +126,7 @@ namespace qmu
|
|||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Parser operator precedence values. */
|
||||
/** @brief Parser operator precedence values. */
|
||||
enum EOprtAssociativity
|
||||
{
|
||||
oaLEFT = 0,
|
||||
|
@ -139,7 +135,7 @@ namespace qmu
|
|||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Parser operator precedence values. */
|
||||
/** @brief Parser operator precedence values. */
|
||||
enum EOprtPrecedence
|
||||
{
|
||||
// binary operators
|
||||
|
@ -159,121 +155,119 @@ namespace qmu
|
|||
//------------------------------------------------------------------------------
|
||||
// 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;
|
||||
|
||||
/** \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;
|
||||
|
||||
/** \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
|
||||
|
||||
/** \brief Type used for storing variables. */
|
||||
/** @brief Type used for storing variables. */
|
||||
typedef std::map<QString, qreal*> varmap_type;
|
||||
|
||||
/** \brief Type used for storing constants. */
|
||||
/** @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. */
|
||||
/** @brief Type for assigning a string name to an index in the internal string table. */
|
||||
typedef std::map<QString, int> strmap_type;
|
||||
|
||||
// Parser callbacks
|
||||
|
||||
/** \brief Callback type used for functions without arguments. */
|
||||
/** @brief Callback type used for functions without arguments. */
|
||||
typedef qreal ( *generic_fun_type ) ();
|
||||
|
||||
/** \brief Callback type used for functions without arguments. */
|
||||
/** @brief Callback type used for functions without arguments. */
|
||||
typedef qreal ( *fun_type0 ) ();
|
||||
|
||||
/** \brief Callback type used for functions with a single arguments. */
|
||||
/** @brief Callback type used for functions with a single arguments. */
|
||||
typedef qreal ( *fun_type1 ) ( qreal );
|
||||
|
||||
/** \brief Callback type used for functions with two arguments. */
|
||||
/** @brief Callback type used for functions with two arguments. */
|
||||
typedef qreal ( *fun_type2 ) ( qreal, qreal );
|
||||
|
||||
/** \brief Callback type used for functions with three arguments. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @brief Callback type used for functions without arguments. */
|
||||
typedef qreal ( *bulkfun_type0 ) ( int, int );
|
||||
|
||||
/** \brief Callback type used for functions with a single arguments. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @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. */
|
||||
/** @brief Callback used for variable creation factory functions. */
|
||||
typedef qreal* ( *facfun_type ) ( const QString &, void* );
|
||||
} // end of namespace
|
||||
|
||||
|
|
|
@ -24,29 +24,29 @@
|
|||
|
||||
#include <QTextStream>
|
||||
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
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.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Assignement operator is deactivated.
|
||||
*/
|
||||
QmuParserErrorMsg& QmuParserErrorMsg::operator= ( const QmuParserErrorMsg& )
|
||||
{
|
||||
|
@ -54,11 +54,11 @@ namespace qmu
|
|||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserErrorMsg::QmuParserErrorMsg ( const QmuParserErrorMsg& )
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserErrorMsg::QmuParserErrorMsg()
|
||||
: m_vErrMsg ( 0 )
|
||||
{
|
||||
|
@ -103,48 +103,49 @@ namespace qmu
|
|||
|
||||
#if defined(_DEBUG)
|
||||
for ( int i = 0; i < ecCOUNT; ++i )
|
||||
{
|
||||
if ( !m_vErrMsg[i].length() )
|
||||
{
|
||||
assert ( false );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// QParserError class
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
/** \brief Default constructor. */
|
||||
/**
|
||||
* @brief Default constructor.
|
||||
*/
|
||||
QmuParserError::QmuParserError()
|
||||
:m_strMsg()
|
||||
,m_strFormula()
|
||||
,m_strTok()
|
||||
,m_iPos(-1)
|
||||
,m_iErrc(ecUNDEFINED)
|
||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||
: 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.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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_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. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Construct an error from a message text.
|
||||
*/
|
||||
QmuParserError::QmuParserError ( const QString &sMsg )
|
||||
: m_ErrMsg ( QmuParserErrorMsg::Instance() )
|
||||
{
|
||||
|
@ -152,84 +153,72 @@ namespace qmu
|
|||
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.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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_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.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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_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.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/** @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())
|
||||
: 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. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/** @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())
|
||||
: 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. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/** @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;
|
||||
|
@ -239,14 +228,15 @@ namespace qmu
|
|||
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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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 )
|
||||
{
|
||||
|
@ -268,8 +258,10 @@ void QmuParserError::ReplaceSubString( QString &strSource, const QString &strFin
|
|||
strSource.swap ( strResult );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Reset the erro object. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Reset the erro object.
|
||||
*/
|
||||
void QmuParserError::Reset()
|
||||
{
|
||||
m_strMsg = "";
|
||||
|
@ -279,46 +271,57 @@ void QmuParserError::ReplaceSubString( QString &strSource, const QString &strFin
|
|||
m_iErrc = ecUNDEFINED;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Set the expression related to this error. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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.*/
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief gets the expression related tp this error.
|
||||
*/
|
||||
const QString& QmuParserError::GetExpr() const
|
||||
{
|
||||
return m_strFormula;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Returns the message string for this error. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @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). */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return string related with this token (if available).
|
||||
*/
|
||||
const QString& QmuParserError::GetToken() const
|
||||
{
|
||||
return m_strTok;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Return the error code. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return the error code.
|
||||
*/
|
||||
EErrorCodes QmuParserError::GetCode() const
|
||||
{
|
||||
return m_iErrc;
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
|
||||
#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
|
||||
|
@ -92,7 +92,7 @@ enum EErrorCodes
|
|||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief A class that handles the error messages.
|
||||
/** @brief A class that handles the error messages.
|
||||
*/
|
||||
class QmuParserErrorMsg
|
||||
{
|
||||
|
@ -102,7 +102,6 @@ public:
|
|||
QmuParserErrorMsg& operator= ( const QmuParserErrorMsg & );
|
||||
QmuParserErrorMsg ( const QmuParserErrorMsg& );
|
||||
QmuParserErrorMsg();
|
||||
|
||||
~QmuParserErrorMsg();
|
||||
|
||||
static const QmuParserErrorMsg& Instance();
|
||||
|
@ -114,21 +113,13 @@ private:
|
|||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \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();
|
||||
|
@ -155,6 +146,11 @@ private:
|
|||
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.
|
||||
*/
|
||||
|
||||
//
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
/** \file
|
||||
\brief This file contains the implementation of parser test cases.
|
||||
/**
|
||||
* @file
|
||||
* @brief This file contains the implementation of parser test cases.
|
||||
*/
|
||||
|
||||
namespace qmu
|
||||
|
@ -40,7 +41,7 @@ namespace qmu
|
|||
{
|
||||
int QmuParserTester::c_iCount = 0;
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserTester::QmuParserTester()
|
||||
: m_vTestFun()
|
||||
{
|
||||
|
@ -60,11 +61,13 @@ namespace qmu
|
|||
QmuParserTester::c_iCount = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal )
|
||||
{
|
||||
if ( a_szExpr[1] == 0 || ( a_szExpr[0] != '0' || a_szExpr[1] != 'x' ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned iVal ( 0 );
|
||||
bool ok = false;
|
||||
|
@ -74,7 +77,9 @@ namespace qmu
|
|||
{
|
||||
int nPos = a_szExpr.indexOf ( QString().setNum ( iVal, 16 ) );
|
||||
if ( nPos == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
*a_iPos += ( int ) ( 2 + nPos );
|
||||
*a_fVal = ( qreal ) iVal;
|
||||
|
@ -87,7 +92,7 @@ namespace qmu
|
|||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestInterface()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -122,14 +127,18 @@ namespace qmu
|
|||
}
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestStrArg()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -147,14 +156,18 @@ namespace qmu
|
|||
iStat += EqnTest ( "strfun3(\"99\",1,2)", 102, true );
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestBinOprt()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -218,15 +231,19 @@ namespace qmu
|
|||
iStat += EqnTest ( "3+4*2/(1-5)^2^3", 3.0001220703125, true );
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
/** \brief Check muParser name restriction enforcement. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/** @brief Check muParser name restriction enforcement. */
|
||||
int QmuParserTester::TestNames()
|
||||
{
|
||||
int iStat = 0,
|
||||
|
@ -327,14 +344,18 @@ namespace qmu
|
|||
#undef PARSER_THROWCHECK
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestSyntax()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -376,14 +397,18 @@ namespace qmu
|
|||
iStat += EqnTest ( "sin()", 0, false ); // unexpected closing bracket
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestVarConst()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -437,46 +462,66 @@ namespace qmu
|
|||
qmu::varmap_type UsedVar = p.GetUsedVar();
|
||||
int iCount = ( int ) UsedVar.size();
|
||||
if ( iCount != 4 )
|
||||
{
|
||||
throw false;
|
||||
}
|
||||
|
||||
// the next check will fail if the parser
|
||||
// erroneousely creates new variables internally
|
||||
if ( p.GetVar().size() != 5 )
|
||||
{
|
||||
throw false;
|
||||
}
|
||||
|
||||
qmu::varmap_type::const_iterator item = UsedVar.begin();
|
||||
for ( idx = 0; item != UsedVar.end(); ++item )
|
||||
{
|
||||
if ( &vVarVal[idx++] != item->second )
|
||||
{
|
||||
throw false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test lookup of undefined variables
|
||||
p.SetExpr ( "undef1+undef2+undef3" );
|
||||
UsedVar = p.GetUsedVar();
|
||||
iCount = ( int ) UsedVar.size();
|
||||
if ( iCount != 3 )
|
||||
{
|
||||
throw false;
|
||||
}
|
||||
|
||||
// the next check will fail if the parser
|
||||
// erroneousely creates new variables internally
|
||||
if ( p.GetVar().size() != 5 )
|
||||
{
|
||||
throw false;
|
||||
}
|
||||
|
||||
for ( item = UsedVar.begin(); item != UsedVar.end(); ++item )
|
||||
{
|
||||
if ( item->second != 0 )
|
||||
{
|
||||
throw false; // all pointers to undefined variables must be null
|
||||
}
|
||||
}
|
||||
|
||||
// 1 used variables
|
||||
p.SetExpr ( "a+b" );
|
||||
UsedVar = p.GetUsedVar();
|
||||
iCount = ( int ) UsedVar.size();
|
||||
if (iCount!=2) throw false;
|
||||
if ( iCount != 2 )
|
||||
{
|
||||
throw false;
|
||||
}
|
||||
item = UsedVar.begin();
|
||||
for ( idx = 0; item != UsedVar.end(); ++item )
|
||||
if (&vVarVal[idx++]!=item->second) throw false;
|
||||
{
|
||||
if ( &vVarVal[idx++] != item->second )
|
||||
{
|
||||
throw false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch ( ... )
|
||||
|
@ -485,14 +530,18 @@ namespace qmu
|
|||
}
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestMultiArg()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -579,15 +628,19 @@ namespace qmu
|
|||
iStat += EqnTest ( "sum(,1,2)", 0, false );
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestInfixOprt()
|
||||
{
|
||||
int iStat ( 0 );
|
||||
|
@ -644,15 +697,19 @@ namespace qmu
|
|||
iStat += EqnTest ( "~~ 123", 123 + 2, true );
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestPostFix()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -696,14 +753,18 @@ namespace qmu
|
|||
iStat += ThrowTest ( "multi*1.0", ecUNASSIGNABLE_TOKEN );
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestExpression()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -756,7 +817,8 @@ namespace qmu
|
|||
iStat += EqnTest ( "(cos(2.41)/b)", -0.372056, true );
|
||||
iStat += EqnTest ( "(1*(2*(3*(4*(5*(6*(a+b)))))))", 2160, true );
|
||||
iStat += EqnTest ( "(1*(2*(3*(4*(5*(6*(7*(a+b))))))))", 15120, true );
|
||||
iStat += EqnTest( "(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))", 0.00377999, true);
|
||||
iStat += EqnTest ( "(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))",
|
||||
0.00377999, true );
|
||||
|
||||
// long formula (Reference: Matlab)
|
||||
iStat += EqnTest (
|
||||
|
@ -776,16 +838,20 @@ namespace qmu
|
|||
iStat += EqnTest ( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true );
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestIfThenElse()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -884,14 +950,18 @@ namespace qmu
|
|||
iStat += EqnTest ( "a=0?5:b=1?3:4, b", 3, true );
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors";
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::TestException()
|
||||
{
|
||||
int iStat = 0;
|
||||
|
@ -978,29 +1048,35 @@ namespace qmu
|
|||
iStat += ThrowTest ( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT );
|
||||
|
||||
if ( iStat == 0 )
|
||||
{
|
||||
qDebug() << "passed" ;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n failed with " << iStat << " errors" ;
|
||||
}
|
||||
|
||||
return iStat;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParserTester::AddTest ( testfun_type a_pFun )
|
||||
{
|
||||
m_vTestFun.push_back ( a_pFun );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParserTester::Run()
|
||||
{
|
||||
int iStat = 0;
|
||||
try
|
||||
{
|
||||
for ( int i = 0; i < ( int ) m_vTestFun.size(); ++i )
|
||||
{
|
||||
iStat += ( this->*m_vTestFun[i] ) ();
|
||||
}
|
||||
}
|
||||
catch ( QmuParser::exception_type &e )
|
||||
{
|
||||
qDebug() << "\n" << e.GetMsg() ;
|
||||
|
@ -1032,7 +1108,7 @@ namespace qmu
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
int QmuParserTester::ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail )
|
||||
{
|
||||
QmuParserTester::c_iCount++;
|
||||
|
@ -1081,15 +1157,13 @@ namespace qmu
|
|||
return bRet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Evaluate a tet expression.
|
||||
|
||||
\return 1 in case of a failure, 0 otherwise.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Evaluate a tet expression.
|
||||
*
|
||||
* @return 1 in case of a failure, 0 otherwise.
|
||||
*/
|
||||
int QmuParserTester::EqnTestWithVarChange(const QString &a_str,
|
||||
double a_fVar1,
|
||||
double a_fRes1,
|
||||
double a_fVar2,
|
||||
int QmuParserTester::EqnTestWithVarChange ( const QString &a_str, double a_fVar1, double a_fRes1, double a_fVar2,
|
||||
double a_fRes2 )
|
||||
{
|
||||
QmuParserTester::c_iCount++;
|
||||
|
@ -1111,11 +1185,15 @@ namespace qmu
|
|||
fVal[1] = p.Eval();
|
||||
|
||||
if ( fabs ( a_fRes1 - fVal[0] ) > 0.0000000001 )
|
||||
{
|
||||
throw std::runtime_error ( "incorrect result (first pass)" );
|
||||
}
|
||||
|
||||
if ( fabs ( a_fRes2 - fVal[1] ) > 0.0000000001 )
|
||||
{
|
||||
throw std::runtime_error ( "incorrect result (second pass)" );
|
||||
}
|
||||
}
|
||||
catch ( QmuParser::exception_type &e )
|
||||
{
|
||||
qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")";
|
||||
|
@ -1135,10 +1213,11 @@ namespace qmu
|
|||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Evaluate a tet expression.
|
||||
|
||||
\return 1 in case of a failure, 0 otherwise.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Evaluate a tet expression.
|
||||
*
|
||||
* @return 1 in case of a failure, 0 otherwise.
|
||||
*/
|
||||
int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass )
|
||||
{
|
||||
|
@ -1228,7 +1307,9 @@ namespace qmu
|
|||
fVal[0] = p1->Eval(); // result from stringparsing
|
||||
fVal[1] = p1->Eval(); // result from bytecode
|
||||
if ( fVal[0] != fVal[1] )
|
||||
{
|
||||
throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." );
|
||||
}
|
||||
|
||||
// Test copy and assignement operators
|
||||
try
|
||||
|
@ -1272,8 +1353,10 @@ namespace qmu
|
|||
// reference:
|
||||
// http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825
|
||||
if ( numeric_limits<qreal>::has_infinity )
|
||||
{
|
||||
bCloseEnough &= ( fabs ( fVal[i] ) != numeric_limits<qreal>::infinity() );
|
||||
}
|
||||
}
|
||||
|
||||
iRet = ( ( bCloseEnough && a_fPass ) || ( !bCloseEnough && !a_fPass ) ) ? 0 : 1;
|
||||
|
||||
|
@ -1294,9 +1377,13 @@ namespace qmu
|
|||
if ( a_fPass )
|
||||
{
|
||||
if ( fVal[0] != fVal[2] && fVal[0] != -999 && fVal[1] != -998 )
|
||||
{
|
||||
qDebug() << "\n fail: " << a_str << " (copy construction)";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -1314,8 +1401,10 @@ namespace qmu
|
|||
return iRet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Internal error in test class Test is going to be aborted. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Internal error in test class Test is going to be aborted.
|
||||
*/
|
||||
void QmuParserTester::Abort() const
|
||||
{
|
||||
qDebug() << "Test failed (internal error in test class)" ;
|
||||
|
|
|
@ -29,61 +29,164 @@
|
|||
#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. */
|
||||
/**
|
||||
* @brief Namespace for test cases.
|
||||
*/
|
||||
namespace Test
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
/** \brief Test cases for unit testing.
|
||||
|
||||
(C) 2004-2011 Ingo Berg
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Test cases for unit testing.
|
||||
*
|
||||
* (C) 2004-2011 Ingo Berg
|
||||
*/
|
||||
class QmuParserTester // final
|
||||
{
|
||||
public:
|
||||
typedef int ( QmuParserTester::*testfun_type ) ();
|
||||
|
||||
QmuParserTester();
|
||||
void Run();
|
||||
private:
|
||||
QVector<testfun_type> m_vTestFun;
|
||||
static int c_iCount;
|
||||
|
||||
void AddTest ( testfun_type a_pFun );
|
||||
|
||||
// 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 );
|
||||
|
||||
// Multiarg callbacks
|
||||
static qreal f1of1(qreal v) { return v;}
|
||||
static qreal f1of1 ( qreal v )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static qreal f1of2(qreal v, qreal ) {return v;}
|
||||
static qreal f2of2(qreal , qreal v) {return v;}
|
||||
static qreal f1of2 ( qreal v, qreal )
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
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;}
|
||||
static qreal f2of2 ( qreal , 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 f1of3 ( qreal v, qreal , 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 f2of3 ( qreal , qreal v, qreal )
|
||||
{
|
||||
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 f3of3 ( qreal , qreal , qreal v )
|
||||
{
|
||||
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 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 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 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 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 FirstArg ( const qreal* a_afArg, int a_iArgc )
|
||||
{
|
||||
if ( !a_iArgc )
|
||||
{
|
||||
throw qmu::QmuParser::exception_type ( "too few arguments for function FirstArg." );
|
||||
}
|
||||
|
||||
return a_afArg[0];
|
||||
}
|
||||
|
@ -91,7 +194,9 @@ namespace qmu
|
|||
static qreal LastArg ( const qreal* a_afArg, int a_iArgc )
|
||||
{
|
||||
if ( !a_iArgc )
|
||||
{
|
||||
throw qmu::QmuParser::exception_type ( "too few arguments for function LastArg." );
|
||||
}
|
||||
|
||||
return a_afArg[a_iArgc - 1];
|
||||
}
|
||||
|
@ -99,10 +204,15 @@ namespace qmu
|
|||
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];
|
||||
for ( int i = 0; i < a_iArgc; ++i )
|
||||
{
|
||||
fRes += a_afArg[i];
|
||||
}
|
||||
return fRes;
|
||||
}
|
||||
|
||||
|
@ -151,9 +261,20 @@ namespace qmu
|
|||
}
|
||||
|
||||
// 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 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 );
|
||||
|
@ -172,25 +293,6 @@ namespace qmu
|
|||
int TestIfThenElse();
|
||||
|
||||
void Abort() const;
|
||||
|
||||
public:
|
||||
typedef int (QmuParserTester::*testfun_type)();
|
||||
|
||||
QmuParserTester();
|
||||
void Run();
|
||||
|
||||
private:
|
||||
QVector<testfun_type> m_vTestFun;
|
||||
void AddTest(testfun_type a_pFun);
|
||||
|
||||
// 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
|
||||
} // namespace qmu
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -20,22 +20,15 @@
|
|||
**
|
||||
******************************************************************************************************/
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include "qmuparsertokenreader.h"
|
||||
#include "qmuparserbase.h"
|
||||
|
||||
/** \file
|
||||
\brief This file contains the parser token reader implementation.
|
||||
*/
|
||||
#include <QStringList>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief This file contains the parser token reader implementation.
|
||||
*/
|
||||
|
||||
namespace qmu
|
||||
{
|
||||
|
@ -43,38 +36,43 @@ namespace qmu
|
|||
// Forward declaration
|
||||
class QmuParserBase;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Copy constructor.
|
||||
|
||||
\sa Assign
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Copy constructor.
|
||||
*
|
||||
* @sa Assign
|
||||
* @throw nothrow
|
||||
*/
|
||||
QmuParserTokenReader::QmuParserTokenReader ( const QmuParserTokenReader &a_Reader )
|
||||
{
|
||||
Assign ( a_Reader );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Assignement operator.
|
||||
|
||||
Self assignement will be suppressed otherwise #Assign is called.
|
||||
|
||||
\param a_Reader Object to copy to this token reader.
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Assignement operator.
|
||||
*
|
||||
* Self assignement will be suppressed otherwise #Assign is called.
|
||||
*
|
||||
* @param a_Reader Object to copy to this token reader.
|
||||
* @throw nothrow
|
||||
*/
|
||||
QmuParserTokenReader& QmuParserTokenReader::operator= ( const QmuParserTokenReader &a_Reader )
|
||||
{
|
||||
if ( &a_Reader != this )
|
||||
{
|
||||
Assign ( a_Reader );
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Assign state of a token reader to this token reader.
|
||||
|
||||
\param a_Reader Object from which the state should be copied.
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Assign state of a token reader to this token reader.
|
||||
*
|
||||
* @param a_Reader Object from which the state should be copied.
|
||||
* @throw nothrow
|
||||
*/
|
||||
void QmuParserTokenReader::Assign ( const QmuParserTokenReader &a_Reader )
|
||||
{
|
||||
|
@ -99,49 +97,34 @@ namespace qmu
|
|||
m_cArgSep = a_Reader.m_cArgSep;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Constructor.
|
||||
|
||||
Create a Token reader and bind it to a parser object.
|
||||
|
||||
\pre [assert] a_pParser may not be NULL
|
||||
\post #m_pParser==a_pParser
|
||||
\param a_pParent Parent parser object of the token reader.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Constructor.
|
||||
*
|
||||
* Create a Token reader and bind it to a parser object.
|
||||
*
|
||||
* @pre [assert] a_pParser may not be NULL
|
||||
* @post #m_pParser==a_pParser
|
||||
* @param a_pParent Parent parser object of the token reader.
|
||||
*/
|
||||
QmuParserTokenReader::QmuParserTokenReader ( QmuParserBase *a_pParent )
|
||||
:m_pParser(a_pParent)
|
||||
,m_strFormula()
|
||||
,m_iPos(0)
|
||||
,m_iSynFlags(0)
|
||||
,m_bIgnoreUndefVar(false)
|
||||
,m_pFunDef(NULL)
|
||||
,m_pPostOprtDef(NULL)
|
||||
,m_pInfixOprtDef(NULL)
|
||||
,m_pOprtDef(NULL)
|
||||
,m_pConstDef(NULL)
|
||||
,m_pStrVarDef(NULL)
|
||||
,m_pVarDef(NULL)
|
||||
,m_pFactory(NULL)
|
||||
,m_pFactoryData(NULL)
|
||||
,m_vIdentFun()
|
||||
,m_UsedVar()
|
||||
,m_fZero(0)
|
||||
,m_iBrackets(0)
|
||||
,m_lastTok()
|
||||
,m_cArgSep(',')
|
||||
: m_pParser ( a_pParent ), m_strFormula(), m_iPos ( 0 ), m_iSynFlags ( 0 ), m_bIgnoreUndefVar ( false ),
|
||||
m_pFunDef ( NULL ), m_pPostOprtDef ( NULL ), m_pInfixOprtDef ( NULL ), m_pOprtDef ( NULL ), m_pConstDef ( NULL ),
|
||||
m_pStrVarDef ( NULL ), m_pVarDef ( NULL ), m_pFactory ( NULL ), m_pFactoryData ( NULL ), m_vIdentFun(),
|
||||
m_UsedVar(), m_fZero ( 0 ), m_iBrackets ( 0 ), m_lastTok(), m_cArgSep ( ',' )
|
||||
{
|
||||
assert ( m_pParser );
|
||||
SetParent ( m_pParser );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Create instance of a QParserTokenReader identical with this
|
||||
and return its pointer.
|
||||
|
||||
This is a factory method the calling function must take care of the object destruction.
|
||||
|
||||
\return A new QParserTokenReader object.
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Create instance of a QParserTokenReader identical with this and return its pointer.
|
||||
*
|
||||
* This is a factory method the calling function must take care of the object destruction.
|
||||
*
|
||||
* @return A new QParserTokenReader object.
|
||||
* @throw nothrow
|
||||
*/
|
||||
QmuParserTokenReader* QmuParserTokenReader::Clone ( QmuParserBase *a_pParent ) const
|
||||
{
|
||||
|
@ -150,14 +133,14 @@ namespace qmu
|
|||
return ptr.release();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QmuParserTokenReader::token_type& QmuParserTokenReader::SaveBeforeReturn ( const token_type &tok )
|
||||
{
|
||||
m_lastTok = tok;
|
||||
return m_lastTok;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParserTokenReader::AddValIdent ( identfun_type a_pCallback )
|
||||
{
|
||||
// Use push_front is used to give user defined callbacks a higher priority than
|
||||
|
@ -169,47 +152,52 @@ namespace qmu
|
|||
m_vIdentFun.push_front ( a_pCallback );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParserTokenReader::SetVarCreator ( facfun_type a_pFactory, void *pUserData )
|
||||
{
|
||||
m_pFactory = a_pFactory;
|
||||
m_pFactoryData = pUserData;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Return the current position of the token reader in the formula string.
|
||||
|
||||
\return #m_iPos
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return the current position of the token reader in the formula string.
|
||||
*
|
||||
* @return #m_iPos
|
||||
* @throw nothrow
|
||||
*/
|
||||
int QmuParserTokenReader::GetPos() const
|
||||
{
|
||||
return m_iPos;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Return a reference to the formula.
|
||||
|
||||
\return #m_strFormula
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return a reference to the formula.
|
||||
*
|
||||
* @return #m_strFormula
|
||||
* @throw nothrow
|
||||
*/
|
||||
const QString& QmuParserTokenReader::GetExpr() const
|
||||
{
|
||||
return m_strFormula;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Return a map containing the used variables only. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Return a map containing the used variables only.
|
||||
*/
|
||||
varmap_type& QmuParserTokenReader::GetUsedVar()
|
||||
{
|
||||
return m_UsedVar;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Initialize the token Reader.
|
||||
|
||||
Sets the formula position index to zero and set Syntax flags to default for initial formula parsing.
|
||||
\pre [assert] triggered if a_szFormula==0
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Initialize the token Reader.
|
||||
*
|
||||
* Sets the formula position index to zero and set Syntax flags to default for initial formula parsing.
|
||||
* @pre [assert] triggered if a_szFormula==0
|
||||
*/
|
||||
void QmuParserTokenReader::SetFormula ( const QString &a_strFormula )
|
||||
{
|
||||
|
@ -217,28 +205,28 @@ namespace qmu
|
|||
ReInit();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Set Flag that contronls behaviour in case of undefined variables beeing found.
|
||||
|
||||
If true, the parser does not throw an exception if an undefined variable is found.
|
||||
otherwise it does. This variable is used internally only!
|
||||
It supresses a "undefined variable" exception in GetUsedVar().
|
||||
Those function should return a complete list of variables including
|
||||
those the are not defined by the time of it's call.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Set Flag that contronls behaviour in case of undefined variables beeing found.
|
||||
*
|
||||
* If true, the parser does not throw an exception if an undefined variable is found. Otherwise it does. This variable
|
||||
* is used internally only! It supresses a "undefined variable" exception in GetUsedVar().
|
||||
* Those function should return a complete list of variables including
|
||||
* those the are not defined by the time of it's call.
|
||||
*/
|
||||
void QmuParserTokenReader::IgnoreUndefVar ( bool bIgnore )
|
||||
{
|
||||
m_bIgnoreUndefVar = bIgnore;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Reset the token reader to the start of the formula.
|
||||
|
||||
The syntax flags will be reset to a value appropriate for the
|
||||
start of a formula.
|
||||
\post #m_iPos==0, #m_iSynFlags = noOPT | noBC | noPOSTOP | noSTR
|
||||
\throw nothrow
|
||||
\sa ESynCodes
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Reset the token reader to the start of the formula.
|
||||
*
|
||||
* The syntax flags will be reset to a value appropriate for the start of a formula.
|
||||
* @post #m_iPos==0, #m_iSynFlags = noOPT | noBC | noPOSTOP | noSTR
|
||||
* @throw nothrow
|
||||
* @sa ESynCodes
|
||||
*/
|
||||
void QmuParserTokenReader::ReInit()
|
||||
{
|
||||
|
@ -249,13 +237,14 @@ namespace qmu
|
|||
m_lastTok = token_type();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Read the next token from the string. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Read the next token from the string.
|
||||
*/
|
||||
QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken()
|
||||
{
|
||||
assert ( m_pParser );
|
||||
|
||||
//std::stack<int> FunArgs;
|
||||
#if defined(_UNICODE)
|
||||
const char_type *szFormula = m_strFormula.toStdWString().c_str();
|
||||
#else
|
||||
|
@ -308,7 +297,7 @@ namespace qmu
|
|||
return token_type(); // never reached
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParserTokenReader::SetParent ( QmuParserBase *a_pParent )
|
||||
{
|
||||
m_pParser = a_pParent;
|
||||
|
@ -321,14 +310,15 @@ namespace qmu
|
|||
m_pConstDef = &a_pParent->m_ConstDef;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Extract all characters that belong to a certain charset.
|
||||
|
||||
\param a_szCharSet [in] Const char array of the characters allowed in the token.
|
||||
\param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet.
|
||||
\param a_iPos [in] Position in the string from where to start reading.
|
||||
\return The Position of the first character not listed in a_szCharSet.
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Extract all characters that belong to a certain charset.
|
||||
*
|
||||
* @param a_szCharSet [in] Const char array of the characters allowed in the token.
|
||||
* @param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet.
|
||||
* @param a_iPos [in] Position in the string from where to start reading.
|
||||
* @return The Position of the first character not listed in a_szCharSet.
|
||||
* @throw nothrow
|
||||
*/
|
||||
int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_sTok, int a_iPos ) const
|
||||
{
|
||||
|
@ -360,13 +350,13 @@ int QmuParserTokenReader::ExtractToken(const QString &a_szCharSet, QString &a_sT
|
|||
return iEnd;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check Expression for the presence of a binary operator token.
|
||||
|
||||
Userdefined binary operator "++" gives inconsistent parsing result for
|
||||
the equations "a++b" and "a ++ b" if alphabetic characters are allowed
|
||||
in operator tokens. To avoid this this function checks specifically
|
||||
for operator tokens.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check Expression for the presence of a binary operator token.
|
||||
*
|
||||
* Userdefined binary operator "++" gives inconsistent parsing result for the equations "a++b" and "a ++ b" if
|
||||
* alphabetic characters are allowed in operator tokens. To avoid this this function checks specifically
|
||||
* for operator tokens.
|
||||
*/
|
||||
int QmuParserTokenReader::ExtractOperatorToken ( QString &a_sTok, int a_iPos ) const
|
||||
{
|
||||
|
@ -402,10 +392,11 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check if a built in operator or other token can be found
|
||||
\param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token.
|
||||
\return true if an operator token has been found.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check if a built in operator or other token can be found
|
||||
* @param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token.
|
||||
* @return true if an operator token has been found.
|
||||
*/
|
||||
bool QmuParserTokenReader::IsBuiltIn ( token_type &a_Tok )
|
||||
{
|
||||
|
@ -509,7 +500,7 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
bool QmuParserTokenReader::IsArgSep ( token_type &a_Tok )
|
||||
{
|
||||
if ( m_strFormula.at ( m_iPos ) == m_cArgSep )
|
||||
|
@ -533,13 +524,14 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check for End of Formula.
|
||||
|
||||
\return true if an end of formula is found false otherwise.
|
||||
\param a_Tok [out] If an eof is found the corresponding token will be stored there.
|
||||
\throw nothrow
|
||||
\sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check for End of Formula.
|
||||
*
|
||||
* @return true if an end of formula is found false otherwise.
|
||||
* @param a_Tok [out] If an eof is found the corresponding token will be stored there.
|
||||
* @throw nothrow
|
||||
* @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok
|
||||
*/
|
||||
bool QmuParserTokenReader::IsEOF ( token_type &a_Tok )
|
||||
{
|
||||
|
@ -566,9 +558,10 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check if a string position contains a unary infix operator.
|
||||
\return true if a function token has been found false otherwise.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check if a string position contains a unary infix operator.
|
||||
* @return true if a function token has been found false otherwise.
|
||||
*/
|
||||
bool QmuParserTokenReader::IsInfixOpTok ( token_type &a_Tok )
|
||||
{
|
||||
|
@ -608,12 +601,13 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
*/
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check whether the token at a given position is a function token.
|
||||
\param a_Tok [out] If a value token is found it will be placed here.
|
||||
\throw ParserException if Syntaxflags do not allow a function at a_iPos
|
||||
\return true if a function token has been found false otherwise.
|
||||
\pre [assert] m_pParser!=0
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check whether the token at a given position is a function token.
|
||||
* @param a_Tok [out] If a value token is found it will be placed here.
|
||||
* @throw ParserException if Syntaxflags do not allow a function at a_iPos
|
||||
* @return true if a function token has been found false otherwise.
|
||||
* @pre [assert] m_pParser!=0
|
||||
*/
|
||||
bool QmuParserTokenReader::IsFunTok ( token_type &a_Tok )
|
||||
{
|
||||
|
@ -640,10 +634,11 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check if a string position contains a binary operator.
|
||||
\param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token.
|
||||
\return true if an operator token has been found.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check if a string position contains a binary operator.
|
||||
* @param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token.
|
||||
* @return true if an operator token has been found.
|
||||
*/
|
||||
bool QmuParserTokenReader::IsOprt ( token_type &a_Tok )
|
||||
{
|
||||
|
@ -704,8 +699,10 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check if a string position contains a unary post value operator. */
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check if a string position contains a unary post value operator.
|
||||
*/
|
||||
bool QmuParserTokenReader::IsPostOpTok ( token_type &a_Tok )
|
||||
{
|
||||
// <ibg 20110629> Do not check for postfix operators if they are not allowed at
|
||||
|
@ -750,13 +747,14 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check whether the token at a given position is a value token.
|
||||
|
||||
Value tokens are either values or constants.
|
||||
|
||||
\param a_Tok [out] If a value token is found it will be placed here.
|
||||
\return true if a value token has been found.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check whether the token at a given position is a value token.
|
||||
*
|
||||
* Value tokens are either values or constants.
|
||||
*
|
||||
* @param a_Tok [out] If a value token is found it will be placed here.
|
||||
* @return true if a value token has been found.
|
||||
*/
|
||||
bool QmuParserTokenReader::IsValTok ( token_type &a_Tok )
|
||||
{
|
||||
|
@ -807,10 +805,11 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check wheter a token at a given position is a variable token.
|
||||
\param a_Tok [out] If a variable token has been found it will be placed here.
|
||||
\return true if a variable token has been found.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check wheter a token at a given position is a variable token.
|
||||
* @param a_Tok [out] If a variable token has been found it will be placed here.
|
||||
* @return true if a variable token has been found.
|
||||
*/
|
||||
bool QmuParserTokenReader::IsVarTok ( token_type &a_Tok )
|
||||
{
|
||||
|
@ -842,7 +841,7 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
bool QmuParserTokenReader::IsStrVarTok ( token_type &a_Tok )
|
||||
{
|
||||
if ( !m_pStrVarDef || !m_pStrVarDef->size() )
|
||||
|
@ -871,19 +870,22 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check wheter a token at a given position is an undefined variable.
|
||||
|
||||
\param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here.
|
||||
\return true if a variable token has been found.
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check wheter a token at a given position is an undefined variable.
|
||||
*
|
||||
* @param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here.
|
||||
* @return true if a variable token has been found.
|
||||
* @throw nothrow
|
||||
*/
|
||||
bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok )
|
||||
{
|
||||
QString strTok;
|
||||
int iEnd ( ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ) );
|
||||
if ( iEnd == m_iPos )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( m_iSynFlags & noVAR )
|
||||
{
|
||||
|
@ -923,12 +925,13 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Check wheter a token at a given position is a string.
|
||||
\param a_Tok [out] If a variable token has been found it will be placed here.
|
||||
\return true if a string token has been found.
|
||||
\sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok
|
||||
\throw nothrow
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Check wheter a token at a given position is a string.
|
||||
* @param a_Tok [out] If a variable token has been found it will be placed here.
|
||||
* @return true if a string token has been found.
|
||||
* @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok
|
||||
* @throw nothrow
|
||||
*/
|
||||
bool QmuParserTokenReader::IsString ( token_type &a_Tok )
|
||||
{
|
||||
|
@ -963,30 +966,29 @@ int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) cons
|
|||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Create an error containing the parse error position.
|
||||
|
||||
This function will create an Parser Exception object containing the error text and its position.
|
||||
|
||||
\param a_iErrc [in] The error code of type #EErrorCodes.
|
||||
\param a_iPos [in] The position where the error was detected.
|
||||
\param a_strTok [in] The token string representation associated with the error.
|
||||
\throw ParserException always throws thats the only purpose of this function.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Create an error containing the parse error position.
|
||||
*
|
||||
* This function will create an Parser Exception object containing the error text and its position.
|
||||
*
|
||||
* @param a_iErrc [in] The error code of type #EErrorCodes.
|
||||
* @param a_iPos [in] The position where the error was detected.
|
||||
* @param a_strTok [in] The token string representation associated with the error.
|
||||
* @throw ParserException always throws thats the only purpose of this function.
|
||||
*/
|
||||
void QmuParserTokenReader::Error( EErrorCodes a_iErrc,
|
||||
int a_iPos,
|
||||
const QString &a_sTok) const
|
||||
void QmuParserTokenReader::Error ( EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok ) const
|
||||
{
|
||||
m_pParser->Error ( a_iErrc, a_iPos, a_sTok );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void QmuParserTokenReader::SetArgSep ( char_type cArgSep )
|
||||
{
|
||||
m_cArgSep = cArgSep;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
QChar QmuParserTokenReader::GetArgSep() const
|
||||
{
|
||||
return m_cArgSep;
|
||||
|
|
|
@ -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