25 #include <QMessageLogger>
27 #include <QStringList>
28 #include <QTextStream>
31 #ifdef QMUP_USE_OPENMP
37 #include "../vmisc/vmath.h"
57 <<
"-" <<
"*" <<
"/" <<
"^" <<
"&&" <<
"||" <<
"="
58 <<
"(" <<
")" <<
"?" <<
":";
65 : m_locale(QLocale::c()),
66 m_decimalPoint(QLocale::c().decimalPoint()),
67 m_thousandsSeparator(QLocale::c().groupSeparator()),
87 m_Tokens(
QMap<int, QString>()),
88 m_Numbers(
QMap<int, QString>()),
89 allowSubexpressions(true)
101 : m_locale(a_Parser.getLocale()),
102 m_decimalPoint(a_Parser.getDecimalPoint()),
103 m_thousandsSeparator(a_Parser.getThousandsSeparator()),
122 m_nFinalResultIdx(0),
123 m_Tokens(
QMap<int, QString>()),
124 m_Numbers(
QMap<int, QString>()),
125 allowSubexpressions(true)
146 if (
this != &a_Parser)
292 QTextStream ss(&versionInfo);
299 ss <<
"; " <<
sizeof(
void*)*8 <<
"BIT";
317 #ifdef QMUP_USE_OPENMP
323 #if defined(MUP_MATH_EXCEPTIONS)
339 funmap_type &a_Storage,
const QString &a_szCharSet )
341 if (a_Callback.
GetAddr() ==
nullptr)
369 CheckOprt(a_strName, a_Callback, a_szCharSet);
370 a_Storage[a_strName] = a_Callback;
382 const QString &a_szCharSet)
const
384 const std::wstring a_sNameStd = a_sName.toStdWString();
385 const std::wstring a_szCharSetStd = a_szCharSet.toStdWString();
387 if ( a_sNameStd.length() ==
false || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) ||
388 (a_sNameStd.at(0)>=
'0' && a_sNameStd.at(0)<=
'9'))
413 std::wstring a_sNameStd = a_sName.toStdWString();
414 std::wstring a_szCharSetStd = a_szCharSet.toStdWString();
416 if ( a_sNameStd.length() ==
false || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) ||
417 (a_sNameStd[0]>=
'0' && a_sNameStd[0]<=
'9'))
435 if (
m_pTokenReader->GetArgSep()==std::use_facet<std::numpunct<char_type> >(loc).decimal_point())
445 QString sBuf(a_sExpr +
" " );
585 if (a_pVar ==
nullptr)
731 if (a_vArg.back().GetCode()!=
cmSTRING)
747 a_vArg[0].GetAsString();
751 a_vArg[1].GetAsString();
756 a_vArg[2].GetAsString();
790 if (a_stOpt.empty() || a_stOpt.top().GetFuncAddr() ==
nullptr)
808 int iArgNumerical = iArgCount - ((funTok.
GetType()==
tpSTR) ? 1 : 0);
815 if (funTok.
GetArgCount()>=0 && iArgCount>iArgRequired)
833 for (
int i=0; i<iArgNumerical; ++i)
835 if (a_stVal.isEmpty())
839 stArg.push_back( a_stVal.pop() );
849 stArg.push_back(a_stVal.pop());
885 while (a_stOpt.size() && a_stOpt.top().GetCode()==
cmELSE)
888 Q_ASSERT(a_stOpt.size()>0);
893 Q_ASSERT(a_stOpt.size()>0);
894 Q_ASSERT(a_stVal.size()>=2);
901 a_stVal.push( not qFuzzyIsNull(vExpr.
GetVal()) ? vVal1 : vVal2);
930 valTok2 = a_stVal.pop(),
931 optTok = a_stOpt.pop(),
941 if (valTok2.GetCode()!=
cmVAR)
952 a_stVal.push(resTok);
964 while (stOpt.size() && stOpt.top().GetCode() !=
cmBO && stOpt.top().GetCode() !=
cmIF)
966 const ECmdCode code = stOpt.top().GetCode();
1026 Stack[sidx] = Stack[sidx] <= Stack[sidx+1];
1030 Stack[sidx] = Stack[sidx] >= Stack[sidx+1];
1042 Stack[sidx] = Stack[sidx] < Stack[sidx+1];
1046 Stack[sidx] = Stack[sidx] > Stack[sidx+1];
1050 Stack[sidx] += Stack[1+sidx];
1054 Stack[sidx] -= Stack[1+sidx];
1058 Stack[sidx] *= Stack[1+sidx];
1062 #if defined(MUP_MATH_EXCEPTIONS)
1063 if (Stack[1+sidx]==0)
1068 Stack[sidx] /= Stack[1+sidx];
1072 Stack[sidx] = qPow(Stack[sidx], Stack[1+sidx]);
1077 QT_WARNING_DISABLE_GCC(
"-Wfloat-equal")
1078 Stack[sidx] =
static_cast<bool>(Stack[sidx]) &&
static_cast<bool>(Stack[sidx+1]);
1084 QT_WARNING_DISABLE_GCC(
"-Wfloat-equal")
1085 Stack[sidx] =
static_cast<bool>(Stack[sidx]) ||
static_cast<bool>(Stack[sidx+1]);
1095 Stack[sidx] = *(pTok->Oprt.ptr + nOffset) = Stack[sidx + 1];
1102 if (qFuzzyIsNull(Stack[sidx--]))
1104 pTok += pTok->Oprt.offset;
1108 pTok += pTok->Oprt.offset;
1115 Stack[++sidx] = *(pTok->Val.ptr + nOffset);
1118 Stack[++sidx] = pTok->Val.data2;
1121 buf = *(pTok->Val.ptr + nOffset);
1122 Stack[++sidx] = buf*buf;
1125 buf = *(pTok->Val.ptr + nOffset);
1126 Stack[++sidx] = buf*buf*buf;
1129 buf = *(pTok->Val.ptr + nOffset);
1130 Stack[++sidx] = buf*buf*buf*buf;
1133 Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2;
1138 int iArgCount = pTok->Fun.argc;
1141 QT_WARNING_DISABLE_CLANG(
"-Wundefined-reinterpret-cast")
1142 QT_WARNING_DISABLE_MSVC(4191)
1143 void* fPtr =
reinterpret_cast<void*
>(pTok->Fun.ptr);
1149 Stack[sidx] = (*
reinterpret_cast<fun_type0>(fPtr))();
1152 Stack[sidx] = (*
reinterpret_cast<fun_type1>(fPtr))(Stack[sidx]);
1156 Stack[sidx] = (*
reinterpret_cast<fun_type2>(fPtr))(Stack[sidx], Stack[sidx+1]);
1160 Stack[sidx] = (*
reinterpret_cast<fun_type3>(fPtr))(Stack[sidx], Stack[sidx+1],
1165 Stack[sidx] = (*
reinterpret_cast<fun_type4>(fPtr))(Stack[sidx], Stack[sidx+1],
1166 Stack[sidx+2], Stack[sidx+3]);
1170 Stack[sidx] = (*
reinterpret_cast<fun_type5>(fPtr))(Stack[sidx], Stack[sidx+1],
1171 Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]);
1175 Stack[sidx] = (*
reinterpret_cast<fun_type6>(fPtr))(Stack[sidx], Stack[sidx+1],
1176 Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]);
1180 Stack[sidx] = (*
reinterpret_cast<fun_type7>(fPtr))(Stack[sidx], Stack[sidx+1],
1181 Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]);
1185 Stack[sidx] = (*
reinterpret_cast<fun_type8>(fPtr))(Stack[sidx], Stack[sidx+1],
1186 Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6],
1191 Stack[sidx] = (*
reinterpret_cast<fun_type9>(fPtr))(Stack[sidx], Stack[sidx+1],
1192 Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6],
1193 Stack[sidx+7], Stack[sidx+8]);
1197 Stack[sidx] = (*
reinterpret_cast<fun_type10>(fPtr))(Stack[sidx], Stack[sidx+1],
1198 Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6],
1199 Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]);
1207 sidx -= -iArgCount - 1;
1208 Stack[sidx] =(*
reinterpret_cast<multfun_type>(fPtr))(&Stack[sidx], -iArgCount);
1215 sidx -= pTok->Fun.argc -1;
1218 int iIdxStack = pTok->Fun.idx;
1219 void* fPtr =
reinterpret_cast<void*
>(pTok->Fun.ptr);
1220 Q_ASSERT( iIdxStack>=0 && iIdxStack<
m_vStringBuf.size() );
1222 switch (pTok->Fun.argc)
1233 Stack[sidx], Stack[sidx+1]);
1243 int iArgCount = pTok->Fun.argc;
1245 void* fPtr =
reinterpret_cast<void*
>(pTok->Fun.ptr);
1251 Stack[sidx] = (*
reinterpret_cast<bulkfun_type0>(fPtr))(nOffset, nThreadID);
1254 Stack[sidx] = (*
reinterpret_cast<bulkfun_type1>(fPtr))(nOffset, nThreadID,
1259 Stack[sidx] = (*
reinterpret_cast<bulkfun_type2>(fPtr))(nOffset, nThreadID, Stack[sidx],
1264 Stack[sidx] = (*
reinterpret_cast<bulkfun_type3>(fPtr))(nOffset, nThreadID, Stack[sidx],
1265 Stack[sidx+1], Stack[sidx+2]);
1269 Stack[sidx] = (*
reinterpret_cast<bulkfun_type4>(fPtr))(nOffset, nThreadID, Stack[sidx],
1270 Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]);
1274 Stack[sidx] = (*
reinterpret_cast<bulkfun_type5>(fPtr))(nOffset, nThreadID, Stack[sidx],
1275 Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
1280 Stack[sidx] = (*
reinterpret_cast<bulkfun_type6>(fPtr))(nOffset, nThreadID, Stack[sidx],
1281 Stack[sidx+1], Stack[sidx+2],
1282 Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]);
1286 Stack[sidx] = (*
reinterpret_cast<bulkfun_type7>(fPtr))(nOffset, nThreadID, Stack[sidx],
1287 Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
1288 Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]);
1292 Stack[sidx] = (*
reinterpret_cast<bulkfun_type8>(fPtr))(nOffset, nThreadID, Stack[sidx],
1293 Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
1294 Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]);
1298 Stack[sidx] = (*
reinterpret_cast<bulkfun_type9>(fPtr))(nOffset, nThreadID, Stack[sidx],
1299 Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
1300 Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]);
1304 Stack[sidx] = (*
reinterpret_cast<bulkfun_type10>(fPtr))(nOffset, nThreadID,
1306 Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
1307 Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8],
1341 return Stack[m_nFinalResultIdx];
1345 void QmuParserBase::CreateRPN()
const
1347 if (m_pTokenReader->GetExpr().length() ==
false)
1366 opt = m_pTokenReader->ReadNextToken(m_locale, m_decimalPoint, m_thousandsSeparator);
1375 opt.
SetIdx(m_vStringBuf.size());
1378 m_vStringBuf.push_back(str);
1379 m_Tokens.insert(m_pTokenReader->GetPos()-str.length(), str);
1385 m_vRPN.AddVar(
static_cast<qreal*
>(opt.
GetVar()) );
1387 m_Tokens.insert(m_pTokenReader->GetPos()-str.length(), str);
1393 m_vRPN.AddVal( opt.
GetVal() );
1395 m_Numbers.insert(m_pTokenReader->GetPos()-str.length(), str);
1400 if (m_nIfElseCounter<0)
1404 ApplyRemainingOprt(stOpt, stVal);
1405 m_vRPN.AddIfElse(
cmELSE);
1409 if (stArgCount.empty())
1413 if (stOpt.empty() && allowSubexpressions ==
false)
1421 ApplyRemainingOprt(stOpt, stVal);
1434 ApplyRemainingOprt(stOpt, stVal);
1437 if (stOpt.size() && stOpt.top().GetCode()==
cmBO)
1445 assert(stArgCount.size());
1446 int iArgCount = stArgCount.pop();
1450 if (iArgCount>1 && ( stOpt.size()==0 || (stOpt.top().GetCode()!=
cmFUNC &&
1460 stOpt.top().GetFuncAddr()!=
nullptr)
1462 ApplyFunc(stOpt, stVal, iArgCount);
1493 while ( stOpt.size() && stOpt.top().GetCode() !=
cmBO && stOpt.top().GetCode() !=
cmELSE &&
1494 stOpt.top().GetCode() !=
cmIF)
1497 int nPrec1 = GetOprtPrecedence(topToken),
1498 nPrec2 = GetOprtPrecedence(opt);
1505 if ( (eOprtAsct==
oaRIGHT && (nPrec1 <= nPrec2)) ||
1506 (eOprtAsct==
oaLEFT && (nPrec1 < nPrec2)) )
1511 else if (nPrec1 < nPrec2)
1518 ApplyFunc(stOpt, stVal, 1);
1522 ApplyBinOprt(stOpt, stVal);
1528 m_vRPN.AddIfElse(opt.
GetCode());
1550 ApplyFunc(stOpt, stVal, 1);
1572 if (QmuParserBase::g_DbgDumpStack)
1574 StackDump(stVal, stOpt);
1579 if (QmuParserBase::g_DbgDumpCmdCode)
1584 if (m_nIfElseCounter>0)
1590 Q_ASSERT(stArgCount.size()==1);
1591 m_nFinalResultIdx = stArgCount.top();
1592 if (m_nFinalResultIdx==0)
1597 if (stVal.size()==0)
1602 if (stVal.top().GetType()!=
tpDBL)
1607 m_vStackBuffer.resize(m_vRPN.GetMaxStackSize() * s_MaxNumOpenMPThreads);
1619 qreal QmuParserBase::ParseString()
const
1624 m_pParseFormula = &QmuParserBase::ParseCmdCode;
1625 return (this->*m_pParseFormula)();
1645 void Q_NORETURN QmuParserBase::Error(
EErrorCodes a_iErrc,
int a_iPos,
const QString &a_sTok)
const
1658 void QmuParserBase::ClearVar()
1671 void QmuParserBase::RemoveVar(
const QString &a_strVarName)
1673 varmap_type::iterator item = m_VarDef.find(a_strVarName);
1674 if (item!=m_VarDef.end())
1676 m_VarDef.erase(item);
1688 void QmuParserBase::ClearFun()
1702 void QmuParserBase::ClearConst()
1705 m_StrVarDef.clear();
1715 void QmuParserBase::ClearPostfixOprt()
1717 m_PostOprtDef.clear();
1728 void QmuParserBase::ClearOprt()
1741 void QmuParserBase::ClearInfixOprt()
1743 m_InfixOprtDef.clear();
1753 void QmuParserBase::EnableOptimizer(
bool a_bIsOn)
1755 m_vRPN.EnableOptimizer(a_bIsOn);
1768 void QmuParserBase::EnableDebugDump(
bool bDumpCmd,
bool bDumpStack)
1770 QmuParserBase::g_DbgDumpCmdCode = bDumpCmd;
1771 QmuParserBase::g_DbgDumpStack = bDumpStack;
1784 void QmuParserBase::EnableBuiltInOprt(
bool a_bIsOn)
1786 m_bBuiltInOp = a_bIsOn;
1794 QChar QmuParserBase::GetArgSep()
const
1796 return m_pTokenReader->GetArgSep();
1806 m_pTokenReader->SetArgSep(cArgSep);
1820 qDebug() <<
"\nValue stack:\n";
1821 while ( stVal.empty() ==
false )
1830 qDebug() <<
" " << val.
GetVal() <<
" ";
1833 qDebug() <<
"\nOperator stack:\n";
1835 while ( stOprt.empty() ==
false )
1840 qDebug() <<
"OPRT_INTRNL \"" << QmuParserBase::c_DefaultOprt[topToken.
GetCode()] <<
"\" \n";
1847 qDebug() <<
"VAR\n";
1850 qDebug() <<
"VAL\n";
1853 qDebug() <<
"FUNC \"" << topToken.
GetAsString() <<
"\"\n";
1856 qDebug() <<
"FUNC_BULK \"" << topToken.
GetAsString() <<
"\"\n";
1859 qDebug() <<
"OPRT_INFIX \"" << topToken.
GetAsString() <<
"\"\n";
1862 qDebug() <<
"OPRT_BIN \"" << topToken.
GetAsString() <<
"\"\n";
1865 qDebug() <<
"FUNC_STR\n";
1868 qDebug() <<
"END\n";
1871 qDebug() <<
"UNKNOWN\n";
1874 qDebug() <<
"BRACKET \"(\"\n";
1877 qDebug() <<
"BRACKET \")\"\n";
1883 qDebug() <<
"ELSE\n";
1886 qDebug() <<
"ENDIF\n";
1889 qDebug() << topToken.
GetCode() <<
" ";
1895 qDebug() << Qt::dec;
1906 qreal* QmuParserBase::Eval(
int &nStackSize)
const
1908 (this->*m_pParseFormula)();
1909 nStackSize = m_nFinalResultIdx;
1912 return &m_vStackBuffer[1];
1916 void QmuParserBase::Eval(qreal *results,
int nBulkSize)
const
1922 #ifdef QMUP_USE_OPENMP
1924 #ifdef DEBUG_OMP_STUFF
1925 int *pThread =
new int[nBulkSize];
1926 int *pIdx =
new int[nBulkSize];
1929 int nMaxThreads = qMin(omp_get_max_threads(), s_MaxNumOpenMPThreads);
1932 omp_set_num_threads(nMaxThreads);
1934 #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID)
1935 for (i=0; i<nBulkSize; ++i)
1937 int nThreadID = omp_get_thread_num();
1938 results[i] = ParseCmdCodeBulk(i, nThreadID);
1940 #ifdef DEBUG_OMP_STUFF
1941 #pragma omp critical
1943 pThread[ct] = nThreadID;
1950 #ifdef DEBUG_OMP_STUFF
1951 FILE *pFile = fopen(
"bulk_dbg.txt",
"w");
1952 for (i=0; i<nBulkSize; ++i)
1954 fprintf(pFile,
"idx: %d thread: %d \n", pIdx[i], pThread[i]);
1964 for (i=0; i<nBulkSize; ++i)
1966 results[i] = ParseCmdCodeBulk(i, 0);
Mathematical expressions parser (base parser engine).
void setDecimalPoint(const QChar &c)
void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, const QString &a_szCharSet) const
Check if a name contains invalid characters.
void Assign(const QmuParserBase &a_Parser)
Copy state of a parser object to this.
void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, funmap_type &a_Storage, const QString &a_szCharSet)
Add a function or operator callback to the parser.
void CheckName(const QString &a_sName, const QString &a_szCharSet) const
Check if a name contains invalid characters.
QLocale getLocale() const
void InitTokenReader()
Initialize the token reader.
funmap_type m_OprtDef
Binary operator callbacks.
void SetArgSep(char_type cArgSep)
Set argument separator.
valbuf_type m_vStackBuffer
This is merely a buffer used for the stack in the cmd parsing routine.
QmuParserByteCode m_vRPN
The Bytecode class.
static QString GetVersion(EParserVersionInfo eInfo=pviFULL)
Returns the version of muparser.
stringbuf_type m_vStringVarBuf
void DefineStrConst(const QString &a_strName, const QString &a_strVal)
Define a new string constant.
void DefineOprt(const QString &a_sName, fun_type2 a_pFun, unsigned a_iPrec=0, EOprtAssociativity a_eAssociativity=oaLEFT, bool a_bAllowOpt=false)
Define a binary operator.
void setAllowSubexpressions(bool value)
EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const
Get operator priority.
static const QStringList c_DefaultOprt
Identifiers for built in binary operators.
valmap_type m_ConstDef
user constants.
int GetOprtPrecedence(const token_type &a_Tok) const
Get operator priority.
QmuParserTokenReader token_reader_type
Typedef for the token reader.
strmap_type m_StrVarDef
user defined string constants
funmap_type m_FunDef
Map of function names and pointers.
void Q_NORETURN Error(EErrorCodes a_iErrc, int a_iPos=-1, const QString &a_sTok=QString()) const
Create an error containing the parse error position.
funmap_type m_PostOprtDef
Postfix operator callbacks.
void ReInit() const
Reset parser to string parsing mode and clear internal buffers.
void DefineVar(const QString &a_sName, qreal *a_pVar)
Add a user defined variable.
void ApplyRemainingOprt(QStack< token_type > &a_stOpt, QStack< token_type > &a_stVal) const
Apply a binary operator.
virtual void InitConst()=0
const QString & ValidNameChars() const
Virtual function that defines the characters allowed in name identifiers.
QString m_sInfixOprtChars
Charset for infix operator tokens.
static const int s_MaxNumOpenMPThreads
Maximum number of threads spawned by OpenMP when using the bulk mode.
QChar getDecimalPoint() const
int m_nIfElseCounter
Internal counter for keeping track of nested if-then-else clauses.
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const
Evaluate the RPN.
QLocale m_locale
The locale used by the parser.
QMap< int, QString > m_Numbers
Keep all numbers what exist in formula.
void Init()
Initialize user defined functions.
QChar getThousandsSeparator() const
void ApplyFunc(QStack< token_type > &a_stOpt, QStack< token_type > &a_stVal, int iArgCount) const
Apply a function token.
funmap_type m_InfixOprtDef
unary infix operator.
bool m_bBuiltInOp
Flag that can be used for switching built in operators on and off.
static bool g_DbgDumpStack
void ApplyBinOprt(QStack< token_type > &a_stOpt, QStack< token_type > &a_stVal) const
Performs the necessary steps to write code for the execution of binary operators into the bytecode.
void setThousandsSeparator(const QChar &c)
void DefinePostfixOprt(const QString &a_sFun, fun_type1 a_pFun, bool a_bAllowOpt=true)
Add a user defined operator.
const varmap_type & GetUsedVar() const
Return a map containing the used variables only.
stringbuf_type m_vStringBuf
String buffer, used for storing string function arguments.
token_type ApplyStrFunc(const token_type &a_FunTok, const QVector< token_type > &a_vArg) const
Execute a function that takes a single string argument.
void SetExpr(const QString &a_sExpr)
Set the formula.
QMap< int, QString > m_Tokens
Keep all tokens that we can translate.
void setLocale(const QLocale &value)
void SetVarFactory(facfun_type a_pFactory, void *pUserData=nullptr)
Set a function that can create variable pointer for unknown expression variables.
QChar m_thousandsSeparator
qreal ParseCmdCode() const
Parse the command code.
void ResetLocale()
Resets the locale.
virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd)
const QString & ValidInfixOprtChars() const
Virtual function that defines the characters allowed in infix operator definitions.
virtual void InitCharSets()=0
const QString & ValidOprtChars() const
Virtual function that defines the characters allowed in operator definitions.
QString m_sOprtChars
Charset for postfix/ binary operator tokens.
QmuParserBase()
Constructor.
std::unique_ptr< token_reader_type > m_pTokenReader
Managed pointer to the token reader object.
ParseFunction m_pParseFormula
Pointer to the parser function.
varmap_type m_VarDef
user defind variables.
qreal ParseString() const
One of the two main parse functions.
static bool g_DbgDumpCmdCode
void ApplyIfElse(QStack< token_type > &a_stOpt, QStack< token_type > &a_stVal) const
void DefineConst(const QString &a_sName, qreal a_fVal)
Add a user defined constant.
QmuParserBase & operator=(const QmuParserBase &a_Parser)
Assignement operator.
virtual void InitOprt()=0
void DefineInfixOprt(const QString &a_sName, fun_type1 a_pFun, int a_iPrec=prINFIX, bool a_bAllowOpt=true)
Add a user defined operator.
QString m_sNameChars
Charset for names.
void AddIfElse(ECmdCode a_Oprt)
void AddFun(generic_fun_type a_pFun, int a_iArgc)
Add function to bytecode.
const SToken * GetBase() const
void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx)
Add Strung function entry to the parser bytecode.
void AddOp(ECmdCode a_Oprt)
Add an operator identifier to bytecode.
void clear()
Delete the bytecode.
void AddBulkFun(generic_fun_type a_pFun, int a_iArgc)
Add a bulk function to bytecode.
void AddAssignOp(qreal *a_pVar)
Add an assignement operator.
Encapsulation of prototypes for a numerical parser function.
ECmdCode GetCode() const
Return the callback code.
void * GetAddr() const
Get the callback address for the parser function.
Error class of the parser.
void SetFormula(const QString &a_strFormula)
Set the expression related to this error.
ETypeCode GetType() const
EOprtAssociativity GetAssociativity() const
generic_fun_type GetFuncAddr() const
Return the address of the callback function assoziated with function and operator tokens.
void SetIdx(int a_iIdx)
Set an index associated with the token related data.
ECmdCode GetCode() const
Return the token type.
QmuParserToken & SetVal(TBase a_fVal, const TString &a_strTok=TString())
Make this token a value token.
int GetArgCount() const
Return the number of function arguments.
const TString & GetAsString() const
Return the token identifier.
TBase GetVal() const
Get value of the token.
TBase * GetVar() const
Get address of a variable token.
Namespace for mathematical applications.
qreal(* bulkfun_type10)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
std::map< QString, QmuParserCallback > funmap_type
Container for Callback objects.
string_type::value_type char_type
The character type used by the parser.
qreal(* bulkfun_type4)(int, int, qreal, qreal, qreal, qreal)
Callback type used for functions with four arguments.
qreal(* fun_type7)(qreal, qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
qreal(* fun_type10)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
qreal(* fun_type3)(qreal, qreal, qreal)
Callback type used for functions with three arguments.
qreal(* fun_type8)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
@ ecTOO_FEW_PARAMS
Too few function parameters. (Example: "ite(1<2;2)")
@ ecUNEXPECTED_OPERATOR
Unexpected binary operator found.
@ ecOPRT_TYPE_CONFLICT
binary operators may only be applied to value items of the same type
@ ecINVALID_NAME
Invalid function, variable or constant name.
@ ecLOCALE
Conflict with current locale.
@ ecINVALID_INFIX_IDENT
Invalid function, variable or constant name.
@ ecBUILTIN_OVERLOAD
Trying to overload builtin operator.
@ ecUNEXPECTED_EOF
Unexpected end of formula. (Example: "2+sin(")
@ ecINVALID_FUN_PTR
Invalid callback function pointer.
@ ecSTRING_EXPECTED
A string function has been called with a different type of argument.
@ ecNAME_CONFLICT
Name conflict.
@ ecVAL_EXPECTED
A numerical function has been called with a non value type of argument.
@ ecUNASSIGNABLE_TOKEN
Token cant be identified.
@ ecUNEXPECTED_ARG_SEP
An unexpected semicolon has been found. (Example: "1;23")
@ ecUNEXPECTED_ARG
An unexpected argument has been found.
@ ecSTR_RESULT
result is a string
@ ecEMPTY_EXPRESSION
The Expression is empty.
@ ecINVALID_POSTFIX_IDENT
Invalid function, variable or constant name.
@ ecTOO_MANY_PARAMS
Too many function parameters.
@ ecINTERNAL_ERROR
Internal error of any kind.
@ ecINVALID_VAR_PTR
Invalid variable pointer.
@ ecDIV_BY_ZERO
Division by zero (currently unused)
qreal *(* facfun_type)(const QString &, void *)
Callback used for variable creation factory functions.
qreal(* bulkfun_type5)(int, int, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
@ cmOPRT_INFIX
code for infix operators
@ cmBC
Operator item: closing bracket.
@ cmLE
Operator item: less or equal.
@ cmUNKNOWN
uninitialized item
@ cmSUB
Operator item: subtract.
@ cmGT
Operator item: greater than.
@ cmSTRING
Code for a string token.
@ cmFUNC
Code for a generic function item.
@ cmFUNC_STR
Code for a function with a string parameter.
@ cmLT
Operator item: less than.
@ cmMUL
Operator item: multiply.
@ cmGE
Operator item: greater or equal.
@ cmADD
Operator item: add.
@ cmASSIGN
Operator item: Assignment operator.
@ cmENDIF
For use in the ternary if-then-else operator.
@ cmELSE
For use in the ternary if-then-else operator.
@ cmEQ
Operator item: equals.
@ cmFUNC_BULK
Special callbacks for Bulk mode with an additional parameter for the bulk index.
@ cmARG_SEP
function argument separator
@ cmPOW
Operator item: y to the power of ...
@ cmNEQ
Operator item: not equal.
@ cmOPRT_BIN
user defined binary operator
@ cmIF
For use in the ternary if-then-else operator.
@ cmOPRT_POSTFIX
code for postfix operators
@ cmDIV
Operator item: division.
@ cmBO
Operator item: opening bracket.
qreal(* fun_type6)(qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
qreal(* fun_type4)(qreal, qreal, qreal, qreal)
Callback type used for functions with four arguments.
qreal(* fun_type9)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
qreal(* bulkfun_type1)(int, int, qreal)
Callback type used for functions with a single arguments.
qreal(* fun_type2)(qreal, qreal)
Callback type used for functions with two arguments.
qreal(* bulkfun_type2)(int, int, qreal, qreal)
Callback type used for functions with two arguments.
qreal(* generic_fun_type)()
Callback type used for functions without arguments.
qreal(* bulkfun_type0)(int, int)
Callback type used for functions without arguments.
qreal(* strfun_type3)(const QString &, qreal, qreal)
Callback type used for functions taking a string and two values as arguments.
EOprtAssociativity
Parser operator precedence values.
qreal(* fun_type1)(qreal)
Callback type used for functions with a single arguments.
qreal(* bulkfun_type7)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
qreal(* multfun_type)(const qreal *, int)
Callback type used for functions with a variable argument list.
qreal(* strfun_type2)(const QString &, qreal)
Callback type used for functions taking a string and a value as arguments.
qreal(* fun_type0)()
Callback type used for functions without arguments.
@ prPOW
power operator priority (highest)
@ prPOSTFIX
Postfix operator priority (currently unused)
@ prCMP
comparsion operators
@ prMUL_DIV
multiplication/division
qreal(* bulkfun_type6)(int, int, qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
qreal(* bulkfun_type8)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
qreal(* bulkfun_type3)(int, int, qreal, qreal, qreal)
Callback type used for functions with three arguments.
qreal(* bulkfun_type9)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
@ tpDBL
Floating point variables.
@ tpSTR
String type (Function arguments and constants only, no string variables)
std::map< QString, qreal * > varmap_type
Type used for storing variables.
qreal(* fun_type5)(qreal, qreal, qreal, qreal, qreal)
Callback type used for functions with five arguments.
qreal(* strfun_type1)(const QString &)
Callback type used for functions taking a string as an argument.
QT_WARNING_POP static Q_REQUIRED_RESULT bool QmuFuzzyComparePossibleNulls(double p1, double p2)
This file contains the class definition of the qmuparser engine.
#define QMUP_VERSION_DATE