2014-05-01 13:33:40 +02:00
|
|
|
/***************************************************************************************************
|
|
|
|
**
|
2015-02-27 11:21:09 +01:00
|
|
|
** Copyright (C) 2013 Ingo Berg
|
2014-05-01 13:33:40 +02:00
|
|
|
**
|
|
|
|
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
|
|
** software and associated documentation files (the "Software"), to deal in the Software
|
|
|
|
** without restriction, including without limitation the rights to use, copy, modify,
|
|
|
|
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
|
|
**
|
|
|
|
** The above copyright notice and this permission notice shall be included in all copies or
|
|
|
|
** substantial portions of the Software.
|
|
|
|
**
|
|
|
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
|
|
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
|
|
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
**
|
|
|
|
******************************************************************************************************/
|
|
|
|
|
|
|
|
#ifndef QMUQPARSERBASE_H
|
|
|
|
#define QMUQPARSERBASE_H
|
|
|
|
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QChar>
|
2023-07-13 16:49:20 +02:00
|
|
|
#include <QLocale>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QMap>
|
2014-05-01 13:33:40 +02:00
|
|
|
#include <QStack>
|
|
|
|
#include <QString>
|
|
|
|
#include <QStringList>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QVector>
|
2023-07-13 16:49:20 +02:00
|
|
|
#include <QtCore/qcontainerfwd.h>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QtGlobal>
|
2023-07-13 16:49:20 +02:00
|
|
|
#include <climits>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
2014-05-01 13:33:40 +02:00
|
|
|
|
2016-08-08 13:44:49 +02:00
|
|
|
#include "qmuparser_global.h"
|
|
|
|
#include "qmuparserbytecode.h"
|
|
|
|
#include "qmuparsercallback.h"
|
2014-05-01 13:33:40 +02:00
|
|
|
#include "qmuparserdef.h"
|
2016-08-08 13:44:49 +02:00
|
|
|
#include "qmuparsererror.h"
|
|
|
|
#include "qmuparsertoken.h"
|
2014-05-01 13:33:40 +02:00
|
|
|
#include "qmuparsertokenreader.h"
|
2016-08-08 13:44:49 +02:00
|
|
|
|
2014-05-01 13:33:40 +02:00
|
|
|
namespace qmu
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @brief This file contains the class definition of the qmuparser engine.
|
|
|
|
*/
|
|
|
|
|
2021-09-25 16:18:33 +02:00
|
|
|
QT_WARNING_PUSH
|
|
|
|
QT_WARNING_DISABLE_GCC("-Wsuggest-final-types")
|
|
|
|
QT_WARNING_DISABLE_GCC("-Wsuggest-final-methods")
|
|
|
|
|
2014-05-01 13:33:40 +02:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2014-05-06 11:45:21 +02:00
|
|
|
class QMUPARSERSHARED_EXPORT QmuParserBase
|
2014-05-01 13:33:40 +02:00
|
|
|
{
|
|
|
|
friend class QmuParserTokenReader;
|
2023-07-13 16:49:20 +02:00
|
|
|
|
2014-05-01 13:33:40 +02:00
|
|
|
public:
|
|
|
|
QmuParserBase();
|
2015-10-12 13:52:48 +02:00
|
|
|
explicit QmuParserBase(const QmuParserBase &a_Parser);
|
2023-05-03 13:07:02 +02:00
|
|
|
auto operator=(const QmuParserBase &a_Parser) -> QmuParserBase &;
|
2014-05-01 13:33:40 +02:00
|
|
|
virtual ~QmuParserBase();
|
|
|
|
|
2023-07-13 16:49:20 +02:00
|
|
|
static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
|
2023-05-03 13:07:02 +02:00
|
|
|
auto Eval() const -> qreal;
|
|
|
|
auto Eval(int &nStackSize) const -> qreal *;
|
2023-07-13 16:49:20 +02:00
|
|
|
void Eval(qreal *results, int nBulkSize) const;
|
2023-05-03 13:07:02 +02:00
|
|
|
auto GetNumResults() const -> int;
|
2023-07-13 16:49:20 +02:00
|
|
|
void SetExpr(const QString &a_sExpr);
|
|
|
|
void SetVarFactory(facfun_type a_pFactory, void *pUserData = nullptr);
|
|
|
|
void ResetLocale();
|
|
|
|
void EnableOptimizer(bool a_bIsOn = true);
|
|
|
|
void EnableBuiltInOprt(bool a_bIsOn = true);
|
2023-05-03 13:07:02 +02:00
|
|
|
auto HasBuiltInOprt() const -> bool;
|
2023-07-13 16:49:20 +02:00
|
|
|
void AddValIdent(identfun_type a_pCallback);
|
|
|
|
void DefineOprt(const QString &a_sName, fun_type2 a_pFun, unsigned a_iPrec = 0,
|
|
|
|
EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
|
|
|
|
void DefineConst(const QString &a_sName, qreal a_fVal);
|
|
|
|
void DefineStrConst(const QString &a_strName, const QString &a_strVal);
|
|
|
|
void DefineVar(const QString &a_sName, qreal *a_pVar);
|
|
|
|
void DefinePostfixOprt(const QString &a_sFun, fun_type1 a_pFun, bool a_bAllowOpt = true);
|
|
|
|
void DefineInfixOprt(const QString &a_sName, fun_type1 a_pFun, int a_iPrec = prINFIX, bool a_bAllowOpt = true);
|
2014-05-01 13:33:40 +02:00
|
|
|
// Clear user defined variables, constants or functions
|
2023-07-13 16:49:20 +02:00
|
|
|
void ClearVar();
|
|
|
|
void ClearFun();
|
|
|
|
void ClearConst();
|
|
|
|
void ClearInfixOprt();
|
|
|
|
void ClearPostfixOprt();
|
|
|
|
void ClearOprt();
|
|
|
|
void RemoveVar(const QString &a_strVarName);
|
2023-05-03 13:07:02 +02:00
|
|
|
auto GetUsedVar() const -> const varmap_type &;
|
|
|
|
auto GetVar() const -> const varmap_type &;
|
|
|
|
auto GetConst() const -> const valmap_type &;
|
|
|
|
auto GetExpr() const -> const QString &;
|
|
|
|
auto GetFunDef() const -> const funmap_type &;
|
|
|
|
static auto GetVersion(EParserVersionInfo eInfo = pviFULL) -> QString;
|
|
|
|
static auto GetOprtDef() -> const QStringList &;
|
|
|
|
auto GetTokens() const -> QMap<qmusizetype, QString>;
|
|
|
|
auto GetNumbers() const -> QMap<qmusizetype, QString>;
|
2023-07-13 16:49:20 +02:00
|
|
|
void DefineNameChars(const QString &a_szCharset);
|
|
|
|
void DefineOprtChars(const QString &a_szCharset);
|
|
|
|
void DefineInfixOprtChars(const QString &a_szCharset);
|
2023-05-03 13:07:02 +02:00
|
|
|
auto ValidNameChars() const -> const QString &;
|
|
|
|
auto ValidOprtChars() const -> const QString &;
|
|
|
|
auto ValidInfixOprtChars() const -> const QString &;
|
2023-07-13 16:49:20 +02:00
|
|
|
void SetArgSep(char_type cArgSep);
|
2023-05-03 13:07:02 +02:00
|
|
|
auto GetArgSep() const -> QChar;
|
2023-07-13 16:49:20 +02:00
|
|
|
Q_NORETURN void Error(EErrorCodes a_iErrc, qmusizetype a_iPos = -1, const QString &a_sTok = QString()) const;
|
2015-07-03 16:03:19 +02:00
|
|
|
|
2023-07-13 16:49:20 +02:00
|
|
|
template <typename T> void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true);
|
2015-07-03 16:03:19 +02:00
|
|
|
|
2014-08-29 15:42:53 +02:00
|
|
|
void setAllowSubexpressions(bool value);
|
|
|
|
|
2023-05-03 13:07:02 +02:00
|
|
|
auto getLocale() const -> QLocale;
|
2023-07-13 16:49:20 +02:00
|
|
|
void setLocale(const QLocale &value);
|
2017-01-03 10:14:32 +01:00
|
|
|
|
2023-05-03 13:07:02 +02:00
|
|
|
auto getDecimalPoint() const -> QChar;
|
2023-07-13 16:49:20 +02:00
|
|
|
void setDecimalPoint(const QChar &c);
|
2017-01-03 10:14:32 +01:00
|
|
|
|
2023-05-03 13:07:02 +02:00
|
|
|
auto getThousandsSeparator() const -> QChar;
|
2023-07-13 16:49:20 +02:00
|
|
|
void setThousandsSeparator(const QChar &c);
|
2015-02-10 12:39:31 +01:00
|
|
|
|
2023-05-03 13:07:02 +02:00
|
|
|
auto getCNumbers() const -> bool;
|
2019-10-30 10:34:01 +01:00
|
|
|
void setCNumbers(bool cNumbers);
|
|
|
|
|
2014-05-01 13:33:40 +02:00
|
|
|
protected:
|
2018-01-24 21:08:53 +01:00
|
|
|
/**
|
|
|
|
* @brief Typedef for the token reader.
|
|
|
|
*/
|
|
|
|
typedef QmuParserTokenReader token_reader_type;
|
|
|
|
|
2014-05-01 13:33:40 +02:00
|
|
|
static const QStringList c_DefaultOprt;
|
2023-07-13 16:49:20 +02:00
|
|
|
QLocale m_locale; ///< The locale used by the parser
|
2017-01-03 10:14:32 +01:00
|
|
|
QChar m_decimalPoint;
|
|
|
|
QChar m_thousandsSeparator;
|
2023-07-13 16:49:20 +02:00
|
|
|
bool m_cNumbers{false}; ///< Search numbers in c locale
|
|
|
|
funmap_type m_FunDef; ///< Map of function names and pointers.
|
2018-01-24 21:08:53 +01:00
|
|
|
std::unique_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
|
2014-05-01 13:33:40 +02:00
|
|
|
static bool g_DbgDumpCmdCode;
|
|
|
|
static bool g_DbgDumpStack;
|
2017-12-04 10:44:29 +01:00
|
|
|
void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, funmap_type &a_Storage,
|
2023-07-13 16:49:20 +02:00
|
|
|
const QString &a_szCharSet);
|
2014-05-01 13:33:40 +02:00
|
|
|
void Init();
|
|
|
|
virtual void InitCharSets() = 0;
|
|
|
|
virtual void InitFun() = 0;
|
|
|
|
virtual void InitConst() = 0;
|
|
|
|
virtual void InitOprt() = 0;
|
2023-02-09 16:23:11 +01:00
|
|
|
virtual void OnDetectVar(const QString &pExpr, qmusizetype &nStart, qmusizetype &nEnd);
|
2014-05-01 13:33:40 +02:00
|
|
|
/**
|
|
|
|
* @brief A facet class used to change decimal and thousands separator.
|
|
|
|
*/
|
2023-07-13 16:49:20 +02:00
|
|
|
template <class TChar> class change_dec_sep : public std::numpunct<TChar>
|
2014-05-01 13:33:40 +02:00
|
|
|
{
|
2023-07-13 16:49:20 +02:00
|
|
|
public:
|
|
|
|
explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
|
|
|
|
: std::numpunct<TChar>(),
|
|
|
|
m_nGroup(nGroup),
|
|
|
|
m_cDecPoint(cDecSep),
|
|
|
|
m_cThousandsSep(cThousandsSep)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual auto do_decimal_point() const -> char_type override { return m_cDecPoint; }
|
|
|
|
|
|
|
|
virtual auto do_thousands_sep() const -> char_type override { return m_cThousandsSep; }
|
|
|
|
|
|
|
|
virtual auto do_grouping() const -> std::string override
|
|
|
|
{
|
|
|
|
// fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4
|
|
|
|
// courtesy of Jens Bartsch
|
|
|
|
// original code:
|
|
|
|
// return std::string(1, (char)m_nGroup);
|
|
|
|
// new code:
|
|
|
|
return std::string(1, static_cast<char>(m_cThousandsSep > 0 ? m_nGroup : CHAR_MAX));
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int m_nGroup;
|
|
|
|
char_type m_cDecPoint;
|
|
|
|
char_type m_cThousandsSep;
|
2014-05-01 13:33:40 +02:00
|
|
|
};
|
2023-07-13 16:49:20 +02:00
|
|
|
|
2014-05-01 13:33:40 +02:00
|
|
|
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 Type used for parser tokens.
|
|
|
|
*/
|
|
|
|
typedef QmuParserToken<qreal, QString> token_type;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Maximum number of threads spawned by OpenMP when using the bulk mode.
|
|
|
|
*/
|
|
|
|
static const int s_MaxNumOpenMPThreads = 4;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Pointer to the parser function.
|
|
|
|
*
|
|
|
|
* Eval() calls the function whose address is stored there.
|
|
|
|
*/
|
2023-07-13 16:49:20 +02:00
|
|
|
mutable ParseFunction m_pParseFormula;
|
|
|
|
mutable QmuParserByteCode m_vRPN; ///< The Bytecode class.
|
|
|
|
mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
|
|
|
|
stringbuf_type m_vStringVarBuf;
|
2014-05-01 13:33:40 +02:00
|
|
|
|
2023-07-13 16:49:20 +02:00
|
|
|
funmap_type m_PostOprtDef; ///< Postfix operator callbacks
|
|
|
|
funmap_type m_InfixOprtDef; ///< unary infix operator.
|
|
|
|
funmap_type m_OprtDef; ///< Binary operator callbacks
|
|
|
|
valmap_type m_ConstDef; ///< user constants.
|
|
|
|
strmap_type m_StrVarDef; ///< user defined string constants
|
|
|
|
varmap_type m_VarDef; ///< user defind variables.
|
2014-05-01 13:33:40 +02:00
|
|
|
|
2023-07-13 16:49:20 +02:00
|
|
|
bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
|
2014-05-01 13:33:40 +02:00
|
|
|
|
|
|
|
QString m_sNameChars; ///< Charset for names
|
|
|
|
QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens
|
|
|
|
QString m_sInfixOprtChars; ///< Charset for infix operator tokens
|
|
|
|
|
2023-07-13 16:49:20 +02:00
|
|
|
mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses
|
2014-05-01 13:33:40 +02:00
|
|
|
|
|
|
|
// 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;
|
2023-07-13 16:49:20 +02:00
|
|
|
mutable QMap<qmusizetype, QString> m_Tokens; ///< Keep all tokens that we can translate
|
|
|
|
mutable QMap<qmusizetype, QString> m_Numbers; ///< Keep all numbers what exist in formula
|
2014-05-01 13:33:40 +02:00
|
|
|
|
2014-08-29 15:42:53 +02:00
|
|
|
bool allowSubexpressions;
|
|
|
|
|
2023-07-13 16:49:20 +02:00
|
|
|
void Assign(const QmuParserBase &a_Parser);
|
|
|
|
void InitTokenReader();
|
|
|
|
void ReInit() const;
|
|
|
|
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;
|
2023-05-03 13:07:02 +02:00
|
|
|
auto ApplyStrFunc(const token_type &a_FunTok, const QVector<token_type> &a_vArg) const -> token_type;
|
|
|
|
auto GetOprtPrecedence(const token_type &a_Tok) const -> int;
|
|
|
|
auto GetOprtAssociativity(const token_type &a_Tok) const -> EOprtAssociativity;
|
2023-07-13 16:49:20 +02:00
|
|
|
void CreateRPN() const;
|
2023-05-03 13:07:02 +02:00
|
|
|
auto ParseString() const -> qreal;
|
|
|
|
auto ParseCmdCode() const -> qreal;
|
|
|
|
auto ParseCmdCodeBulk(int nOffset, int nThreadID) const -> qreal;
|
2015-10-12 13:52:48 +02:00
|
|
|
// cppcheck-suppress functionStatic
|
2023-07-13 16:49:20 +02:00
|
|
|
void CheckName(const QString &a_sName, const QString &a_szCharSet) const;
|
2015-10-12 13:52:48 +02:00
|
|
|
// cppcheck-suppress functionStatic
|
2023-07-13 16:49:20 +02:00
|
|
|
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;
|
2014-05-01 13:33:40 +02:00
|
|
|
};
|
|
|
|
|
2022-08-08 14:25:14 +02:00
|
|
|
// cppcheck-suppress unknownMacro
|
2021-09-25 16:18:33 +02:00
|
|
|
QT_WARNING_POP
|
|
|
|
|
2015-07-03 16:03:19 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
*/
|
2023-07-13 16:49:20 +02:00
|
|
|
template <typename T> inline void QmuParserBase::DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt)
|
2015-07-03 16:03:19 +02:00
|
|
|
{
|
2023-07-13 16:49:20 +02:00
|
|
|
AddCallback(a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars());
|
2015-07-03 16:03:19 +02:00
|
|
|
}
|
|
|
|
|
2014-05-06 16:36:42 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Initialize the token reader.
|
|
|
|
*
|
|
|
|
* Create new token reader object and submit pointers to function, operator, constant and variable definitions.
|
|
|
|
*
|
|
|
|
* @post m_pTokenReader.get()!=0
|
|
|
|
*/
|
2014-05-07 10:33:56 +02:00
|
|
|
inline void QmuParserBase::InitTokenReader()
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
m_pTokenReader.reset(new token_reader_type(this));
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Add a value parsing function.
|
|
|
|
*
|
|
|
|
* When parsing an expression muParser tries to detect values in the expression string using different valident
|
|
|
|
* callbacks. Thuis it's possible to parse for hex values, binary values and floating point values.
|
|
|
|
*/
|
|
|
|
inline void QmuParserBase::AddValIdent(identfun_type a_pCallback)
|
|
|
|
{
|
|
|
|
m_pTokenReader->AddValIdent(a_pCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Get the default symbols used for the built in operators.
|
|
|
|
* @sa c_DefaultOprt
|
|
|
|
*/
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::GetOprtDef() -> const QStringList &
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
return c_DefaultOprt;
|
|
|
|
}
|
|
|
|
|
2014-06-03 14:15:17 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::GetTokens() const -> QMap<qmusizetype, QString>
|
2014-05-22 14:11:14 +02:00
|
|
|
{
|
|
|
|
return m_Tokens;
|
|
|
|
}
|
|
|
|
|
2014-06-03 14:15:17 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::GetNumbers() const -> QMap<qmusizetype, QString>
|
2014-05-22 14:11:14 +02:00
|
|
|
{
|
|
|
|
return m_Numbers;
|
|
|
|
}
|
|
|
|
|
2014-05-06 16:36:42 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Define the set of valid characters to be used in names of functions, variables, constants.
|
|
|
|
*/
|
2014-05-22 14:11:14 +02:00
|
|
|
inline void QmuParserBase::DefineNameChars(const QString &a_szCharset)
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
m_sNameChars = a_szCharset;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Define the set of valid characters to be used in names of binary operators and postfix operators.
|
|
|
|
*/
|
2014-05-22 14:11:14 +02:00
|
|
|
inline void QmuParserBase::DefineOprtChars(const QString &a_szCharset)
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
m_sOprtChars = a_szCharset;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Define the set of valid characters to be used in names of infix operators.
|
|
|
|
*/
|
2014-05-22 14:11:14 +02:00
|
|
|
inline void QmuParserBase::DefineInfixOprtChars(const QString &a_szCharset)
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
m_sInfixOprtChars = a_szCharset;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Return a map containing the used variables only.
|
|
|
|
*/
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::GetVar() const -> const varmap_type &
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
return m_VarDef;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Return a map containing all parser constants.
|
|
|
|
*/
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::GetConst() const -> const valmap_type &
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
return m_ConstDef;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Return prototypes of all parser functions.
|
|
|
|
* @return #m_FunDef
|
|
|
|
* @sa FunProt
|
|
|
|
* @throw nothrow
|
|
|
|
*
|
|
|
|
* The return type is a map of the public type #funmap_type containing the prototype definitions for all numerical
|
|
|
|
* parser functions. String functions are not part of this map. The Prototype definition is encapsulated in objects
|
|
|
|
* of the class FunProt one per parser function each associated with function names via a map construct.
|
|
|
|
*/
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::GetFunDef() const -> const funmap_type &
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
return m_FunDef;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Retrieve the formula.
|
|
|
|
*/
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::GetExpr() const -> const QString &
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
return m_pTokenReader->GetExpr();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Query status of built in variables.
|
|
|
|
* @return #m_bBuiltInOp; true if built in operators are enabled.
|
|
|
|
* @throw nothrow
|
|
|
|
*/
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::HasBuiltInOprt() const -> bool
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
return m_bBuiltInOp;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Return the number of results on the calculation stack.
|
|
|
|
*
|
|
|
|
* If the expression contains comma seperated subexpressions (i.e. "sin(y), x+y"). There mey be more than one return
|
|
|
|
* value. This function returns the number of available results.
|
|
|
|
*/
|
|
|
|
// cppcheck-suppress unusedFunction
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::GetNumResults() const -> int
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
return m_nFinalResultIdx;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief Calculate the result.
|
|
|
|
*
|
|
|
|
* A note on const correctness:
|
|
|
|
* I consider it important that Calc is a const function.
|
|
|
|
* Due to caching operations Calc changes only the state of internal variables with one exception
|
|
|
|
* m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making
|
|
|
|
* Calc non const GetUsedVar is non const because it explicitely calls Eval() forcing this update.
|
|
|
|
*
|
|
|
|
* @pre A formula must be set.
|
|
|
|
* @pre Variables must have been set (if needed)
|
|
|
|
*
|
|
|
|
* @sa #m_pParseFormula
|
|
|
|
* @return The evaluation result
|
|
|
|
* @throw ParseException if no Formula is set or in case of any other error related to the formula.
|
|
|
|
*/
|
2023-05-03 13:07:02 +02:00
|
|
|
inline auto QmuParserBase::Eval() const -> qreal
|
2014-05-06 16:36:42 +02:00
|
|
|
{
|
|
|
|
return (this->*m_pParseFormula)();
|
|
|
|
}
|
|
|
|
|
2014-05-01 13:33:40 +02:00
|
|
|
} // namespace qmu
|
|
|
|
|
|
|
|
#endif
|