First success build after all changes.
--HG-- branch : feature
This commit is contained in:
parent
7c1d22c5f4
commit
0b49785255
|
@ -166,11 +166,16 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
|
||||||
\param [out] a_fVal Pointer where the value should be stored in case one is found.
|
\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.
|
\return 1 if a value was found 0 otherwise.
|
||||||
*/
|
*/
|
||||||
int QmuParser::IsVal(const char_type* a_szExpr, int *a_iPos, qreal *a_fVal)
|
int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal)
|
||||||
{
|
{
|
||||||
qreal fVal(0);
|
qreal fVal(0);
|
||||||
|
|
||||||
stringstream_type stream(a_szExpr);
|
#if defined(_UNICODE)
|
||||||
|
std::wstring a_szExprStd = a_szExpr.toStdWString();
|
||||||
|
#else
|
||||||
|
std::string a_szExprStd = a_szExpr.toStdString();
|
||||||
|
#endif
|
||||||
|
stringstream_type stream(a_szExprStd);
|
||||||
stream.seekg(0); // todo: check if this really is necessary
|
stream.seekg(0); // todo: check if this really is necessary
|
||||||
stream.imbue(QmuParser::s_locale);
|
stream.imbue(QmuParser::s_locale);
|
||||||
stream >> fVal;
|
stream >> fVal;
|
||||||
|
|
|
@ -83,7 +83,7 @@ protected:
|
||||||
static qreal Min(const qreal*, int); // minimum
|
static qreal Min(const qreal*, int); // minimum
|
||||||
static qreal Max(const qreal*, int); // maximum
|
static qreal Max(const qreal*, int); // maximum
|
||||||
|
|
||||||
static int IsVal(const char_type* a_szExpr, int *a_iPos, qreal *a_fVal);
|
static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace qmu
|
} // namespace qmu
|
||||||
|
|
|
@ -53,15 +53,9 @@ namespace qmu
|
||||||
When defining custom binary operators with #AddOprt(...) make sure not to choose
|
When defining custom binary operators with #AddOprt(...) make sure not to choose
|
||||||
names conflicting with these definitions.
|
names conflicting with these definitions.
|
||||||
*/
|
*/
|
||||||
const char_type* QmuParserBase::c_DefaultOprt[] =
|
const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" << "!=" << "==" << "<" << ">" << "+"
|
||||||
{
|
<< "-" << "*" << "/" << "^" << "&&" << "||" << "="
|
||||||
"<=", ">=", "!=",
|
<< "(" << ")" << "?" << ":";
|
||||||
"==", "<", ">",
|
|
||||||
"+", "-", "*",
|
|
||||||
"/", "^", "&&",
|
|
||||||
"||", "=", "(",
|
|
||||||
")", "?", ":", 0
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** \brief Constructor.
|
/** \brief Constructor.
|
||||||
|
@ -247,7 +241,7 @@ namespace qmu
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void QmuParserBase::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
|
void QmuParserBase::OnDetectVar(QString * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -329,10 +323,10 @@ namespace qmu
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
/** \brief Add a function or operator callback to the parser. */
|
/** \brief Add a function or operator callback to the parser. */
|
||||||
void QmuParserBase::AddCallback(const string_type &a_strName,
|
void QmuParserBase::AddCallback(const QString &a_strName,
|
||||||
const QmuParserCallback &a_Callback,
|
const QmuParserCallback &a_Callback,
|
||||||
funmap_type &a_Storage,
|
funmap_type &a_Storage,
|
||||||
const char_type *a_szCharSet )
|
const QString &a_szCharSet )
|
||||||
{
|
{
|
||||||
if (a_Callback.GetAddr()==0)
|
if (a_Callback.GetAddr()==0)
|
||||||
Error(ecINVALID_FUN_PTR);
|
Error(ecINVALID_FUN_PTR);
|
||||||
|
@ -362,13 +356,19 @@ namespace qmu
|
||||||
|
|
||||||
\throw ParserException if the name contains invalid charakters.
|
\throw ParserException if the name contains invalid charakters.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::CheckOprt(const string_type &a_sName,
|
void QmuParserBase::CheckOprt(const QString &a_sName,
|
||||||
const QmuParserCallback &a_Callback,
|
const QmuParserCallback &a_Callback,
|
||||||
const string_type &a_szCharSet) const
|
const QString &a_szCharSet) const
|
||||||
{
|
{
|
||||||
if ( !a_sName.length() ||
|
#if defined(_UNICODE)
|
||||||
(a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) ||
|
const std::wstring a_sNameStd = a_sName.toStdWString();
|
||||||
(a_sName[0]>='0' && a_sName[0]<='9'))
|
const std::wstring a_szCharSetStd = a_szCharSet.toStdWString();
|
||||||
|
#else
|
||||||
|
const std::string a_sNameStd = a_sName.toStdString();
|
||||||
|
const std::string a_szCharSetStd = a_szCharSet.toStdString();
|
||||||
|
#endif
|
||||||
|
if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) ||
|
||||||
|
(a_sNameStd.at(0)>='0' && a_sNameStd.at(0)<='9'))
|
||||||
{
|
{
|
||||||
switch(a_Callback.GetCode())
|
switch(a_Callback.GetCode())
|
||||||
{
|
{
|
||||||
|
@ -384,12 +384,17 @@ namespace qmu
|
||||||
|
|
||||||
\throw ParserException if the name contains invalid charakters.
|
\throw ParserException if the name contains invalid charakters.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::CheckName(const string_type &a_sName,
|
void QmuParserBase::CheckName(const QString &a_sName, const QString &a_szCharSet) const
|
||||||
const string_type &a_szCharSet) const
|
|
||||||
{
|
{
|
||||||
if ( !a_sName.length() ||
|
#if defined(_UNICODE)
|
||||||
(a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) ||
|
std::wstring a_sNameStd = a_sName.toStdWString();
|
||||||
(a_sName[0]>='0' && a_sName[0]<='9'))
|
std::wstring a_szCharSetStd = a_szCharSet.toStdWString();
|
||||||
|
#else
|
||||||
|
std::string a_sNameStd = a_sName.toStdString();
|
||||||
|
std::string a_szCharSetStd = a_szCharSet.toStdString();
|
||||||
|
#endif
|
||||||
|
if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) ||
|
||||||
|
(a_sNameStd[0]>='0' && a_sNameStd[0]<='9'))
|
||||||
{
|
{
|
||||||
Error(ecINVALID_NAME);
|
Error(ecINVALID_NAME);
|
||||||
}
|
}
|
||||||
|
@ -403,7 +408,7 @@ namespace qmu
|
||||||
Triggers first time calculation thus the creation of the bytecode and
|
Triggers first time calculation thus the creation of the bytecode and
|
||||||
scanning of used variables.
|
scanning of used variables.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
void QmuParserBase::SetExpr(const QString &a_sExpr)
|
||||||
{
|
{
|
||||||
// Check locale compatibility
|
// Check locale compatibility
|
||||||
std::locale loc;
|
std::locale loc;
|
||||||
|
@ -415,9 +420,9 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
// <ibg> 20060222: Bugfix for Borland-Kylix:
|
// <ibg> 20060222: Bugfix for Borland-Kylix:
|
||||||
// adding a space to the expression will keep Borlands KYLIX from going wild
|
// adding a space to the expression will keep Borlands KYLIX from going wild
|
||||||
// when calling tellg on a stringstream created from the expression after
|
// when calling tellg on a stringstream created from the expression after
|
||||||
// reading a value at the end of an expression. (mu::Parser::IsVal function)
|
// reading a value at the end of an expression. (qmu::QmuParser::IsVal function)
|
||||||
// (tellg returns -1 otherwise causing the parser to ignore the value)
|
// (tellg returns -1 otherwise causing the parser to ignore the value)
|
||||||
string_type sBuf(a_sExpr + " " );
|
QString sBuf(a_sExpr + " " );
|
||||||
m_pTokenReader->SetFormula(sBuf);
|
m_pTokenReader->SetFormula(sBuf);
|
||||||
ReInit();
|
ReInit();
|
||||||
}
|
}
|
||||||
|
@ -426,9 +431,9 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
/** \brief Get the default symbols used for the built in operators.
|
/** \brief Get the default symbols used for the built in operators.
|
||||||
\sa c_DefaultOprt
|
\sa c_DefaultOprt
|
||||||
*/
|
*/
|
||||||
const char_type** QmuParserBase::GetOprtDef() const
|
const QStringList &QmuParserBase::GetOprtDef() const
|
||||||
{
|
{
|
||||||
return (const char_type **)(&c_DefaultOprt[0]);
|
return c_DefaultOprt;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -462,49 +467,37 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
/** \brief Virtual function that defines the characters allowed in name identifiers.
|
/** \brief Virtual function that defines the characters allowed in name identifiers.
|
||||||
\sa #ValidOprtChars, #ValidPrefixOprtChars
|
\sa #ValidOprtChars, #ValidPrefixOprtChars
|
||||||
*/
|
*/
|
||||||
const char_type* QmuParserBase::ValidNameChars() const
|
const QString& QmuParserBase::ValidNameChars() const
|
||||||
{
|
{
|
||||||
assert(m_sNameChars.size());
|
assert(m_sNameChars.size());
|
||||||
#if defined(_UNICODE)
|
return m_sNameChars;
|
||||||
return m_sNameChars.toStdWString().c_str();
|
|
||||||
#else
|
|
||||||
return m_sNameChars.toStdString().c_str();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
/** \brief Virtual function that defines the characters allowed in operator definitions.
|
/** \brief Virtual function that defines the characters allowed in operator definitions.
|
||||||
\sa #ValidNameChars, #ValidPrefixOprtChars
|
\sa #ValidNameChars, #ValidPrefixOprtChars
|
||||||
*/
|
*/
|
||||||
const char_type* QmuParserBase::ValidOprtChars() const
|
const QString &QmuParserBase::ValidOprtChars() const
|
||||||
{
|
{
|
||||||
assert(m_sOprtChars.size());
|
assert(m_sOprtChars.size());
|
||||||
#if defined(_UNICODE)
|
return m_sOprtChars;
|
||||||
return m_sOprtChars.toStdWString().c_str();
|
|
||||||
#else
|
|
||||||
return m_sOprtChars.toStdString().c_str();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
/** \brief Virtual function that defines the characters allowed in infix operator definitions.
|
/** \brief Virtual function that defines the characters allowed in infix operator definitions.
|
||||||
\sa #ValidNameChars, #ValidOprtChars
|
\sa #ValidNameChars, #ValidOprtChars
|
||||||
*/
|
*/
|
||||||
const char_type* QmuParserBase::ValidInfixOprtChars() const
|
const QString &QmuParserBase::ValidInfixOprtChars() const
|
||||||
{
|
{
|
||||||
assert(m_sInfixOprtChars.size());
|
assert(m_sInfixOprtChars.size());
|
||||||
#if defined(_UNICODE)
|
return m_sInfixOprtChars;
|
||||||
return m_sInfixOprtChars.toStdWString().c_str();
|
|
||||||
#else
|
|
||||||
return m_sInfixOprtChars.toStdString().c_str();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
/** \brief Add a user defined operator.
|
/** \brief Add a user defined operator.
|
||||||
\post Will reset the Parser to string parsing mode.
|
\post Will reset the Parser to string parsing mode.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::DefinePostfixOprt(const string_type &a_sName,
|
void QmuParserBase::DefinePostfixOprt(const QString &a_sName,
|
||||||
fun_type1 a_pFun,
|
fun_type1 a_pFun,
|
||||||
bool a_bAllowOpt)
|
bool a_bAllowOpt)
|
||||||
{
|
{
|
||||||
|
@ -536,7 +529,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
\param [in] a_bAllowOpt True if operator is volatile (default=false)
|
\param [in] a_bAllowOpt True if operator is volatile (default=false)
|
||||||
\sa EPrec
|
\sa EPrec
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::DefineInfixOprt(const string_type &a_sName,
|
void QmuParserBase::DefineInfixOprt(const QString &a_sName,
|
||||||
fun_type1 a_pFun,
|
fun_type1 a_pFun,
|
||||||
int a_iPrec,
|
int a_iPrec,
|
||||||
bool a_bAllowOpt)
|
bool a_bAllowOpt)
|
||||||
|
@ -558,7 +551,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
|
|
||||||
Adds a new Binary operator the the parser instance.
|
Adds a new Binary operator the the parser instance.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::DefineOprt( const string_type &a_sName,
|
void QmuParserBase::DefineOprt( const QString &a_sName,
|
||||||
fun_type2 a_pFun,
|
fun_type2 a_pFun,
|
||||||
unsigned a_iPrec,
|
unsigned a_iPrec,
|
||||||
EOprtAssociativity a_eAssociativity,
|
EOprtAssociativity a_eAssociativity,
|
||||||
|
@ -566,8 +559,12 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
{
|
{
|
||||||
// Check for conflicts with built in operator names
|
// Check for conflicts with built in operator names
|
||||||
for (int i=0; m_bBuiltInOp && i<cmENDIF; ++i)
|
for (int i=0; m_bBuiltInOp && i<cmENDIF; ++i)
|
||||||
if (a_sName == string_type(c_DefaultOprt[i]))
|
{
|
||||||
|
if (a_sName == c_DefaultOprt.at(i))
|
||||||
|
{
|
||||||
Error(ecBUILTIN_OVERLOAD, -1, a_sName);
|
Error(ecBUILTIN_OVERLOAD, -1, a_sName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AddCallback(a_sName,
|
AddCallback(a_sName,
|
||||||
QmuParserCallback(a_pFun, a_bAllowOpt, a_iPrec, a_eAssociativity),
|
QmuParserCallback(a_pFun, a_bAllowOpt, a_iPrec, a_eAssociativity),
|
||||||
|
@ -580,11 +577,13 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
\param [in] a_strName The name of the constant.
|
\param [in] a_strName The name of the constant.
|
||||||
\param [in] a_strVal the value of the constant.
|
\param [in] a_strVal the value of the constant.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::DefineStrConst(const string_type &a_strName, const string_type &a_strVal)
|
void QmuParserBase::DefineStrConst(const QString &a_strName, const QString &a_strVal)
|
||||||
{
|
{
|
||||||
// Test if a constant with that names already exists
|
// Test if a constant with that names already exists
|
||||||
if (m_StrVarDef.find(a_strName)!=m_StrVarDef.end())
|
if (m_StrVarDef.find(a_strName)!=m_StrVarDef.end())
|
||||||
|
{
|
||||||
Error(ecNAME_CONFLICT);
|
Error(ecNAME_CONFLICT);
|
||||||
|
}
|
||||||
|
|
||||||
CheckName(a_strName, ValidNameChars());
|
CheckName(a_strName, ValidNameChars());
|
||||||
|
|
||||||
|
@ -601,14 +600,18 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
\post Will reset the Parser to string parsing mode.
|
\post Will reset the Parser to string parsing mode.
|
||||||
\throw ParserException in case the name contains invalid signs or a_pVar is NULL.
|
\throw ParserException in case the name contains invalid signs or a_pVar is NULL.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::DefineVar(const string_type &a_sName, qreal *a_pVar)
|
void QmuParserBase::DefineVar(const QString &a_sName, qreal *a_pVar)
|
||||||
{
|
{
|
||||||
if (a_pVar==0)
|
if (a_pVar==0)
|
||||||
|
{
|
||||||
Error(ecINVALID_VAR_PTR);
|
Error(ecINVALID_VAR_PTR);
|
||||||
|
}
|
||||||
|
|
||||||
// Test if a constant with that names already exists
|
// Test if a constant with that names already exists
|
||||||
if (m_ConstDef.find(a_sName)!=m_ConstDef.end())
|
if (m_ConstDef.find(a_sName)!=m_ConstDef.end())
|
||||||
|
{
|
||||||
Error(ecNAME_CONFLICT);
|
Error(ecNAME_CONFLICT);
|
||||||
|
}
|
||||||
|
|
||||||
CheckName(a_sName, ValidNameChars());
|
CheckName(a_sName, ValidNameChars());
|
||||||
m_VarDef[a_sName] = a_pVar;
|
m_VarDef[a_sName] = a_pVar;
|
||||||
|
@ -622,7 +625,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
\post Will reset the Parser to string parsing mode.
|
\post Will reset the Parser to string parsing mode.
|
||||||
\throw ParserException in case the name contains invalid signs.
|
\throw ParserException in case the name contains invalid signs.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::DefineConst(const string_type &a_sName, qreal a_fVal)
|
void QmuParserBase::DefineConst(const QString &a_sName, qreal a_fVal)
|
||||||
{
|
{
|
||||||
CheckName(a_sName, ValidNameChars());
|
CheckName(a_sName, ValidNameChars());
|
||||||
m_ConstDef[a_sName] = a_fVal;
|
m_ConstDef[a_sName] = a_fVal;
|
||||||
|
@ -748,7 +751,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
/** \brief Retrieve the formula. */
|
/** \brief Retrieve the formula. */
|
||||||
const string_type& QmuParserBase::GetExpr() const
|
const QString& QmuParserBase::GetExpr() const
|
||||||
{
|
{
|
||||||
return m_pTokenReader->GetExpr();
|
return m_pTokenReader->GetExpr();
|
||||||
}
|
}
|
||||||
|
@ -1129,9 +1132,9 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
|
|
||||||
switch(pTok->Fun.argc) // switch according to argument count
|
switch(pTok->Fun.argc) // switch according to argument count
|
||||||
{
|
{
|
||||||
case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str()); continue;
|
case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack)); continue;
|
||||||
case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx]); continue;
|
case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx]); continue;
|
||||||
case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx+1]); continue;
|
case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx], Stack[sidx+1]); continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -1448,7 +1451,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
\param a_strTok [in] The token string representation associated with the error.
|
\param a_strTok [in] The token string representation associated with the error.
|
||||||
\throw ParserException always throws thats the only purpose of this function.
|
\throw ParserException always throws thats the only purpose of this function.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const string_type &a_sTok) const
|
void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const
|
||||||
{
|
{
|
||||||
throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos);
|
throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos);
|
||||||
}
|
}
|
||||||
|
@ -1471,7 +1474,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
|
|
||||||
Removes a variable if it exists. If the Variable does not exist nothing will be done.
|
Removes a variable if it exists. If the Variable does not exist nothing will be done.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::RemoveVar(const string_type &a_strVarName)
|
void QmuParserBase::RemoveVar(const QString &a_strVarName)
|
||||||
{
|
{
|
||||||
varmap_type::iterator item = m_VarDef.find(a_strVarName);
|
varmap_type::iterator item = m_VarDef.find(a_strVarName);
|
||||||
if (item!=m_VarDef.end())
|
if (item!=m_VarDef.end())
|
||||||
|
@ -1592,7 +1595,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** \brief Get the argument separator character.
|
/** \brief Get the argument separator character.
|
||||||
*/
|
*/
|
||||||
char_type QmuParserBase::GetArgSep() const
|
QChar QmuParserBase::GetArgSep() const
|
||||||
{
|
{
|
||||||
return m_pTokenReader->GetArgSep();
|
return m_pTokenReader->GetArgSep();
|
||||||
}
|
}
|
||||||
|
@ -1617,22 +1620,22 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
QStack<token_type> stOprt(a_stOprt),
|
QStack<token_type> stOprt(a_stOprt),
|
||||||
stVal(a_stVal);
|
stVal(a_stVal);
|
||||||
|
|
||||||
qmu::console() << "\nValue stack:\n";
|
qDebug() << "\nValue stack:\n";
|
||||||
while ( !stVal.empty() )
|
while ( !stVal.empty() )
|
||||||
{
|
{
|
||||||
token_type val = stVal.pop();
|
token_type val = stVal.pop();
|
||||||
if (val.GetType()==tpSTR)
|
if (val.GetType()==tpSTR)
|
||||||
qmu::console() << " \"" << val.GetAsString() << "\" ";
|
qDebug() << " \"" << val.GetAsString() << "\" ";
|
||||||
else
|
else
|
||||||
qmu::console() << " " << val.GetVal() << " ";
|
qDebug() << " " << val.GetVal() << " ";
|
||||||
}
|
}
|
||||||
qmu::console() << "\nOperator stack:\n";
|
qDebug() << "\nOperator stack:\n";
|
||||||
|
|
||||||
while ( !stOprt.empty() )
|
while ( !stOprt.empty() )
|
||||||
{
|
{
|
||||||
if (stOprt.top().GetCode()<=cmASSIGN)
|
if (stOprt.top().GetCode()<=cmASSIGN)
|
||||||
{
|
{
|
||||||
qmu::console() << "OPRT_INTRNL \""
|
qDebug() << "OPRT_INTRNL \""
|
||||||
<< QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()]
|
<< QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()]
|
||||||
<< "\" \n";
|
<< "\" \n";
|
||||||
}
|
}
|
||||||
|
@ -1640,35 +1643,35 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
|
||||||
{
|
{
|
||||||
switch(stOprt.top().GetCode())
|
switch(stOprt.top().GetCode())
|
||||||
{
|
{
|
||||||
case cmVAR: qmu::console() << "VAR\n"; break;
|
case cmVAR: qDebug() << "VAR\n"; break;
|
||||||
case cmVAL: qmu::console() << "VAL\n"; break;
|
case cmVAL: qDebug() << "VAL\n"; break;
|
||||||
case cmFUNC: qmu::console() << "FUNC \""
|
case cmFUNC: qDebug() << "FUNC \""
|
||||||
<< stOprt.top().GetAsString()
|
<< stOprt.top().GetAsString()
|
||||||
<< "\"\n"; break;
|
<< "\"\n"; break;
|
||||||
case cmFUNC_BULK: qmu::console() << "FUNC_BULK \""
|
case cmFUNC_BULK: qDebug() << "FUNC_BULK \""
|
||||||
<< stOprt.top().GetAsString()
|
<< stOprt.top().GetAsString()
|
||||||
<< "\"\n"; break;
|
<< "\"\n"; break;
|
||||||
case cmOPRT_INFIX: qmu::console() << "OPRT_INFIX \""
|
case cmOPRT_INFIX: qDebug() << "OPRT_INFIX \""
|
||||||
<< stOprt.top().GetAsString()
|
<< stOprt.top().GetAsString()
|
||||||
<< "\"\n"; break;
|
<< "\"\n"; break;
|
||||||
case cmOPRT_BIN: qmu::console() << "OPRT_BIN \""
|
case cmOPRT_BIN: qDebug() << "OPRT_BIN \""
|
||||||
<< stOprt.top().GetAsString()
|
<< stOprt.top().GetAsString()
|
||||||
<< "\"\n"; break;
|
<< "\"\n"; break;
|
||||||
case cmFUNC_STR: qmu::console() << "FUNC_STR\n"; break;
|
case cmFUNC_STR: qDebug() << "FUNC_STR\n"; break;
|
||||||
case cmEND: qmu::console() << "END\n"; break;
|
case cmEND: qDebug() << "END\n"; break;
|
||||||
case cmUNKNOWN: qmu::console() << "UNKNOWN\n"; break;
|
case cmUNKNOWN: qDebug() << "UNKNOWN\n"; break;
|
||||||
case cmBO: qmu::console() << "BRACKET \"(\"\n"; break;
|
case cmBO: qDebug() << "BRACKET \"(\"\n"; break;
|
||||||
case cmBC: qmu::console() << "BRACKET \")\"\n"; break;
|
case cmBC: qDebug() << "BRACKET \")\"\n"; break;
|
||||||
case cmIF: qmu::console() << "IF\n"; break;
|
case cmIF: qDebug() << "IF\n"; break;
|
||||||
case cmELSE: qmu::console() << "ELSE\n"; break;
|
case cmELSE: qDebug() << "ELSE\n"; break;
|
||||||
case cmENDIF: qmu::console() << "ENDIF\n"; break;
|
case cmENDIF: qDebug() << "ENDIF\n"; break;
|
||||||
default: qmu::console() << stOprt.top().GetCode() << " "; break;
|
default: qDebug() << stOprt.top().GetCode() << " "; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stOprt.pop();
|
stOprt.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
qmu::console() << dec << endl;
|
qDebug() << dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <QStack>
|
#include <QStack>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
//--- Parser includes --------------------------------------------------------------------------
|
//--- Parser includes --------------------------------------------------------------------------
|
||||||
#include "qmuparserdef.h"
|
#include "qmuparserdef.h"
|
||||||
|
@ -75,13 +76,13 @@ private:
|
||||||
typedef QVector<qreal> valbuf_type;
|
typedef QVector<qreal> valbuf_type;
|
||||||
|
|
||||||
/** \brief Type for a vector of strings. */
|
/** \brief Type for a vector of strings. */
|
||||||
typedef QVector<string_type> stringbuf_type;
|
typedef QVector<QString> stringbuf_type;
|
||||||
|
|
||||||
/** \brief Typedef for the token reader. */
|
/** \brief Typedef for the token reader. */
|
||||||
typedef QmuParserTokenReader token_reader_type;
|
typedef QmuParserTokenReader token_reader_type;
|
||||||
|
|
||||||
/** \brief Type used for parser tokens. */
|
/** \brief Type used for parser tokens. */
|
||||||
typedef QmuParserToken<qreal, string_type> token_type;
|
typedef QmuParserToken<qreal, QString> token_type;
|
||||||
|
|
||||||
/** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */
|
/** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */
|
||||||
static const int s_MaxNumOpenMPThreads = 4;
|
static const int s_MaxNumOpenMPThreads = 4;
|
||||||
|
@ -108,7 +109,7 @@ private:
|
||||||
|
|
||||||
int GetNumResults() const;
|
int GetNumResults() const;
|
||||||
|
|
||||||
void SetExpr(const string_type &a_sExpr);
|
void SetExpr(const QString &a_sExpr);
|
||||||
void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
|
void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
|
||||||
|
|
||||||
void SetDecSep(char_type cDecSep);
|
void SetDecSep(char_type cDecSep);
|
||||||
|
@ -128,21 +129,21 @@ private:
|
||||||
\param a_bAllowOpt A flag indicating this function may be optimized
|
\param a_bAllowOpt A flag indicating this function may be optimized
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt = true)
|
void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true)
|
||||||
{
|
{
|
||||||
AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
|
AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefineOprt(const string_type &a_strName,
|
void DefineOprt(const QString &a_strName,
|
||||||
fun_type2 a_pFun,
|
fun_type2 a_pFun,
|
||||||
unsigned a_iPri=0,
|
unsigned a_iPri=0,
|
||||||
EOprtAssociativity a_eAssociativity = oaLEFT,
|
EOprtAssociativity a_eAssociativity = oaLEFT,
|
||||||
bool a_bAllowOpt = false);
|
bool a_bAllowOpt = false);
|
||||||
void DefineConst(const string_type &a_sName, qreal a_fVal);
|
void DefineConst(const QString &a_sName, qreal a_fVal);
|
||||||
void DefineStrConst(const string_type &a_sName, const string_type &a_strVal);
|
void DefineStrConst(const QString &a_sName, const QString &a_strVal);
|
||||||
void DefineVar(const string_type &a_sName, qreal *a_fVar);
|
void DefineVar(const QString &a_sName, qreal *a_fVar);
|
||||||
void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
|
void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
|
||||||
void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true);
|
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
|
// Clear user defined variables, constants or functions
|
||||||
void ClearVar();
|
void ClearVar();
|
||||||
|
@ -152,29 +153,29 @@ private:
|
||||||
void ClearPostfixOprt();
|
void ClearPostfixOprt();
|
||||||
void ClearOprt();
|
void ClearOprt();
|
||||||
|
|
||||||
void RemoveVar(const string_type &a_strVarName);
|
void RemoveVar(const QString &a_strVarName);
|
||||||
const varmap_type& GetUsedVar() const;
|
const varmap_type& GetUsedVar() const;
|
||||||
const varmap_type& GetVar() const;
|
const varmap_type& GetVar() const;
|
||||||
const valmap_type& GetConst() const;
|
const valmap_type& GetConst() const;
|
||||||
const string_type& GetExpr() const;
|
const QString &GetExpr() const;
|
||||||
const funmap_type& GetFunDef() const;
|
const funmap_type& GetFunDef() const;
|
||||||
string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const;
|
string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const;
|
||||||
|
|
||||||
const char_type ** GetOprtDef() const;
|
const QStringList &GetOprtDef() const;
|
||||||
void DefineNameChars(const QString &a_szCharset);
|
void DefineNameChars(const QString &a_szCharset);
|
||||||
void DefineOprtChars(const QString &a_szCharset);
|
void DefineOprtChars(const QString &a_szCharset);
|
||||||
void DefineInfixOprtChars(const QString &a_szCharset);
|
void DefineInfixOprtChars(const QString &a_szCharset);
|
||||||
|
|
||||||
const char_type* ValidNameChars() const;
|
const QString& ValidNameChars() const;
|
||||||
const char_type* ValidOprtChars() const;
|
const QString &ValidOprtChars() const;
|
||||||
const char_type* ValidInfixOprtChars() const;
|
const QString &ValidInfixOprtChars() const;
|
||||||
|
|
||||||
void SetArgSep(char_type cArgSep);
|
void SetArgSep(char_type cArgSep);
|
||||||
char_type GetArgSep() const;
|
QChar GetArgSep() const;
|
||||||
|
|
||||||
void Error(EErrorCodes a_iErrc,
|
void Error(EErrorCodes a_iErrc,
|
||||||
int a_iPos = (int)qmu::string_type::npos,
|
int a_iPos = -1,
|
||||||
const string_type &a_strTok = string_type() ) const;
|
const QString &a_strTok = QString() ) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -185,9 +186,9 @@ private:
|
||||||
virtual void InitConst() = 0;
|
virtual void InitConst() = 0;
|
||||||
virtual void InitOprt() = 0;
|
virtual void InitOprt() = 0;
|
||||||
|
|
||||||
virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);
|
virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd);
|
||||||
|
|
||||||
static const char_type *c_DefaultOprt[];
|
static const QStringList c_DefaultOprt;
|
||||||
static std::locale s_locale; ///< The locale used by the parser
|
static std::locale s_locale; ///< The locale used by the parser
|
||||||
static bool g_DbgDumpCmdCode;
|
static bool g_DbgDumpCmdCode;
|
||||||
static bool g_DbgDumpStack;
|
static bool g_DbgDumpStack;
|
||||||
|
@ -235,10 +236,10 @@ private:
|
||||||
void InitTokenReader();
|
void InitTokenReader();
|
||||||
void ReInit() const;
|
void ReInit() const;
|
||||||
|
|
||||||
void AddCallback( const string_type &a_strName,
|
void AddCallback(const QString &a_strName,
|
||||||
const QmuParserCallback &a_Callback,
|
const QmuParserCallback &a_Callback,
|
||||||
funmap_type &a_Storage,
|
funmap_type &a_Storage,
|
||||||
const char_type *a_szCharSet );
|
const QString &a_szCharSet );
|
||||||
|
|
||||||
void ApplyRemainingOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) 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 ApplyBinOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||||
|
@ -257,10 +258,10 @@ private:
|
||||||
qreal ParseCmdCode() const;
|
qreal ParseCmdCode() const;
|
||||||
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
|
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
|
||||||
|
|
||||||
void CheckName(const string_type &a_strName, const string_type &a_CharSet) const;
|
void CheckName(const QString &a_strName, const QString &a_CharSet) const;
|
||||||
void CheckOprt(const string_type &a_sName,
|
void CheckOprt(const QString &a_sName,
|
||||||
const QmuParserCallback &a_Callback,
|
const QmuParserCallback &a_Callback,
|
||||||
const string_type &a_szCharSet) const;
|
const QString &a_szCharSet) const;
|
||||||
|
|
||||||
void StackDump(const QStack<token_type > &a_stVal,
|
void StackDump(const QStack<token_type > &a_stVal,
|
||||||
const QStack<token_type > &a_stOprt) const;
|
const QStack<token_type > &a_stOprt) const;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
#include "qmuparserdef.h"
|
#include "qmuparserdef.h"
|
||||||
#include "qmuparsererror.h"
|
#include "qmuparsererror.h"
|
||||||
|
@ -492,89 +493,76 @@ namespace qmu
|
||||||
{
|
{
|
||||||
if (!m_vRPN.size())
|
if (!m_vRPN.size())
|
||||||
{
|
{
|
||||||
qmu::console() << "No bytecode available\n";
|
qDebug() << "No bytecode available\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qmu::console() << "Number of RPN tokens:" << (int)m_vRPN.size() << "\n";
|
qDebug() << "Number of RPN tokens:" << m_vRPN.size() << "\n";
|
||||||
for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i)
|
for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i)
|
||||||
{
|
{
|
||||||
qmu::console() << std::dec << i << " : \t";
|
qDebug() << i << " : \t";
|
||||||
switch (m_vRPN[i].Cmd)
|
switch (m_vRPN[i].Cmd)
|
||||||
{
|
{
|
||||||
case cmVAL: qmu::console() << "VAL \t";
|
case cmVAL: qDebug() << "VAL \t" << "[" << m_vRPN[i].Val.data2 << "]\n";
|
||||||
qmu::console() << "[" << m_vRPN[i].Val.data2 << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmVAR: qmu::console() << "VAR \t";
|
case cmVAR: qDebug() << "VAR \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||||
qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmVARPOW2: qmu::console() << "VARPOW2 \t";
|
case cmVARPOW2: qDebug() << "VARPOW2 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||||
qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmVARPOW3: qmu::console() << "VARPOW3 \t";
|
case cmVARPOW3: qDebug() << "VARPOW3 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||||
qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmVARPOW4: qmu::console() << "VARPOW4 \t";
|
case cmVARPOW4: qDebug() << "VARPOW4 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
|
||||||
qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmVARMUL: qmu::console() << "VARMUL \t";
|
case cmVARMUL: qDebug() << "VARMUL \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]"
|
||||||
qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]";
|
<< " * [" << m_vRPN[i].Val.data << "]" << " + [" << m_vRPN[i].Val.data2 << "]\n";
|
||||||
qmu::console() << " * [" << m_vRPN[i].Val.data << "]";
|
|
||||||
qmu::console() << " + [" << m_vRPN[i].Val.data2 << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmFUNC: qmu::console() << "CALL\t";
|
case cmFUNC: qDebug() << "CALL\t" << "[ARG:" << m_vRPN[i].Fun.argc << "]" << "[ADDR: 0x"
|
||||||
qmu::console() << "[ARG:" << std::dec << m_vRPN[i].Fun.argc << "]";
|
<< m_vRPN[i].Fun.ptr << "]" << "\n";
|
||||||
qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Fun.ptr << "]";
|
|
||||||
qmu::console() << "\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmFUNC_STR:
|
case cmFUNC_STR:
|
||||||
qmu::console() << "CALL STRFUNC\t";
|
qDebug() << "CALL STRFUNC\t" << "[ARG:" << m_vRPN[i].Fun.argc << "]" << "[IDX:"
|
||||||
qmu::console() << "[ARG:" << std::dec << m_vRPN[i].Fun.argc << "]";
|
<< m_vRPN[i].Fun.idx << "]" << "[ADDR: 0x" << m_vRPN[i].Fun.ptr
|
||||||
qmu::console() << "[IDX:" << std::dec << m_vRPN[i].Fun.idx << "]";
|
<< "]\n";
|
||||||
qmu::console() << "[ADDR: 0x" << m_vRPN[i].Fun.ptr << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmLT: qmu::console() << "LT\n"; break;
|
case cmLT: qDebug() << "LT\n"; break;
|
||||||
case cmGT: qmu::console() << "GT\n"; break;
|
case cmGT: qDebug() << "GT\n"; break;
|
||||||
case cmLE: qmu::console() << "LE\n"; break;
|
case cmLE: qDebug() << "LE\n"; break;
|
||||||
case cmGE: qmu::console() << "GE\n"; break;
|
case cmGE: qDebug() << "GE\n"; break;
|
||||||
case cmEQ: qmu::console() << "EQ\n"; break;
|
case cmEQ: qDebug() << "EQ\n"; break;
|
||||||
case cmNEQ: qmu::console() << "NEQ\n"; break;
|
case cmNEQ: qDebug() << "NEQ\n"; break;
|
||||||
case cmADD: qmu::console() << "ADD\n"; break;
|
case cmADD: qDebug() << "ADD\n"; break;
|
||||||
case cmLAND: qmu::console() << "&&\n"; break;
|
case cmLAND: qDebug() << "&&\n"; break;
|
||||||
case cmLOR: qmu::console() << "||\n"; break;
|
case cmLOR: qDebug() << "||\n"; break;
|
||||||
case cmSUB: qmu::console() << "SUB\n"; break;
|
case cmSUB: qDebug() << "SUB\n"; break;
|
||||||
case cmMUL: qmu::console() << "MUL\n"; break;
|
case cmMUL: qDebug() << "MUL\n"; break;
|
||||||
case cmDIV: qmu::console() << "DIV\n"; break;
|
case cmDIV: qDebug() << "DIV\n"; break;
|
||||||
case cmPOW: qmu::console() << "POW\n"; break;
|
case cmPOW: qDebug() << "POW\n"; break;
|
||||||
|
|
||||||
case cmIF: qmu::console() << "IF\t";
|
case cmIF: qDebug() << "IF\t" << "[OFFSET:" << m_vRPN[i].Oprt.offset << "]\n";
|
||||||
qmu::console() << "[OFFSET:" << std::dec << m_vRPN[i].Oprt.offset << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmELSE: qmu::console() << "ELSE\t";
|
case cmELSE: qDebug() << "ELSE\t" << "[OFFSET:" << m_vRPN[i].Oprt.offset << "]\n";
|
||||||
qmu::console() << "[OFFSET:" << std::dec << m_vRPN[i].Oprt.offset << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmENDIF: qmu::console() << "ENDIF\n"; break;
|
case cmENDIF: qDebug() << "ENDIF\n"; break;
|
||||||
|
|
||||||
case cmASSIGN:
|
case cmASSIGN:
|
||||||
qmu::console() << "ASSIGN\t";
|
qDebug() << "ASSIGN\t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Oprt.ptr, 'f', 16) << "]\n";
|
||||||
qmu::console() << "[ADDR: 0x" << m_vRPN[i].Oprt.ptr << "]\n";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: qmu::console() << "(unknown code: " << m_vRPN[i].Cmd << ")\n";
|
default: qDebug() << "(unknown code: " << m_vRPN[i].Cmd << ")\n";
|
||||||
break;
|
break;
|
||||||
} // switch cmdCode
|
} // switch cmdCode
|
||||||
} // while bytecode
|
} // while bytecode
|
||||||
|
|
||||||
qmu::console() << "END" << std::endl;
|
qDebug() << "END";
|
||||||
}
|
}
|
||||||
} // namespace qmu
|
} // namespace qmu
|
||||||
|
|
|
@ -107,7 +107,7 @@ private:
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** \brief Container for Callback objects. */
|
/** \brief Container for Callback objects. */
|
||||||
typedef std::map<string_type, QmuParserCallback> funmap_type;
|
typedef std::map<QString, QmuParserCallback> funmap_type;
|
||||||
|
|
||||||
} // namespace qmu
|
} // namespace qmu
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
#include "qmuparserfixes.h"
|
#include "qmuparserfixes.h"
|
||||||
|
|
||||||
|
@ -50,53 +52,14 @@
|
||||||
|
|
||||||
#if defined(_UNICODE)
|
#if defined(_UNICODE)
|
||||||
/** \brief Definition of the basic parser string type. */
|
/** \brief Definition of the basic parser string type. */
|
||||||
#define MUP_STRING_TYPE std::wstring
|
#define QMUP_STRING_TYPE std::wstring
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/** \brief Definition of the basic parser string type. */
|
/** \brief Definition of the basic parser string type. */
|
||||||
#define MUP_STRING_TYPE std::string
|
#define QMUP_STRING_TYPE std::string
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace qmu
|
namespace qmu
|
||||||
{
|
{
|
||||||
#if defined(_UNICODE)
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** \brief Encapsulate wcout. */
|
|
||||||
inline std::wostream& console()
|
|
||||||
{
|
|
||||||
return std::wcout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Encapsulate cin. */
|
|
||||||
inline std::wistream& console_in()
|
|
||||||
{
|
|
||||||
return std::wcin;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/** \brief Encapsulate cout.
|
|
||||||
|
|
||||||
Used for supporting UNICODE more easily.
|
|
||||||
*/
|
|
||||||
inline std::ostream& console()
|
|
||||||
{
|
|
||||||
return std::cout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Encapsulate cin.
|
|
||||||
|
|
||||||
Used for supporting UNICODE more easily.
|
|
||||||
*/
|
|
||||||
inline std::istream& console_in()
|
|
||||||
{
|
|
||||||
return std::cin;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** \brief Bytecode values.
|
/** \brief Bytecode values.
|
||||||
|
|
||||||
|
@ -200,7 +163,7 @@ namespace qmu
|
||||||
|
|
||||||
Depends on wether UNICODE is used or not.
|
Depends on wether UNICODE is used or not.
|
||||||
*/
|
*/
|
||||||
typedef MUP_STRING_TYPE string_type;
|
typedef QMUP_STRING_TYPE string_type;
|
||||||
|
|
||||||
/** \brief The character type used by the parser.
|
/** \brief The character type used by the parser.
|
||||||
|
|
||||||
|
@ -216,13 +179,13 @@ namespace qmu
|
||||||
// Data container types
|
// Data container types
|
||||||
|
|
||||||
/** \brief Type used for storing variables. */
|
/** \brief Type used for storing variables. */
|
||||||
typedef std::map<string_type, qreal*> varmap_type;
|
typedef std::map<QString, qreal*> varmap_type;
|
||||||
|
|
||||||
/** \brief Type used for storing constants. */
|
/** \brief Type used for storing constants. */
|
||||||
typedef std::map<string_type, qreal> valmap_type;
|
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<string_type, std::size_t> strmap_type;
|
typedef std::map<QString, int> strmap_type;
|
||||||
|
|
||||||
// Parser callbacks
|
// Parser callbacks
|
||||||
|
|
||||||
|
@ -299,19 +262,19 @@ namespace qmu
|
||||||
typedef qreal (*multfun_type)(const qreal*, int);
|
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 char_type*);
|
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 char_type*, qreal);
|
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 char_type*, qreal, qreal);
|
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 char_type *sExpr, int *nPos, qreal *fVal);
|
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 char_type*, void*);
|
typedef qreal* (*facfun_type)(const QString &, void*);
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include "qmuparsererror.h"
|
#include "qmuparsererror.h"
|
||||||
|
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
|
|
||||||
namespace qmu
|
namespace qmu
|
||||||
{
|
{
|
||||||
|
@ -34,9 +36,9 @@ namespace qmu
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
string_type QmuParserErrorMsg::operator[](unsigned a_iIdx) const
|
QString QmuParserErrorMsg::operator[](unsigned a_iIdx) const
|
||||||
{
|
{
|
||||||
return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : string_type();
|
return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -137,15 +139,13 @@ namespace qmu
|
||||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||||
{
|
{
|
||||||
m_strMsg = m_ErrMsg[m_iErrc];
|
m_strMsg = m_ErrMsg[m_iErrc];
|
||||||
stringstream_type stream;
|
ReplaceSubString(m_strMsg, "$POS$", QString().setNum(m_iPos));
|
||||||
stream << (int)m_iPos;
|
|
||||||
ReplaceSubString(m_strMsg, "$POS$", stream.str());
|
|
||||||
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
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 string_type &sMsg)
|
QmuParserError::QmuParserError(const QString &sMsg)
|
||||||
:m_ErrMsg(QmuParserErrorMsg::Instance())
|
:m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
|
@ -160,8 +160,8 @@ namespace qmu
|
||||||
\param [in] a_iPos the position in the expression where the error occured.
|
\param [in] a_iPos the position in the expression where the error occured.
|
||||||
*/
|
*/
|
||||||
QmuParserError::QmuParserError(EErrorCodes iErrc,
|
QmuParserError::QmuParserError(EErrorCodes iErrc,
|
||||||
const string_type &sTok,
|
const QString &sTok,
|
||||||
const string_type &sExpr,
|
const QString &sExpr,
|
||||||
int iPos )
|
int iPos )
|
||||||
:m_strMsg()
|
:m_strMsg()
|
||||||
,m_strFormula(sExpr)
|
,m_strFormula(sExpr)
|
||||||
|
@ -171,9 +171,7 @@ namespace qmu
|
||||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||||
{
|
{
|
||||||
m_strMsg = m_ErrMsg[m_iErrc];
|
m_strMsg = m_ErrMsg[m_iErrc];
|
||||||
stringstream_type stream;
|
ReplaceSubString(m_strMsg, "$POS$", QString().setNum(m_iPos));
|
||||||
stream << (int)m_iPos;
|
|
||||||
ReplaceSubString(m_strMsg, "$POS$", stream.str());
|
|
||||||
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +181,7 @@ namespace qmu
|
||||||
\param [in] iPos the position in the expression where the error occured.
|
\param [in] iPos the position in the expression where the error occured.
|
||||||
\param [in] sTok The token string related to this error.
|
\param [in] sTok The token string related to this error.
|
||||||
*/
|
*/
|
||||||
QmuParserError::QmuParserError(EErrorCodes iErrc, int iPos, const string_type &sTok)
|
QmuParserError::QmuParserError(EErrorCodes iErrc, int iPos, const QString &sTok)
|
||||||
:m_strMsg()
|
:m_strMsg()
|
||||||
,m_strFormula()
|
,m_strFormula()
|
||||||
,m_strTok(sTok)
|
,m_strTok(sTok)
|
||||||
|
@ -192,9 +190,7 @@ namespace qmu
|
||||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||||
{
|
{
|
||||||
m_strMsg = m_ErrMsg[m_iErrc];
|
m_strMsg = m_ErrMsg[m_iErrc];
|
||||||
stringstream_type stream;
|
ReplaceSubString(m_strMsg, "$POS$", QString().setNum(m_iPos));
|
||||||
stream << (int)m_iPos;
|
|
||||||
ReplaceSubString(m_strMsg, "$POS$", stream.str());
|
|
||||||
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +200,7 @@ namespace qmu
|
||||||
\param [in] iPos the position related to the error.
|
\param [in] iPos the position related to the error.
|
||||||
\param [in] sTok The token string related to this error.
|
\param [in] sTok The token string related to this error.
|
||||||
*/
|
*/
|
||||||
QmuParserError::QmuParserError(const char_type *szMsg, int iPos, const string_type &sTok)
|
QmuParserError::QmuParserError(const QString &szMsg, int iPos, const QString &sTok)
|
||||||
:m_strMsg(szMsg)
|
:m_strMsg(szMsg)
|
||||||
,m_strFormula()
|
,m_strFormula()
|
||||||
,m_strTok(sTok)
|
,m_strTok(sTok)
|
||||||
|
@ -212,9 +208,7 @@ namespace qmu
|
||||||
,m_iErrc(ecGENERIC)
|
,m_iErrc(ecGENERIC)
|
||||||
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
,m_ErrMsg(QmuParserErrorMsg::Instance())
|
||||||
{
|
{
|
||||||
stringstream_type stream;
|
ReplaceSubString(m_strMsg, "$POS$", QString().setNum(m_iPos));
|
||||||
stream << (int)m_iPos;
|
|
||||||
ReplaceSubString(m_strMsg, "$POS$", stream.str());
|
|
||||||
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,19 +248,17 @@ namespace qmu
|
||||||
\param strFind The string that shall be replaced.
|
\param strFind The string that shall be replaced.
|
||||||
\param strReplaceWith The string that should be inserted instead of strFind
|
\param strReplaceWith The string that should be inserted instead of strFind
|
||||||
*/
|
*/
|
||||||
void QmuParserError::ReplaceSubString( string_type &strSource,
|
void QmuParserError::ReplaceSubString( QString &strSource, const QString &strFind, const QString &strReplaceWith)
|
||||||
const string_type &strFind,
|
|
||||||
const string_type &strReplaceWith)
|
|
||||||
{
|
{
|
||||||
string_type strResult;
|
QString strResult;
|
||||||
string_type::size_type iPos(0), iNext(0);
|
int iPos(0), iNext(0);
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
iNext = strSource.find(strFind, iPos);
|
iNext = strSource.indexOf(strFind, iPos);
|
||||||
strResult.append(strSource, iPos, iNext-iPos);
|
strResult.append(strSource.mid(iPos, iNext-iPos));
|
||||||
|
|
||||||
if( iNext==string_type::npos )
|
if( iNext==-1 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
strResult.append(strReplaceWith);
|
strResult.append(strReplaceWith);
|
||||||
|
@ -289,21 +281,21 @@ namespace qmu
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** \brief Set the expression related to this error. */
|
/** \brief Set the expression related to this error. */
|
||||||
void QmuParserError::SetFormula(const string_type &a_strFormula)
|
void QmuParserError::SetFormula(const QString &a_strFormula)
|
||||||
{
|
{
|
||||||
m_strFormula = a_strFormula;
|
m_strFormula = a_strFormula;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** \brief gets the expression related tp this error.*/
|
/** \brief gets the expression related tp this error.*/
|
||||||
const string_type& QmuParserError::GetExpr() const
|
const QString& QmuParserError::GetExpr() const
|
||||||
{
|
{
|
||||||
return m_strFormula;
|
return m_strFormula;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** \brief Returns the message string for this error. */
|
/** \brief Returns the message string for this error. */
|
||||||
const string_type& QmuParserError::GetMsg() const
|
const QString& QmuParserError::GetMsg() const
|
||||||
{
|
{
|
||||||
return m_strMsg;
|
return m_strMsg;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +312,7 @@ namespace qmu
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** \brief Return string related with this token (if available). */
|
/** \brief Return string related with this token (if available). */
|
||||||
const string_type& QmuParserError::GetToken() const
|
const QString& QmuParserError::GetToken() const
|
||||||
{
|
{
|
||||||
return m_strTok;
|
return m_strTok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,10 +106,10 @@ public:
|
||||||
~QmuParserErrorMsg();
|
~QmuParserErrorMsg();
|
||||||
|
|
||||||
static const QmuParserErrorMsg& Instance();
|
static const QmuParserErrorMsg& Instance();
|
||||||
string_type operator[](unsigned a_iIdx) const;
|
QString operator[](unsigned a_iIdx) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<string_type> m_vErrMsg; ///< A vector with the predefined error messages
|
QVector<QString> m_vErrMsg; ///< A vector with the predefined error messages
|
||||||
static const self_type m_Instance; ///< The instance pointer
|
static const self_type m_Instance; ///< The instance pointer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,41 +124,34 @@ class QmuParserError
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** \brief Replace all ocuurences of a substring with another string. */
|
/** \brief Replace all ocuurences of a substring with another string. */
|
||||||
void ReplaceSubString( string_type &strSource,
|
void ReplaceSubString(QString &strSource,
|
||||||
const string_type &strFind,
|
const QString &strFind,
|
||||||
const string_type &strReplaceWith);
|
const QString &strReplaceWith);
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
QmuParserError();
|
QmuParserError();
|
||||||
explicit QmuParserError(EErrorCodes a_iErrc);
|
explicit QmuParserError(EErrorCodes a_iErrc);
|
||||||
explicit QmuParserError(const string_type &sMsg);
|
explicit QmuParserError(const QString &sMsg);
|
||||||
QmuParserError( EErrorCodes a_iErrc,
|
QmuParserError( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1);
|
||||||
const string_type &sTok,
|
QmuParserError(EErrorCodes a_iErrc, int a_iPos, const QString &sTok);
|
||||||
const string_type &sFormula = string_type(),
|
QmuParserError(const QString &a_szMsg, int a_iPos, const QString &sTok = QString());
|
||||||
int a_iPos = -1);
|
|
||||||
QmuParserError( EErrorCodes a_iErrc,
|
|
||||||
int a_iPos,
|
|
||||||
const string_type &sTok);
|
|
||||||
QmuParserError( const char_type *a_szMsg,
|
|
||||||
int a_iPos = -1,
|
|
||||||
const string_type &sTok = string_type());
|
|
||||||
QmuParserError(const QmuParserError &a_Obj);
|
QmuParserError(const QmuParserError &a_Obj);
|
||||||
QmuParserError& operator=(const QmuParserError &a_Obj);
|
QmuParserError& operator=(const QmuParserError &a_Obj);
|
||||||
~QmuParserError();
|
~QmuParserError();
|
||||||
|
|
||||||
void SetFormula(const string_type &a_strFormula);
|
void SetFormula(const QString &a_strFormula);
|
||||||
const string_type& GetExpr() const;
|
const QString &GetExpr() const;
|
||||||
const string_type& GetMsg() const;
|
const QString &GetMsg() const;
|
||||||
std::size_t GetPos() const;
|
std::size_t GetPos() const;
|
||||||
const string_type& GetToken() const;
|
const QString &GetToken() const;
|
||||||
EErrorCodes GetCode() const;
|
EErrorCodes GetCode() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string_type m_strMsg; ///< The message string
|
QString m_strMsg; ///< The message string
|
||||||
string_type m_strFormula; ///< Formula string
|
QString m_strFormula; ///< Formula string
|
||||||
string_type m_strTok; ///< Token related with the error
|
QString m_strTok; ///< Token related with the error
|
||||||
int m_iPos; ///< Formula position related to the error
|
int m_iPos; ///< Formula position related to the error
|
||||||
EErrorCodes m_iErrc; ///< Error code
|
EErrorCodes m_iErrc; ///< Error code
|
||||||
const QmuParserErrorMsg &m_ErrMsg;
|
const QmuParserErrorMsg &m_ErrMsg;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "qmuparsertest.h"
|
#include "qmuparsertest.h"
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -60,32 +61,37 @@ namespace qmu
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------
|
||||||
int QmuParserTester::IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal)
|
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') )
|
if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsigned iVal(0);
|
unsigned iVal(0);
|
||||||
|
bool ok = false;
|
||||||
|
iVal = a_szExpr.toUInt(&ok, 16);
|
||||||
|
|
||||||
// New code based on streams for UNICODE compliance:
|
if(ok)
|
||||||
stringstream_type::pos_type nPos(0);
|
{
|
||||||
stringstream_type ss(a_szExpr + 2);
|
int nPos = a_szExpr.indexOf(QString().setNum(iVal, 16));
|
||||||
ss >> std::hex >> iVal;
|
if(nPos == 0)
|
||||||
nPos = ss.tellg();
|
|
||||||
|
|
||||||
if (nPos==(stringstream_type::pos_type)0)
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
*a_iPos += (int)(2 + nPos);
|
*a_iPos += (int)(2 + nPos);
|
||||||
*a_fVal = (qreal)iVal;
|
*a_fVal = (qreal)iVal;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------
|
||||||
int QmuParserTester::TestInterface()
|
int QmuParserTester::TestInterface()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing member functions...";
|
qDebug() << "testing member functions...";
|
||||||
|
|
||||||
// Test RemoveVar
|
// Test RemoveVar
|
||||||
qreal afVal[3] = {1,2,3};
|
qreal afVal[3] = {1,2,3};
|
||||||
|
@ -116,9 +122,9 @@ namespace qmu
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +133,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestStrArg()
|
int QmuParserTester::TestStrArg()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing string arguments...";
|
qDebug() << "testing string arguments...";
|
||||||
|
|
||||||
iStat += EqnTest("valueof(\"\")", 123, true); // empty string arguments caused a crash
|
iStat += EqnTest("valueof(\"\")", 123, true); // empty string arguments caused a crash
|
||||||
iStat += EqnTest("valueof(\"aaa\")+valueof(\"bbb\") ", 246, true);
|
iStat += EqnTest("valueof(\"aaa\")+valueof(\"bbb\") ", 246, true);
|
||||||
|
@ -141,9 +147,9 @@ namespace qmu
|
||||||
iStat += EqnTest("strfun3(\"99\",1,2)", 102, true);
|
iStat += EqnTest("strfun3(\"99\",1,2)", 102, true);
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +158,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestBinOprt()
|
int QmuParserTester::TestBinOprt()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing binary operators...";
|
qDebug() << "testing binary operators...";
|
||||||
|
|
||||||
// built in operators
|
// built in operators
|
||||||
// xor operator
|
// xor operator
|
||||||
|
@ -212,9 +218,9 @@ namespace qmu
|
||||||
iStat += EqnTest("3+4*2/(1-5)^2^3", 3.0001220703125, true);
|
iStat += EqnTest("3+4*2/(1-5)^2^3", 3.0001220703125, true);
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +232,7 @@ namespace qmu
|
||||||
int iStat= 0,
|
int iStat= 0,
|
||||||
iErr = 0;
|
iErr = 0;
|
||||||
|
|
||||||
qmu::console() << "testing name restriction enforcement...";
|
qDebug() << "testing name restriction enforcement...";
|
||||||
|
|
||||||
QmuParser p;
|
QmuParser p;
|
||||||
|
|
||||||
|
@ -321,9 +327,9 @@ namespace qmu
|
||||||
#undef PARSER_THROWCHECK
|
#undef PARSER_THROWCHECK
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -332,7 +338,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestSyntax()
|
int QmuParserTester::TestSyntax()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing syntax engine...";
|
qDebug() << "testing syntax engine...";
|
||||||
|
|
||||||
iStat += ThrowTest("1,", ecUNEXPECTED_EOF); // incomplete hex definition
|
iStat += ThrowTest("1,", ecUNEXPECTED_EOF); // incomplete hex definition
|
||||||
iStat += ThrowTest("a,", ecUNEXPECTED_EOF); // incomplete hex definition
|
iStat += ThrowTest("a,", ecUNEXPECTED_EOF); // incomplete hex definition
|
||||||
|
@ -370,9 +376,9 @@ namespace qmu
|
||||||
iStat += EqnTest("sin()", 0, false); // unexpected closing bracket
|
iStat += EqnTest("sin()", 0, false); // unexpected closing bracket
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -381,7 +387,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestVarConst()
|
int QmuParserTester::TestVarConst()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing variable/constant detection...";
|
qDebug() << "testing variable/constant detection...";
|
||||||
|
|
||||||
// Test if the result changes when a variable changes
|
// Test if the result changes when a variable changes
|
||||||
iStat += EqnTestWithVarChange( "a", 1, 1, 2, 2 );
|
iStat += EqnTestWithVarChange( "a", 1, 1, 2, 2 );
|
||||||
|
@ -479,9 +485,9 @@ namespace qmu
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -490,7 +496,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestMultiArg()
|
int QmuParserTester::TestMultiArg()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing multiarg functions...";
|
qDebug() << "testing multiarg functions...";
|
||||||
|
|
||||||
// Compound expressions
|
// Compound expressions
|
||||||
iStat += EqnTest( "1,2,3", 3, true);
|
iStat += EqnTest( "1,2,3", 3, true);
|
||||||
|
@ -573,9 +579,9 @@ namespace qmu
|
||||||
iStat += EqnTest( "sum(,1,2)", 0, false);
|
iStat += EqnTest( "sum(,1,2)", 0, false);
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -585,7 +591,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestInfixOprt()
|
int QmuParserTester::TestInfixOprt()
|
||||||
{
|
{
|
||||||
int iStat(0);
|
int iStat(0);
|
||||||
qmu::console() << "testing infix operators...";
|
qDebug() << "testing infix operators...";
|
||||||
|
|
||||||
iStat += EqnTest( "-1", -1, true);
|
iStat += EqnTest( "-1", -1, true);
|
||||||
iStat += EqnTest( "-(-1)", 1, true);
|
iStat += EqnTest( "-(-1)", 1, true);
|
||||||
|
@ -638,9 +644,9 @@ namespace qmu
|
||||||
iStat += EqnTest( "~~ 123", 123+2, true);
|
iStat += EqnTest( "~~ 123", 123+2, true);
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -650,7 +656,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestPostFix()
|
int QmuParserTester::TestPostFix()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing postfix operators...";
|
qDebug() << "testing postfix operators...";
|
||||||
|
|
||||||
// application
|
// application
|
||||||
iStat += EqnTest( "3{m}+5", 5.003, true);
|
iStat += EqnTest( "3{m}+5", 5.003, true);
|
||||||
|
@ -690,9 +696,9 @@ namespace qmu
|
||||||
iStat += ThrowTest( "multi*1.0", ecUNASSIGNABLE_TOKEN);
|
iStat += ThrowTest( "multi*1.0", ecUNASSIGNABLE_TOKEN);
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -701,7 +707,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestExpression()
|
int QmuParserTester::TestExpression()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing expression samples...";
|
qDebug() << "testing expression samples...";
|
||||||
|
|
||||||
qreal b = 2;
|
qreal b = 2;
|
||||||
|
|
||||||
|
@ -770,9 +776,9 @@ namespace qmu
|
||||||
iStat += EqnTest( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true);
|
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)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -783,7 +789,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestIfThenElse()
|
int QmuParserTester::TestIfThenElse()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing if-then-else operator...";
|
qDebug() << "testing if-then-else operator...";
|
||||||
|
|
||||||
// Test error detection
|
// Test error detection
|
||||||
iStat += ThrowTest(":3", ecUNEXPECTED_CONDITIONAL);
|
iStat += ThrowTest(":3", ecUNEXPECTED_CONDITIONAL);
|
||||||
|
@ -878,9 +884,9 @@ namespace qmu
|
||||||
iStat += EqnTest("a=0?5:b=1?3:4, b", 3, true);
|
iStat += EqnTest("a=0?5:b=1?3:4, b", 3, true);
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors";
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -889,7 +895,7 @@ namespace qmu
|
||||||
int QmuParserTester::TestException()
|
int QmuParserTester::TestException()
|
||||||
{
|
{
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
qmu::console() << "testing error codes...";
|
qDebug() << "testing error codes...";
|
||||||
|
|
||||||
iStat += ThrowTest("3+", ecUNEXPECTED_EOF);
|
iStat += ThrowTest("3+", ecUNEXPECTED_EOF);
|
||||||
iStat += ThrowTest("3+)", ecUNEXPECTED_PARENS);
|
iStat += ThrowTest("3+)", ecUNEXPECTED_PARENS);
|
||||||
|
@ -972,9 +978,9 @@ namespace qmu
|
||||||
iStat += ThrowTest( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT);
|
iStat += ThrowTest( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT);
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
qmu::console() << "passed" << endl;
|
qDebug() << "passed" ;
|
||||||
else
|
else
|
||||||
qmu::console() << "\n failed with " << iStat << " errors" << endl;
|
qDebug() << "\n failed with " << iStat << " errors" ;
|
||||||
|
|
||||||
return iStat;
|
return iStat;
|
||||||
}
|
}
|
||||||
|
@ -997,37 +1003,37 @@ namespace qmu
|
||||||
}
|
}
|
||||||
catch(QmuParser::exception_type &e)
|
catch(QmuParser::exception_type &e)
|
||||||
{
|
{
|
||||||
qmu::console() << "\n" << e.GetMsg() << endl;
|
qDebug() << "\n" << e.GetMsg() ;
|
||||||
qmu::console() << e.GetToken() << endl;
|
qDebug() << e.GetToken() ;
|
||||||
Abort();
|
Abort();
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
qmu::console() << e.what() << endl;
|
qDebug() << e.what() ;
|
||||||
Abort();
|
Abort();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
qmu::console() << "Internal error";
|
qDebug() << "Internal error";
|
||||||
Abort();
|
Abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iStat==0)
|
if (iStat==0)
|
||||||
{
|
{
|
||||||
qmu::console() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" << endl;
|
qDebug() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qmu::console() << "Test failed with " << iStat
|
qDebug() << "Test failed with " << iStat
|
||||||
<< " errors (" << QmuParserTester::c_iCount
|
<< " errors (" << QmuParserTester::c_iCount
|
||||||
<< " expressions)" << endl;
|
<< " expressions)" ;
|
||||||
}
|
}
|
||||||
QmuParserTester::c_iCount = 0;
|
QmuParserTester::c_iCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int QmuParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail)
|
int QmuParserTester::ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail)
|
||||||
{
|
{
|
||||||
QmuParserTester::c_iCount++;
|
QmuParserTester::c_iCount++;
|
||||||
|
|
||||||
|
@ -1054,7 +1060,7 @@ namespace qmu
|
||||||
// output the formula in case of an failed test
|
// output the formula in case of an failed test
|
||||||
if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) )
|
if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) )
|
||||||
{
|
{
|
||||||
qmu::console() << "\n "
|
qDebug() << "\n "
|
||||||
<< "Expression: " << a_str
|
<< "Expression: " << a_str
|
||||||
<< " Code:" << e.GetCode() << "(" << e.GetMsg() << ")"
|
<< " Code:" << e.GetCode() << "(" << e.GetMsg() << ")"
|
||||||
<< " Expected:" << a_iErrc;
|
<< " Expected:" << a_iErrc;
|
||||||
|
@ -1067,7 +1073,7 @@ namespace qmu
|
||||||
bool bRet((a_bFail==false) ? 0 : 1);
|
bool bRet((a_bFail==false) ? 0 : 1);
|
||||||
if (bRet==1)
|
if (bRet==1)
|
||||||
{
|
{
|
||||||
qmu::console() << "\n "
|
qDebug() << "\n "
|
||||||
<< "Expression: " << a_str
|
<< "Expression: " << a_str
|
||||||
<< " did evaluate; Expected error:" << a_iErrc;
|
<< " did evaluate; Expected error:" << a_iErrc;
|
||||||
}
|
}
|
||||||
|
@ -1080,7 +1086,7 @@ namespace qmu
|
||||||
|
|
||||||
\return 1 in case of a failure, 0 otherwise.
|
\return 1 in case of a failure, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
int QmuParserTester::EqnTestWithVarChange(const string_type &a_str,
|
int QmuParserTester::EqnTestWithVarChange(const QString &a_str,
|
||||||
double a_fVar1,
|
double a_fVar1,
|
||||||
double a_fRes1,
|
double a_fRes1,
|
||||||
double a_fVar2,
|
double a_fVar2,
|
||||||
|
@ -1112,17 +1118,17 @@ namespace qmu
|
||||||
}
|
}
|
||||||
catch(QmuParser::exception_type &e)
|
catch(QmuParser::exception_type &e)
|
||||||
{
|
{
|
||||||
qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")";
|
qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")";
|
qDebug() << "\n fail: " << a_str << " (" << e.what() << ")";
|
||||||
return 1; // always return a failure since this exception is not expected
|
return 1; // always return a failure since this exception is not expected
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)";
|
qDebug() << "\n fail: " << a_str << " (unexpected exception)";
|
||||||
return 1; // exceptions other than ParserException are not allowed
|
return 1; // exceptions other than ParserException are not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1134,7 +1140,7 @@ namespace qmu
|
||||||
|
|
||||||
\return 1 in case of a failure, 0 otherwise.
|
\return 1 in case of a failure, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
int QmuParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
|
int QmuParserTester::EqnTest(const QString &a_str, double a_fRes, bool a_fPass)
|
||||||
{
|
{
|
||||||
QmuParserTester::c_iCount++;
|
QmuParserTester::c_iCount++;
|
||||||
int iRet(0);
|
int iRet(0);
|
||||||
|
@ -1253,7 +1259,7 @@ namespace qmu
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
qmu::console() << "\n " << e.what() << "\n";
|
qDebug() << "\n " << e.what() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// limited floating point accuracy requires the following test
|
// limited floating point accuracy requires the following test
|
||||||
|
@ -1274,7 +1280,7 @@ namespace qmu
|
||||||
|
|
||||||
if (iRet==1)
|
if (iRet==1)
|
||||||
{
|
{
|
||||||
qmu::console() << "\n fail: " << a_str.c_str()
|
qDebug() << "\n fail: " << a_str
|
||||||
<< " (incorrect result; expected: " << a_fRes
|
<< " (incorrect result; expected: " << a_fRes
|
||||||
<< " ;calculated: " << fVal[0] << ","
|
<< " ;calculated: " << fVal[0] << ","
|
||||||
<< fVal[1] << ","
|
<< fVal[1] << ","
|
||||||
|
@ -1288,20 +1294,20 @@ namespace qmu
|
||||||
if (a_fPass)
|
if (a_fPass)
|
||||||
{
|
{
|
||||||
if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998)
|
if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998)
|
||||||
qmu::console() << "\n fail: " << a_str.c_str() << " (copy construction)";
|
qDebug() << "\n fail: " << a_str << " (copy construction)";
|
||||||
else
|
else
|
||||||
qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")";
|
qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")";
|
qDebug() << "\n fail: " << a_str << " (" << e.what() << ")";
|
||||||
return 1; // always return a failure since this exception is not expected
|
return 1; // always return a failure since this exception is not expected
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)";
|
qDebug() << "\n fail: " << a_str << " (unexpected exception)";
|
||||||
return 1; // exceptions other than ParserException are not allowed
|
return 1; // exceptions other than ParserException are not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1312,7 +1318,7 @@ namespace qmu
|
||||||
/** \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
|
void QmuParserTester::Abort() const
|
||||||
{
|
{
|
||||||
qmu::console() << "Test failed (internal error in test class)" << endl;
|
qDebug() << "Test failed (internal error in test class)" ;
|
||||||
while (!getchar());
|
while (!getchar());
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <numeric> // for accumulate
|
#include <numeric> // for accumulate
|
||||||
#include "qmuparser.h"
|
#include "qmuparser.h"
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
\brief This file contains the parser test class.
|
\brief This file contains the parser test class.
|
||||||
|
@ -48,14 +49,14 @@ namespace qmu
|
||||||
static int c_iCount;
|
static int c_iCount;
|
||||||
|
|
||||||
// Multiarg callbacks
|
// 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 f1of2(qreal v, qreal ) {return v;}
|
||||||
static qreal f2of2(qreal , qreal v) {return v;};
|
static qreal f2of2(qreal , qreal v) {return v;}
|
||||||
|
|
||||||
static qreal f1of3(qreal v, qreal , qreal ) {return v;};
|
static qreal f1of3(qreal v, qreal , qreal ) {return v;}
|
||||||
static qreal f2of3(qreal , qreal v, qreal ) {return v;};
|
static qreal f2of3(qreal , qreal v, qreal ) {return v;}
|
||||||
static qreal f3of3(qreal , qreal , qreal v) {return v;};
|
static qreal f3of3(qreal , qreal , qreal v) {return v;}
|
||||||
|
|
||||||
static qreal f1of4(qreal v, qreal, qreal , qreal ) {return v;}
|
static qreal f1of4(qreal v, qreal, qreal , qreal ) {return v;}
|
||||||
static qreal f2of4(qreal , qreal v, qreal , qreal ) {return v;}
|
static qreal f2of4(qreal , qreal v, qreal , qreal ) {return v;}
|
||||||
|
@ -120,36 +121,32 @@ namespace qmu
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal ValueOf(const char_type*)
|
static qreal ValueOf(const QString &)
|
||||||
{
|
{
|
||||||
return 123;
|
return 123;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal StrFun1(const char_type* v1)
|
static qreal StrFun1(const QString & v1)
|
||||||
{
|
{
|
||||||
int val(0);
|
int val = v1.toInt();
|
||||||
stringstream_type(v1) >> val;
|
|
||||||
return (qreal)val;
|
return (qreal)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal StrFun2(const char_type* v1, qreal v2)
|
static qreal StrFun2(const QString & v1, qreal v2)
|
||||||
{
|
{
|
||||||
int val(0);
|
int val = v1.toInt();
|
||||||
stringstream_type(v1) >> val;
|
|
||||||
return (qreal)(val + v2);
|
return (qreal)(val + v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal StrFun3(const char_type* v1, qreal v2, qreal v3)
|
static qreal StrFun3(const QString & v1, qreal v2, qreal v3)
|
||||||
{
|
{
|
||||||
int val(0);
|
int val = v1.toInt();
|
||||||
stringstream_type(v1) >> val;
|
|
||||||
return val + v2 + v3;
|
return val + v2 + v3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal StrToFloat(const char_type* a_szMsg)
|
static qreal StrToFloat(const QString & a_szMsg)
|
||||||
{
|
{
|
||||||
qreal val(0);
|
qreal val = a_szMsg.toDouble();
|
||||||
stringstream_type(a_szMsg) >> val;
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +156,7 @@ namespace qmu
|
||||||
static qreal Milli(qreal a_fVal) { return a_fVal / (qreal)1e3; }
|
static qreal Milli(qreal a_fVal) { return a_fVal / (qreal)1e3; }
|
||||||
|
|
||||||
// Custom value recognition
|
// Custom value recognition
|
||||||
static int IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal);
|
static int IsHexVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal);
|
||||||
|
|
||||||
int TestNames();
|
int TestNames();
|
||||||
int TestSyntax();
|
int TestSyntax();
|
||||||
|
@ -187,13 +184,13 @@ namespace qmu
|
||||||
void AddTest(testfun_type a_pFun);
|
void AddTest(testfun_type a_pFun);
|
||||||
|
|
||||||
// Test Double Parser
|
// Test Double Parser
|
||||||
int EqnTest(const string_type& a_str, double a_fRes, bool a_fPass);
|
int EqnTest(const QString &a_str, double a_fRes, bool a_fPass);
|
||||||
int EqnTestWithVarChange(const string_type& a_str,
|
int EqnTestWithVarChange(const QString &a_str,
|
||||||
double a_fRes1,
|
double a_fRes1,
|
||||||
double a_fVar1,
|
double a_fVar1,
|
||||||
double a_fRes2,
|
double a_fRes2,
|
||||||
double a_fVar2);
|
double a_fVar2);
|
||||||
int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true);
|
int ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail = true);
|
||||||
};
|
};
|
||||||
} // namespace Test
|
} // namespace Test
|
||||||
} // namespace qmu
|
} // namespace qmu
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
#include "qmuparsertokenreader.h"
|
#include "qmuparsertokenreader.h"
|
||||||
#include "qmuparserbase.h"
|
#include "qmuparserbase.h"
|
||||||
|
|
||||||
|
@ -191,7 +193,7 @@ namespace qmu
|
||||||
\return #m_strFormula
|
\return #m_strFormula
|
||||||
\throw nothrow
|
\throw nothrow
|
||||||
*/
|
*/
|
||||||
const string_type& QmuParserTokenReader::GetExpr() const
|
const QString& QmuParserTokenReader::GetExpr() const
|
||||||
{
|
{
|
||||||
return m_strFormula;
|
return m_strFormula;
|
||||||
}
|
}
|
||||||
|
@ -209,7 +211,7 @@ namespace qmu
|
||||||
Sets the formula position index to zero and set Syntax flags to default for initial formula parsing.
|
Sets the formula position index to zero and set Syntax flags to default for initial formula parsing.
|
||||||
\pre [assert] triggered if a_szFormula==0
|
\pre [assert] triggered if a_szFormula==0
|
||||||
*/
|
*/
|
||||||
void QmuParserTokenReader::SetFormula(const string_type &a_strFormula)
|
void QmuParserTokenReader::SetFormula(const QString &a_strFormula)
|
||||||
{
|
{
|
||||||
m_strFormula = a_strFormula;
|
m_strFormula = a_strFormula;
|
||||||
ReInit();
|
ReInit();
|
||||||
|
@ -253,13 +255,19 @@ namespace qmu
|
||||||
{
|
{
|
||||||
assert(m_pParser);
|
assert(m_pParser);
|
||||||
|
|
||||||
std::stack<int> FunArgs;
|
//std::stack<int> FunArgs;
|
||||||
const char_type *szFormula = m_strFormula.c_str();
|
#if defined(_UNICODE)
|
||||||
|
const char_type *szFormula = m_strFormula.toStdWString().c_str();
|
||||||
|
#else
|
||||||
|
const char_type *szFormula = m_strFormula.toStdString().c_str();
|
||||||
|
#endif
|
||||||
token_type tok;
|
token_type tok;
|
||||||
|
|
||||||
// Ignore all non printable characters when reading the expression
|
// Ignore all non printable characters when reading the expression
|
||||||
while (szFormula[m_iPos]>0 && szFormula[m_iPos]<=0x20)
|
while (szFormula[m_iPos]>0 && szFormula[m_iPos]<=0x20)
|
||||||
|
{
|
||||||
++m_iPos;
|
++m_iPos;
|
||||||
|
}
|
||||||
|
|
||||||
if ( IsEOF(tok) ) return SaveBeforeReturn(tok); // Check for end of formula
|
if ( IsEOF(tok) ) return SaveBeforeReturn(tok); // Check for end of formula
|
||||||
if ( IsOprt(tok) ) return SaveBeforeReturn(tok); // Check for user defined binary operator
|
if ( IsOprt(tok) ) return SaveBeforeReturn(tok); // Check for user defined binary operator
|
||||||
|
@ -281,18 +289,22 @@ namespace qmu
|
||||||
// undefined variables in order to collect all variable
|
// undefined variables in order to collect all variable
|
||||||
// names including the undefined ones.)
|
// names including the undefined ones.)
|
||||||
if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) )
|
if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) )
|
||||||
|
{
|
||||||
return SaveBeforeReturn(tok);
|
return SaveBeforeReturn(tok);
|
||||||
|
}
|
||||||
|
|
||||||
// Check for unknown token
|
// Check for unknown token
|
||||||
//
|
//
|
||||||
// !!! From this point on there is no exit without an exception possible...
|
// !!! From this point on there is no exit without an exception possible...
|
||||||
//
|
//
|
||||||
string_type strTok;
|
QString strTok;
|
||||||
int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
|
int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
|
||||||
if (iEnd!=m_iPos)
|
if (iEnd!=m_iPos)
|
||||||
|
{
|
||||||
Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok);
|
Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok);
|
||||||
|
}
|
||||||
|
|
||||||
Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.substr(m_iPos));
|
Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.mid(m_iPos));
|
||||||
return token_type(); // never reached
|
return token_type(); // never reached
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,18 +330,32 @@ namespace qmu
|
||||||
\return The Position of the first character not listed in a_szCharSet.
|
\return The Position of the first character not listed in a_szCharSet.
|
||||||
\throw nothrow
|
\throw nothrow
|
||||||
*/
|
*/
|
||||||
int QmuParserTokenReader::ExtractToken(const char_type *a_szCharSet,
|
int QmuParserTokenReader::ExtractToken(const QString &a_szCharSet, QString &a_sTok, int a_iPos) const
|
||||||
string_type &a_sTok,
|
|
||||||
int a_iPos) const
|
|
||||||
{
|
{
|
||||||
int iEnd = (int)m_strFormula.find_first_not_of(a_szCharSet, a_iPos);
|
#if defined(_UNICODE)
|
||||||
|
const std::wstring m_strFormulaStd = m_strFormula.toStdWString();
|
||||||
|
const std::wstring a_szCharSetstd = a_szCharSet.toStdWString();
|
||||||
|
#else
|
||||||
|
const std::string m_strFormulaStd = m_strFormula.toStdString();
|
||||||
|
const std::string a_szCharSetStd = a_szCharSet.toStdString();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int iEnd = (int)m_strFormulaStd.find_first_not_of(a_szCharSetStd, a_iPos);
|
||||||
|
|
||||||
if (iEnd==(int)string_type::npos)
|
if (iEnd==(int)string_type::npos)
|
||||||
iEnd = (int)m_strFormula.length();
|
{
|
||||||
|
iEnd = (int)m_strFormulaStd.length();
|
||||||
|
}
|
||||||
|
|
||||||
// Assign token string if there was something found
|
// Assign token string if there was something found
|
||||||
if (a_iPos!=iEnd)
|
if (a_iPos!=iEnd)
|
||||||
a_sTok = string_type( m_strFormula.begin()+a_iPos, m_strFormula.begin()+iEnd);
|
{
|
||||||
|
#if defined(_UNICODE)
|
||||||
|
a_sTok = QString().fromStdWString(std::wstring( m_strFormulaStd.begin()+a_iPos, m_strFormulaStd.begin()+iEnd));
|
||||||
|
#else
|
||||||
|
a_sTok = QString().fromStdString(std::string( m_strFormulaStd.begin()+a_iPos, m_strFormulaStd.begin()+iEnd));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return iEnd;
|
return iEnd;
|
||||||
}
|
}
|
||||||
|
@ -342,17 +368,30 @@ namespace qmu
|
||||||
in operator tokens. To avoid this this function checks specifically
|
in operator tokens. To avoid this this function checks specifically
|
||||||
for operator tokens.
|
for operator tokens.
|
||||||
*/
|
*/
|
||||||
int QmuParserTokenReader::ExtractOperatorToken(string_type &a_sTok,
|
int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) const
|
||||||
int a_iPos) const
|
|
||||||
{
|
{
|
||||||
int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->ValidInfixOprtChars(), a_iPos);
|
#if defined(_UNICODE)
|
||||||
|
const std::wstring m_strFormulaStd = m_strFormula.toStdWString();
|
||||||
|
const std::wstring oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdWString();
|
||||||
|
#else
|
||||||
|
const std::string m_strFormulaStd = m_strFormula.toStdString();
|
||||||
|
const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString();
|
||||||
|
#endif
|
||||||
|
int iEnd = (int)m_strFormulaStd.find_first_not_of(oprtCharsStd, a_iPos);
|
||||||
if (iEnd==(int)string_type::npos)
|
if (iEnd==(int)string_type::npos)
|
||||||
iEnd = (int)m_strFormula.length();
|
{
|
||||||
|
iEnd = (int)m_strFormulaStd.length();
|
||||||
|
}
|
||||||
|
|
||||||
// Assign token string if there was something found
|
// Assign token string if there was something found
|
||||||
if (a_iPos!=iEnd)
|
if (a_iPos!=iEnd)
|
||||||
{
|
{
|
||||||
a_sTok = string_type( m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd);
|
#if defined(_UNICODE)
|
||||||
|
a_sTok = QString().fromStdWString(string_type(m_strFormulaStd.begin() + a_iPos,
|
||||||
|
m_strFormulaStd.begin() + iEnd));
|
||||||
|
#else
|
||||||
|
a_sTok = QString().fromStdString(string_type(m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd));
|
||||||
|
#endif
|
||||||
return iEnd;
|
return iEnd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -370,15 +409,14 @@ namespace qmu
|
||||||
*/
|
*/
|
||||||
bool QmuParserTokenReader::IsBuiltIn(token_type &a_Tok)
|
bool QmuParserTokenReader::IsBuiltIn(token_type &a_Tok)
|
||||||
{
|
{
|
||||||
const char_type **const pOprtDef = m_pParser->GetOprtDef(),
|
const QStringList pOprtDef = m_pParser->GetOprtDef();
|
||||||
*const szFormula = m_strFormula.c_str();
|
|
||||||
|
|
||||||
// Compare token with function and operator strings
|
// Compare token with function and operator strings
|
||||||
// check string for operator/function
|
// check string for operator/function
|
||||||
for (int i=0; pOprtDef[i]; i++)
|
for (int i=0; i < pOprtDef.size(); ++i)
|
||||||
{
|
{
|
||||||
std::size_t len( std::char_traits<char_type>::length(pOprtDef[i]) );
|
int len = pOprtDef.at(i).length();
|
||||||
if ( string_type(pOprtDef[i]) == string_type(szFormula + m_iPos, szFormula + m_iPos + len) )
|
if ( pOprtDef.at(i) == m_strFormula.mid(m_iPos, m_iPos + len) )
|
||||||
{
|
{
|
||||||
switch(i)
|
switch(i)
|
||||||
{
|
{
|
||||||
|
@ -404,7 +442,7 @@ namespace qmu
|
||||||
|
|
||||||
// The assignement operator need special treatment
|
// The assignement operator need special treatment
|
||||||
if (i==cmASSIGN && m_iSynFlags & noASSIGN)
|
if (i==cmASSIGN && m_iSynFlags & noASSIGN)
|
||||||
Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]);
|
Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at(i));
|
||||||
|
|
||||||
if (!m_pParser->HasBuiltInOprt()) continue;
|
if (!m_pParser->HasBuiltInOprt()) continue;
|
||||||
if (m_iSynFlags & noOPT)
|
if (m_iSynFlags & noOPT)
|
||||||
|
@ -415,7 +453,7 @@ namespace qmu
|
||||||
if ( IsInfixOpTok(a_Tok) )
|
if ( IsInfixOpTok(a_Tok) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]);
|
Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;
|
m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;
|
||||||
|
@ -424,7 +462,7 @@ namespace qmu
|
||||||
|
|
||||||
case cmBO:
|
case cmBO:
|
||||||
if (m_iSynFlags & noBO)
|
if (m_iSynFlags & noBO)
|
||||||
Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);
|
Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i));
|
||||||
|
|
||||||
if (m_lastTok.GetCode()==cmFUNC)
|
if (m_lastTok.GetCode()==cmFUNC)
|
||||||
m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;
|
m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;
|
||||||
|
@ -436,24 +474,24 @@ namespace qmu
|
||||||
|
|
||||||
case cmBC:
|
case cmBC:
|
||||||
if (m_iSynFlags & noBC)
|
if (m_iSynFlags & noBC)
|
||||||
Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);
|
Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i));
|
||||||
|
|
||||||
m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN;
|
m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN;
|
||||||
|
|
||||||
if (--m_iBrackets<0)
|
if (--m_iBrackets<0)
|
||||||
Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);
|
Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmELSE:
|
case cmELSE:
|
||||||
if (m_iSynFlags & noELSE)
|
if (m_iSynFlags & noELSE)
|
||||||
Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);
|
Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at(i));
|
||||||
|
|
||||||
m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;
|
m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmIF:
|
case cmIF:
|
||||||
if (m_iSynFlags & noIF)
|
if (m_iSynFlags & noIF)
|
||||||
Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);
|
Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at(i));
|
||||||
|
|
||||||
m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;
|
m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;
|
||||||
break;
|
break;
|
||||||
|
@ -462,8 +500,8 @@ namespace qmu
|
||||||
Error(ecINTERNAL_ERROR);
|
Error(ecINTERNAL_ERROR);
|
||||||
} // switch operator id
|
} // switch operator id
|
||||||
|
|
||||||
m_iPos += (int)len;
|
m_iPos += len;
|
||||||
a_Tok.Set( (ECmdCode)i, pOprtDef[i] );
|
a_Tok.Set( (ECmdCode)i, pOprtDef.at(i) );
|
||||||
return true;
|
return true;
|
||||||
} // if operator string found
|
} // if operator string found
|
||||||
} // end of for all operator strings
|
} // end of for all operator strings
|
||||||
|
@ -474,17 +512,17 @@ namespace qmu
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
bool QmuParserTokenReader::IsArgSep(token_type &a_Tok)
|
bool QmuParserTokenReader::IsArgSep(token_type &a_Tok)
|
||||||
{
|
{
|
||||||
const char_type* szFormula = m_strFormula.c_str();
|
if (m_strFormula.at(m_iPos)==m_cArgSep)
|
||||||
|
|
||||||
if (szFormula[m_iPos]==m_cArgSep)
|
|
||||||
{
|
{
|
||||||
// copy the separator into null terminated string
|
// copy the separator into null terminated string
|
||||||
char_type szSep[2];
|
QString szSep;
|
||||||
szSep[0] = m_cArgSep;
|
szSep[0] = m_cArgSep;
|
||||||
szSep[1] = 0;
|
szSep[1] = 0;
|
||||||
|
|
||||||
if (m_iSynFlags & noARG_SEP)
|
if (m_iSynFlags & noARG_SEP)
|
||||||
|
{
|
||||||
Error(ecUNEXPECTED_ARG_SEP, m_iPos, szSep);
|
Error(ecUNEXPECTED_ARG_SEP, m_iPos, szSep);
|
||||||
|
}
|
||||||
|
|
||||||
m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN;
|
m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN;
|
||||||
m_iPos++;
|
m_iPos++;
|
||||||
|
@ -505,7 +543,11 @@ namespace qmu
|
||||||
*/
|
*/
|
||||||
bool QmuParserTokenReader::IsEOF(token_type &a_Tok)
|
bool QmuParserTokenReader::IsEOF(token_type &a_Tok)
|
||||||
{
|
{
|
||||||
const char_type* szFormula = m_strFormula.c_str();
|
#if defined(_UNICODE)
|
||||||
|
const char_type* szFormula = m_strFormula.toStdWString().c_str();
|
||||||
|
#else
|
||||||
|
const char_type* szFormula = m_strFormula.toStdString().c_str();
|
||||||
|
#endif
|
||||||
|
|
||||||
// check for EOF
|
// check for EOF
|
||||||
if ( !szFormula[m_iPos] /*|| szFormula[m_iPos] == '\n'*/)
|
if ( !szFormula[m_iPos] /*|| szFormula[m_iPos] == '\n'*/)
|
||||||
|
@ -530,7 +572,7 @@ namespace qmu
|
||||||
*/
|
*/
|
||||||
bool QmuParserTokenReader::IsInfixOpTok(token_type &a_Tok)
|
bool QmuParserTokenReader::IsInfixOpTok(token_type &a_Tok)
|
||||||
{
|
{
|
||||||
string_type sTok;
|
QString sTok;
|
||||||
int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos);
|
int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos);
|
||||||
if (iEnd==m_iPos)
|
if (iEnd==m_iPos)
|
||||||
return false;
|
return false;
|
||||||
|
@ -539,7 +581,7 @@ namespace qmu
|
||||||
funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin();
|
funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin();
|
||||||
for ( ; it!=m_pInfixOprtDef->rend(); ++it)
|
for ( ; it!=m_pInfixOprtDef->rend(); ++it)
|
||||||
{
|
{
|
||||||
if (sTok.find(it->first)!=0)
|
if (sTok.indexOf(it->first)!=0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
a_Tok.Set(it->second, it->first);
|
a_Tok.Set(it->second, it->first);
|
||||||
|
@ -575,7 +617,7 @@ namespace qmu
|
||||||
*/
|
*/
|
||||||
bool QmuParserTokenReader::IsFunTok(token_type &a_Tok)
|
bool QmuParserTokenReader::IsFunTok(token_type &a_Tok)
|
||||||
{
|
{
|
||||||
string_type strTok;
|
QString strTok;
|
||||||
int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
|
int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
|
||||||
if (iEnd==m_iPos)
|
if (iEnd==m_iPos)
|
||||||
return false;
|
return false;
|
||||||
|
@ -585,13 +627,12 @@ namespace qmu
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check if the next sign is an opening bracket
|
// Check if the next sign is an opening bracket
|
||||||
const char_type *szFormula = m_strFormula.c_str();
|
if (m_strFormula.at(iEnd)!='(')
|
||||||
if (szFormula[iEnd]!='(')
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
a_Tok.Set(item->second, strTok);
|
a_Tok.Set(item->second, strTok);
|
||||||
|
|
||||||
m_iPos = (int)iEnd;
|
m_iPos = iEnd;
|
||||||
if (m_iSynFlags & noFUN)
|
if (m_iSynFlags & noFUN)
|
||||||
Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString());
|
Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString());
|
||||||
|
|
||||||
|
@ -606,18 +647,19 @@ namespace qmu
|
||||||
*/
|
*/
|
||||||
bool QmuParserTokenReader::IsOprt(token_type &a_Tok)
|
bool QmuParserTokenReader::IsOprt(token_type &a_Tok)
|
||||||
{
|
{
|
||||||
const char_type *const szExpr = m_strFormula.c_str();
|
QString strTok;
|
||||||
string_type strTok;
|
|
||||||
|
|
||||||
int iEnd = ExtractOperatorToken(strTok, m_iPos);
|
int iEnd = ExtractOperatorToken(strTok, m_iPos);
|
||||||
if (iEnd==m_iPos)
|
if (iEnd==m_iPos)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check if the operator is a built in operator, if so ignore it here
|
// Check if the operator is a built in operator, if so ignore it here
|
||||||
const char_type **const pOprtDef = m_pParser->GetOprtDef();
|
const QStringList pOprtDef = m_pParser->GetOprtDef();
|
||||||
for (int i=0; m_pParser->HasBuiltInOprt() && pOprtDef[i]; ++i)
|
QStringList::const_iterator constIterator;
|
||||||
|
for (constIterator = pOprtDef.constBegin(); m_pParser->HasBuiltInOprt() && constIterator != pOprtDef.constEnd();
|
||||||
|
++constIterator)
|
||||||
{
|
{
|
||||||
if (string_type(pOprtDef[i])==strTok)
|
if ((*constIterator)==strTok)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,8 +672,8 @@ namespace qmu
|
||||||
funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin();
|
funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin();
|
||||||
for ( ; it!=m_pOprtDef->rend(); ++it)
|
for ( ; it!=m_pOprtDef->rend(); ++it)
|
||||||
{
|
{
|
||||||
const string_type &sID = it->first;
|
const QString &sID = it->first;
|
||||||
if ( sID == string_type(szExpr + m_iPos, szExpr + m_iPos + sID.length()) )
|
if ( sID == m_strFormula.mid(m_iPos, m_iPos + sID.length()) )
|
||||||
{
|
{
|
||||||
a_Tok.Set(it->second, strTok);
|
a_Tok.Set(it->second, strTok);
|
||||||
|
|
||||||
|
@ -686,7 +728,7 @@ namespace qmu
|
||||||
// token readers.
|
// token readers.
|
||||||
|
|
||||||
// Test if there could be a postfix operator
|
// Test if there could be a postfix operator
|
||||||
string_type sTok;
|
QString sTok;
|
||||||
int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos);
|
int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos);
|
||||||
if (iEnd==m_iPos)
|
if (iEnd==m_iPos)
|
||||||
return false;
|
return false;
|
||||||
|
@ -695,11 +737,11 @@ namespace qmu
|
||||||
funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin();
|
funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin();
|
||||||
for ( ; it!=m_pPostOprtDef->rend(); ++it)
|
for ( ; it!=m_pPostOprtDef->rend(); ++it)
|
||||||
{
|
{
|
||||||
if (sTok.find(it->first)!=0)
|
if (sTok.indexOf(it->first)!=0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
a_Tok.Set(it->second, sTok);
|
a_Tok.Set(it->second, sTok);
|
||||||
m_iPos += (int)it->first.length();
|
m_iPos += it->first.length();
|
||||||
|
|
||||||
m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN;
|
m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN;
|
||||||
return true;
|
return true;
|
||||||
|
@ -721,7 +763,7 @@ namespace qmu
|
||||||
assert(m_pConstDef);
|
assert(m_pConstDef);
|
||||||
assert(m_pParser);
|
assert(m_pParser);
|
||||||
|
|
||||||
string_type strTok;
|
QString strTok;
|
||||||
qreal fVal(0);
|
qreal fVal(0);
|
||||||
int iEnd(0);
|
int iEnd(0);
|
||||||
|
|
||||||
|
@ -737,7 +779,7 @@ namespace qmu
|
||||||
a_Tok.SetVal(item->second, strTok);
|
a_Tok.SetVal(item->second, strTok);
|
||||||
|
|
||||||
if (m_iSynFlags & noVAL)
|
if (m_iSynFlags & noVAL)
|
||||||
Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);
|
Error(ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok);
|
||||||
|
|
||||||
m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
|
m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
|
||||||
return true;
|
return true;
|
||||||
|
@ -750,11 +792,11 @@ namespace qmu
|
||||||
for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item)
|
for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item)
|
||||||
{
|
{
|
||||||
int iStart = m_iPos;
|
int iStart = m_iPos;
|
||||||
if ( (*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal)==1 )
|
if ( (*item)(m_strFormula.mid(m_iPos), &m_iPos, &fVal)==1 )
|
||||||
{
|
{
|
||||||
strTok.assign(m_strFormula.c_str(), iStart, m_iPos);
|
strTok = m_strFormula.mid(iStart, m_iPos);
|
||||||
if (m_iSynFlags & noVAL)
|
if (m_iSynFlags & noVAL)
|
||||||
Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);
|
Error(ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok);
|
||||||
|
|
||||||
a_Tok.SetVal(fVal, strTok);
|
a_Tok.SetVal(fVal, strTok);
|
||||||
m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
|
m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
|
||||||
|
@ -775,7 +817,7 @@ namespace qmu
|
||||||
if (!m_pVarDef->size())
|
if (!m_pVarDef->size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string_type strTok;
|
QString strTok;
|
||||||
int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
|
int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
|
||||||
if (iEnd==m_iPos)
|
if (iEnd==m_iPos)
|
||||||
return false;
|
return false;
|
||||||
|
@ -806,7 +848,7 @@ namespace qmu
|
||||||
if (!m_pStrVarDef || !m_pStrVarDef->size())
|
if (!m_pStrVarDef || !m_pStrVarDef->size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string_type strTok;
|
QString strTok;
|
||||||
int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
|
int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
|
||||||
if (iEnd==m_iPos)
|
if (iEnd==m_iPos)
|
||||||
return false;
|
return false;
|
||||||
|
@ -838,7 +880,7 @@ namespace qmu
|
||||||
*/
|
*/
|
||||||
bool QmuParserTokenReader::IsUndefVarTok(token_type &a_Tok)
|
bool QmuParserTokenReader::IsUndefVarTok(token_type &a_Tok)
|
||||||
{
|
{
|
||||||
string_type strTok;
|
QString strTok;
|
||||||
int iEnd( ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos) );
|
int iEnd( ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos) );
|
||||||
if ( iEnd==m_iPos )
|
if ( iEnd==m_iPos )
|
||||||
return false;
|
return false;
|
||||||
|
@ -855,7 +897,7 @@ namespace qmu
|
||||||
// If a factory is available implicitely create new variables
|
// If a factory is available implicitely create new variables
|
||||||
if (m_pFactory)
|
if (m_pFactory)
|
||||||
{
|
{
|
||||||
qreal *fVar = m_pFactory(strTok.c_str(), m_pFactoryData);
|
qreal *fVar = m_pFactory(strTok, m_pFactoryData);
|
||||||
a_Tok.SetVar(fVar, strTok );
|
a_Tok.SetVar(fVar, strTok );
|
||||||
|
|
||||||
// Do not use m_pParser->DefineVar( strTok, fVar );
|
// Do not use m_pParser->DefineVar( strTok, fVar );
|
||||||
|
@ -893,21 +935,21 @@ namespace qmu
|
||||||
if (m_strFormula[m_iPos]!='"')
|
if (m_strFormula[m_iPos]!='"')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string_type strBuf(&m_strFormula[m_iPos+1]);
|
QString strBuf(m_strFormula[m_iPos+1]);
|
||||||
std::size_t iEnd(0), iSkip(0);
|
int iEnd(0), iSkip(0);
|
||||||
|
|
||||||
// parser over escaped '\"' end replace them with '"'
|
// parser over escaped '\"' end replace them with '"'
|
||||||
for(iEnd=(int)strBuf.find( "\"" ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( "\"", iEnd))
|
for(iEnd=strBuf.indexOf( "\"" ); iEnd!=0 && iEnd!=-1; iEnd=strBuf.indexOf( "\"", iEnd))
|
||||||
{
|
{
|
||||||
if (strBuf[iEnd-1]!='\\') break;
|
if (strBuf[iEnd-1]!='\\') break;
|
||||||
strBuf.replace(iEnd-1, 2, "\"" );
|
strBuf.replace(iEnd-1, 2, "\"" );
|
||||||
iSkip++;
|
iSkip++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iEnd==string_type::npos)
|
if (iEnd==-1)
|
||||||
Error(ecUNTERMINATED_STRING, m_iPos, "\"" );
|
Error(ecUNTERMINATED_STRING, m_iPos, "\"" );
|
||||||
|
|
||||||
string_type strTok(strBuf.begin(), strBuf.begin()+iEnd);
|
QString strTok = strBuf.mid(0, iEnd);
|
||||||
|
|
||||||
if (m_iSynFlags & noSTR)
|
if (m_iSynFlags & noSTR)
|
||||||
Error(ecUNEXPECTED_STR, m_iPos, strTok);
|
Error(ecUNEXPECTED_STR, m_iPos, strTok);
|
||||||
|
@ -915,7 +957,7 @@ namespace qmu
|
||||||
m_pParser->m_vStringBuf.push_back(strTok); // Store string in internal buffer
|
m_pParser->m_vStringBuf.push_back(strTok); // Store string in internal buffer
|
||||||
a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size());
|
a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size());
|
||||||
|
|
||||||
m_iPos += (int)strTok.length() + 2 + (int)iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen
|
m_iPos += (int)strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen
|
||||||
m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND );
|
m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -933,7 +975,7 @@ namespace qmu
|
||||||
*/
|
*/
|
||||||
void QmuParserTokenReader::Error( EErrorCodes a_iErrc,
|
void QmuParserTokenReader::Error( EErrorCodes a_iErrc,
|
||||||
int a_iPos,
|
int a_iPos,
|
||||||
const string_type &a_sTok) const
|
const QString &a_sTok) const
|
||||||
{
|
{
|
||||||
m_pParser->Error(a_iErrc, a_iPos, a_sTok);
|
m_pParser->Error(a_iErrc, a_iPos, a_sTok);
|
||||||
}
|
}
|
||||||
|
@ -945,7 +987,7 @@ namespace qmu
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
char_type QmuParserTokenReader::GetArgSep() const
|
QChar QmuParserTokenReader::GetArgSep() const
|
||||||
{
|
{
|
||||||
return m_cArgSep;
|
return m_cArgSep;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace qmu
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef QmuParserToken<qreal, string_type> token_type;
|
typedef QmuParserToken<qreal, QString> token_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -61,13 +61,13 @@ namespace qmu
|
||||||
|
|
||||||
void AddValIdent(identfun_type a_pCallback);
|
void AddValIdent(identfun_type a_pCallback);
|
||||||
void SetVarCreator(facfun_type a_pFactory, void *pUserData);
|
void SetVarCreator(facfun_type a_pFactory, void *pUserData);
|
||||||
void SetFormula(const string_type &a_strFormula);
|
void SetFormula(const QString &a_strFormula);
|
||||||
void SetArgSep(char_type cArgSep);
|
void SetArgSep(char_type cArgSep);
|
||||||
|
|
||||||
int GetPos() const;
|
int GetPos() const;
|
||||||
const string_type& GetExpr() const;
|
const QString &GetExpr() const;
|
||||||
varmap_type& GetUsedVar();
|
varmap_type& GetUsedVar();
|
||||||
char_type GetArgSep() const;
|
QChar GetArgSep() const;
|
||||||
|
|
||||||
void IgnoreUndefVar(bool bIgnore);
|
void IgnoreUndefVar(bool bIgnore);
|
||||||
void ReInit();
|
void ReInit();
|
||||||
|
@ -106,10 +106,8 @@ namespace qmu
|
||||||
void Assign(const QmuParserTokenReader &a_Reader);
|
void Assign(const QmuParserTokenReader &a_Reader);
|
||||||
|
|
||||||
void SetParent(QmuParserBase *a_pParent);
|
void SetParent(QmuParserBase *a_pParent);
|
||||||
int ExtractToken(const char_type *a_szCharSet,
|
int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const;
|
||||||
string_type &a_strTok,
|
int ExtractOperatorToken(QString &a_sTok, int a_iPos) const;
|
||||||
int a_iPos) const;
|
|
||||||
int ExtractOperatorToken(string_type &a_sTok, int a_iPos) const;
|
|
||||||
|
|
||||||
bool IsBuiltIn(token_type &a_Tok);
|
bool IsBuiltIn(token_type &a_Tok);
|
||||||
bool IsArgSep(token_type &a_Tok);
|
bool IsArgSep(token_type &a_Tok);
|
||||||
|
@ -125,12 +123,12 @@ namespace qmu
|
||||||
bool IsString(token_type &a_Tok);
|
bool IsString(token_type &a_Tok);
|
||||||
void Error(EErrorCodes a_iErrc,
|
void Error(EErrorCodes a_iErrc,
|
||||||
int a_iPos = -1,
|
int a_iPos = -1,
|
||||||
const string_type &a_sTok = string_type() ) const;
|
const QString &a_sTok = QString() ) const;
|
||||||
|
|
||||||
token_type& SaveBeforeReturn(const token_type &tok);
|
token_type& SaveBeforeReturn(const token_type &tok);
|
||||||
|
|
||||||
QmuParserBase *m_pParser;
|
QmuParserBase *m_pParser;
|
||||||
string_type m_strFormula;
|
QString m_strFormula;
|
||||||
int m_iPos;
|
int m_iPos;
|
||||||
int m_iSynFlags;
|
int m_iSynFlags;
|
||||||
bool m_bIgnoreUndefVar;
|
bool m_bIgnoreUndefVar;
|
||||||
|
@ -149,7 +147,7 @@ namespace qmu
|
||||||
qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables
|
qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables
|
||||||
int m_iBrackets;
|
int m_iBrackets;
|
||||||
token_type m_lastTok;
|
token_type m_lastTok;
|
||||||
char_type m_cArgSep; ///< The character used for separating function arguments
|
QChar m_cArgSep; ///< The character used for separating function arguments
|
||||||
};
|
};
|
||||||
} // namespace qmu
|
} // namespace qmu
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user