Disable multiple subexpression mode. One expresiion per time.

--HG--
branch : feature
This commit is contained in:
dismine 2014-08-29 16:42:53 +03:00
parent 2b83e18773
commit 44d1465881
8 changed files with 48 additions and 95 deletions

View File

@ -55,14 +55,7 @@ Calculator::Calculator(const VContainer *data)
:QmuParser(), vVarVal(nullptr), data(data) :QmuParser(), vVarVal(nullptr), data(data)
{ {
InitCharacterSets(); InitCharacterSets();
setAllowSubexpressions(false);//Only one expression per time
// Add unary operators
DefinePostfixOprt(cm_Oprt, CmUnit);
DefinePostfixOprt(mm_Oprt, MmUnit);
DefinePostfixOprt(in_Oprt, InchUnit);
SetArgSep(',');
SetDecSep('.');
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -85,15 +78,12 @@ Calculator::Calculator(const QString &formula, bool fromUser)
:QmuParser(), vVarVal(nullptr), data(nullptr) :QmuParser(), vVarVal(nullptr), data(nullptr)
{ {
InitCharacterSets(); InitCharacterSets();
setAllowSubexpressions(false);//Only one expression per time
SetVarFactory(AddVariable, this); SetVarFactory(AddVariable, this);
// Add unary operators // Add unary operators
if (fromUser) if (fromUser)
{ {
DefinePostfixOprt(qApp->PostfixOperator(cm_Oprt), CmUnit);
DefinePostfixOprt(qApp->PostfixOperator(mm_Oprt), MmUnit);
DefinePostfixOprt(qApp->PostfixOperator(in_Oprt), InchUnit);
bool osSeparatorValue = qApp->getSettings()->value("configuration/osSeparator", 1).toBool(); bool osSeparatorValue = qApp->getSettings()->value("configuration/osSeparator", 1).toBool();
if (osSeparatorValue) if (osSeparatorValue)
@ -111,16 +101,13 @@ Calculator::Calculator(const QString &formula, bool fromUser)
} }
else else
{ {
DefinePostfixOprt(cm_Oprt, CmUnit);
DefinePostfixOprt(mm_Oprt, MmUnit);
DefinePostfixOprt(in_Oprt, InchUnit);
SetArgSep(','); SetArgSep(',');
SetDecSep('.'); SetDecSep('.');
} }
SetExpr(formula); SetExpr(formula);
//Need run for making tokens. Don't catch exception here, because because we want know if formula has error. //Need run for making tokens. Don't catch exception here, because we want know if formula has error.
Eval(); Eval();
} }
@ -221,69 +208,6 @@ void Calculator::InitCharacterSets()
DefineOprtChars(symbols + QStringLiteral("+-*^/?<>=#!$%&|~'_")); DefineOprtChars(symbols + QStringLiteral("+-*^/?<>=#!$%&|~'_"));
} }
//---------------------------------------------------------------------------------------------------------------------
qreal Calculator::CmUnit(qreal val)
{
qreal unit = val;
switch (qApp->patternUnit())
{
case Unit::Mm:
unit = val * 10.0;
break;
case Unit::Cm:
break;
case Unit::Inch:
unit = val / 2.54;
break;
default:
break;
}
return unit;
}
//---------------------------------------------------------------------------------------------------------------------
qreal Calculator::MmUnit(qreal val)
{
qreal unit = val;
switch (qApp->patternUnit())
{
case Unit::Mm:
break;
case Unit::Cm:
unit = val / 10.0;
break;
case Unit::Inch:
unit = val / 25.4;
break;
default:
break;
}
return unit;
}
//---------------------------------------------------------------------------------------------------------------------
qreal Calculator::InchUnit(qreal val)
{
qreal unit = val;
switch (qApp->patternUnit())
{
case Unit::Mm:
unit = val * 25.4;
break;
case Unit::Cm:
unit = val * 2.54;
break;
case Unit::Inch:
break;
default:
break;
}
return unit;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Factory function for creating new parser variables // Factory function for creating new parser variables
// This could as well be a function performing database queries. // This could as well be a function performing database queries.

View File

@ -66,9 +66,6 @@ private:
const VContainer *data; const VContainer *data;
void InitVariables(const VContainer *data, const QMap<int, QString> &tokens); void InitVariables(const VContainer *data, const QMap<int, QString> &tokens);
void InitCharacterSets(); void InitCharacterSets();
static qreal CmUnit(qreal val);
static qreal MmUnit(qreal val);
static qreal InchUnit(qreal val);
static qreal* AddVariable(const QString &a_szName, void *a_pUserData); static qreal* AddVariable(const QString &a_szName, void *a_pUserData);
}; };

View File

@ -40,7 +40,7 @@ VFormula::VFormula()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VFormula::VFormula(const QString &formula, const VContainer *container) VFormula::VFormula(const QString &formula, const VContainer *container)
:formula(formula), value(QString(tr("Error"))), checkZero(true), data(container), toolId(NULL_ID), :formula(qApp->FormulaToUser(formula)), value(QString(tr("Error"))), checkZero(true), data(container), toolId(NULL_ID),
postfix(QStringLiteral("")), _error(true) postfix(QStringLiteral("")), _error(true)
{ {
this->formula.replace("\n", " ");// Replace line return with spaces for calc if exist this->formula.replace("\n", " ");// Replace line return with spaces for calc if exist
@ -90,17 +90,32 @@ bool VFormula::operator!=(const VFormula &formula) const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QString VFormula::getFormula() const QString VFormula::getFormula(FormulaType type) const
{ {
if (type == FormulaType::ToUser)
{
return formula; return formula;
}
else
{
return qApp->FormulaFromUser(formula);
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VFormula::setFormula(const QString &value) void VFormula::setFormula(const QString &value, FormulaType type)
{ {
if (formula != value) if (formula != value)
{
if (type == FormulaType::ToUser)
{ {
formula = value; formula = value;
}
else
{
formula = qApp->FormulaToUser(value);
}
formula.replace("\n", " ");// Replace line return with spaces for calc if exist
Eval(); Eval();
} }
} }
@ -200,7 +215,8 @@ void VFormula::Eval()
try try
{ {
Calculator *cal = new Calculator(data); Calculator *cal = new Calculator(data);
const qreal result = cal->EvalFormula(formula); QString expression = qApp->FormulaFromUser(formula);
const qreal result = cal->EvalFormula(expression);
delete cal; delete cal;
//if result equal 0 //if result equal 0

View File

@ -31,6 +31,8 @@
#include <QCoreApplication> #include <QCoreApplication>
enum class FormulaType : char{ToUser, FromUser};
class VContainer; class VContainer;
class VFormula class VFormula
@ -44,8 +46,8 @@ public:
bool operator==(const VFormula &formula) const; bool operator==(const VFormula &formula) const;
bool operator!=(const VFormula &formula) const; bool operator!=(const VFormula &formula) const;
QString getFormula() const; QString getFormula(FormulaType type = FormulaType::ToUser) const;
void setFormula(const QString &value); void setFormula(const QString &value, FormulaType type = FormulaType::ToUser);
QString getValue() const; QString getValue() const;

View File

@ -88,11 +88,11 @@ void VFormulaPropertyEditor::onToolButtonClicked()
DialogEditWrongFormula* tmpWidget = new DialogEditWrongFormula(formula.getData(), formula.getToolId()); DialogEditWrongFormula* tmpWidget = new DialogEditWrongFormula(formula.getData(), formula.getToolId());
tmpWidget->setCheckZero(formula.getCheckZero()); tmpWidget->setCheckZero(formula.getCheckZero());
tmpWidget->setPostfix(formula.getPostfix()); tmpWidget->setPostfix(formula.getPostfix());
tmpWidget->setFormula(formula.getFormula()); tmpWidget->setFormula(formula.getFormula(FormulaType::FromUser));
if (tmpWidget->exec() == QDialog::Accepted) if (tmpWidget->exec() == QDialog::Accepted)
{ {
formula.setFormula(tmpWidget->getFormula()); formula.setFormula(tmpWidget->getFormula(), FormulaType::ToUser);
TextLabel->setText(formula.getValue()); TextLabel->setText(formula.getValue());
delete tmpWidget; delete tmpWidget;
emit dataChangedByUser(formula, this); emit dataChangedByUser(formula, this);

View File

@ -148,7 +148,7 @@ void VToolOptionsPropertyBrowser::userChangedData(VProperty *property)
VFormula formula = variant.value<VFormula>(); VFormula formula = variant.value<VFormula>();
if (formula.error() == false) if (formula.error() == false)
{ {
i->setFormulaLength(variant.value<VFormula>().getFormula()); i->setFormulaLength(variant.value<VFormula>().getFormula(FormulaType::FromUser));
} }
} }
break; break;

View File

@ -65,7 +65,7 @@ QmuParserBase::QmuParserBase()
:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(),
m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(),
m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(),
m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()), m_Numbers(QMap<int, QString>()) m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()), m_Numbers(QMap<int, QString>()), allowSubexpressions(true)
{ {
InitTokenReader(); InitTokenReader();
} }
@ -80,7 +80,7 @@ QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser)
:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(),
m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(),
m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(),
m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()), m_Numbers(QMap<int, QString>()) m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()), m_Numbers(QMap<int, QString>()), allowSubexpressions(true)
{ {
m_pTokenReader.reset(new token_reader_type(this)); m_pTokenReader.reset(new token_reader_type(this));
Assign(a_Parser); Assign(a_Parser);
@ -219,6 +219,12 @@ void QmuParserBase::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd)
Q_UNUSED(nEnd); Q_UNUSED(nEnd);
} }
//---------------------------------------------------------------------------------------------------------------------
void QmuParserBase::setAllowSubexpressions(bool value)
{
allowSubexpressions = value;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief Returns the version of muparser. * @brief Returns the version of muparser.
@ -1323,6 +1329,10 @@ void QmuParserBase::CreateRPN() const
{ {
Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos()); Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos());
} }
if (stOpt.empty() && allowSubexpressions == false)
{
Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos());
}
++stArgCount.top(); ++stArgCount.top();
// fallthrough intentional (no break!) // fallthrough intentional (no break!)
case cmEND: case cmEND:

View File

@ -120,6 +120,8 @@ public:
{ {
AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
} }
void setAllowSubexpressions(bool value);
protected: protected:
static const QStringList 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
@ -235,6 +237,8 @@ private:
mutable QMap<int, QString> m_Tokens;///< Keep all tokens that we can translate mutable QMap<int, QString> m_Tokens;///< Keep all tokens that we can translate
mutable QMap<int, QString> m_Numbers;///< Keep all numbers what exist in formula mutable QMap<int, QString> m_Numbers;///< Keep all numbers what exist in formula
bool allowSubexpressions;
void Assign(const QmuParserBase &a_Parser); void Assign(const QmuParserBase &a_Parser);
void InitTokenReader(); void InitTokenReader();
void ReInit() const; void ReInit() const;