X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/abbc64cf04a35ab3549d5c516f44c7c5921baa63..3bcfe4df6fdde086eb1b59f7a0173358170174a1:/ArithmeticEvaluator.cpp?ds=sidebyside diff --git a/ArithmeticEvaluator.cpp b/ArithmeticEvaluator.cpp index 60db08e..2898f13 100644 --- a/ArithmeticEvaluator.cpp +++ b/ArithmeticEvaluator.cpp @@ -15,20 +15,26 @@ supp. infos : saved in UTF-8 [éè] #include ArithmeticEvaluator::ArithmeticEvaluator() { - opMarkers = "+-*/"; + opMarkers = "+-*/|%"; // | is for euclidan division varMarkers = "$"; expression = QStringList(); /* CAUTION : function are mandatory using ( ) to encapsulate the operand since spaces are removed. Thus, an expression like sin 10 will lead to sin10 after spaces removal, and thus becomes invalid. */ - fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round"; + fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round"; } ArithmeticEvaluator::ArithmeticEvaluator(const QString& _expression) throw(int) { - opMarkers = "+-*/"; + opMarkers = "+-*/|%"; // | is for euclidan division varMarkers = "$"; - fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round"; + expression = QStringList(); + /* CAUTION : function are mandatory using ( ) to encapsulate the operand + since spaces are removed. Thus, an expression like sin 10 will lead to + sin10 after spaces removal, and thus becomes invalid. + */ + fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round"; + try { setExpression(_expression); } @@ -37,7 +43,10 @@ ArithmeticEvaluator::ArithmeticEvaluator(const QString& _expression) throw(int) } } -void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) { +void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) { + + setVariableNames(_expression); + try { convert(_expression); } @@ -46,6 +55,28 @@ void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) { } } +void ArithmeticEvaluator::setVariablesValue(const QHash& _varValues) { + varValues = _varValues; + /* + QHashIterator iterV(varValues); + while (iterV.hasNext()) { + iterV.next(); + cout << "var " << qPrintable(iterV.key()) << " = " << iterV.value() << endl; + } + */ +} + +void ArithmeticEvaluator::setVariableNames(const QString& _expression) { + varNames.clear(); + QRegularExpression re("[$][a-zA-Z0-9_]+"); + QRegularExpressionMatchIterator matcher = re.globalMatch(_expression); + while(matcher.hasNext()) { + QRegularExpressionMatch m = matcher.next(); + QString var = m.captured(0); + varNames.append(var); + } +} + void ArithmeticEvaluator::print() { foreach(QString elt, expression) { cout << qPrintable(elt) << " "; @@ -84,6 +115,7 @@ double ArithmeticEvaluator::evalFunction(int indexFunc, double value) { } double ArithmeticEvaluator::evaluate() throw(int) { + errorMessage = ""; QStack stack; bool ok; double value1,value2; @@ -102,7 +134,11 @@ double ArithmeticEvaluator::evaluate() throw(int) { stack.push(evalFunction(idFunc,value1)); } else if (varMarkers.contains(c)) { - if (!varValues.contains(elt)) throw(-index); + if (!varValues.contains(elt)) { + errorMessage = "cannot find value of "; + errorMessage += qPrintable(elt); + throw(-index); + } stack.push(varValues.value(elt)); } else if (opMarkers.contains(c)) { @@ -120,6 +156,16 @@ double ArithmeticEvaluator::evaluate() throw(int) { else if (c == '/') { stack.push(value1/value2); } + else if (c == '|') { + int val1 = (int)value1; + int val2 = (int)value2; + stack.push(val1/val2); + } + else if (c == '%') { + int val1 = (int)value1; + int val2 = (int)value2; + stack.push(val1%val2); + } } else { value1 = elt.toDouble(&ok); @@ -165,15 +211,15 @@ double ArithmeticEvaluator::evaluate() throw(int) { */ void ArithmeticEvaluator::convert(const QString& _expression) throw(int) { - QString expr = _expression; + + QString expr = _expression; QString result=""; - expr.remove(QChar(' '), Qt::CaseInsensitive); - foreach(QString func, fctMarkers) { + expr.remove(QChar(' '), Qt::CaseInsensitive); + foreach(QString func, fctMarkers) { QString rep = QString("\x1b%1").arg(fctMarkers.indexOf(QRegExp(func))); expr.replace(QRegExp(func),rep); - } - //cout << "packed expr: " << qPrintable(expr) << endl; + } int offset = 0; try { @@ -267,7 +313,7 @@ QString ArithmeticEvaluator::convertRecur(const QString& _expression, int *offse *offset += 1; } } - else if (expr[*offset] == '/') { + else if ((expr[*offset] == '/')||(expr[*offset] == '|')||(expr[*offset] == '%')) { if (!checkAfterOp(expr,*offset)) throw(*offset); @@ -275,7 +321,7 @@ QString ArithmeticEvaluator::convertRecur(const QString& _expression, int *offse c = '1'; while ( (pile.isEmpty() == false) && (c != '(') && (c != '+') && (c != '-')) { c = pile.pop(); - if ( (c=='*') || (c == '/')) { + if ( (c=='*') || (c == '/') || (c == '|') || (c=='%')) { result.append(c).append(","); } else { @@ -375,7 +421,7 @@ QString ArithmeticEvaluator::getVariable(const QString& _expression, int offset, *size = 1; } - while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '-') || (_expression[i] == '_')) { + while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '_')) { number.append(_expression[i]); i += 1; *size += 1; @@ -433,6 +479,8 @@ bool ArithmeticEvaluator::checkAfterPar(const QString& _expression, int offset) else if (_expression[offset+1] == '-') return true; else if (_expression[offset+1] == '*') return true; else if (_expression[offset+1] == '/') return true; + else if (_expression[offset+1] == '|') return true; + else if (_expression[offset+1] == '%') return true; return false; }