Expressions: Simpified parser, fixed precedence (parentheses)

This commit is contained in:
Eivind Kvedalen
2016-03-26 22:55:10 +01:00
committed by wmayer
parent 97aa0a1c6d
commit 4f7470c5e8
4 changed files with 442 additions and 412 deletions

View File

@@ -452,19 +452,33 @@ Expression *OperatorExpression::simplify() const
std::string OperatorExpression::toString() const
{
std::stringstream s;
bool needsParens;
Operator leftOperator(NONE), rightOperator(NONE);
switch (op) {
case NEG:
s << "-";
break;
s << "-" << left->toString();
return s.str();
case POS:
s << "+";
break;
s << "+" << left->toString();
return s.str();
default:
break;
}
if (left->priority() < priority())
needsParens = false;
if (freecad_dynamic_cast<OperatorExpression>(left))
leftOperator = static_cast<OperatorExpression*>(left)->op;
if (left->priority() < priority()) // Check on operator priority first
needsParens = true;
else if (leftOperator == op) { // Equal priority?
if (!isLeftAssociative())
needsParens = true;
//else if (!isCommutative())
// needsParens = true;
}
if (needsParens)
s << "(" << left->toString() << ")";
else
s << left->toString();
@@ -505,14 +519,23 @@ std::string OperatorExpression::toString() const
break;
case UNIT:
break;
case POS:
case NEG:
return s.str();
default:
assert(0);
}
if (right->priority() < priority())
needsParens = false;
if (freecad_dynamic_cast<OperatorExpression>(right))
rightOperator = static_cast<OperatorExpression*>(right)->op;
if (right->priority() < priority()) // Check on operator priority first
needsParens = true;
else if (rightOperator == op) { // Equal priority?
if (!isRightAssociative())
needsParens = true;
else if (!isCommutative())
needsParens = true;
}
if (needsParens)
s << "(" << right->toString() << ")";
else
s << right->toString();
@@ -585,6 +608,35 @@ void OperatorExpression::visit(ExpressionVisitor &v)
v.visit(this);
}
bool OperatorExpression::isCommutative() const
{
switch (op) {
case EQ:
case NEQ:
case ADD:
case MUL:
return true;
default:
return false;
}
}
bool OperatorExpression::isLeftAssociative() const
{
return true;
}
bool OperatorExpression::isRightAssociative() const
{
switch (op) {
case ADD:
case MUL:
return true;
default:
return false;
}
}
//
// FunctionExpression class. This class handles functions with one or two parameters.
//