mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[fix #11475] expressions: add left and right associavity for dump of binary operators
complete test for left associativity
This commit is contained in:
parent
0bf1135244
commit
a518e9f639
@ -378,6 +378,8 @@ class QgsExpression
|
||||
virtual void accept( QgsExpression::Visitor& v ) const;
|
||||
|
||||
int precedence() const;
|
||||
bool leftAssociative() const;
|
||||
bool rightAssociative() const;
|
||||
};
|
||||
|
||||
class NodeInOperator : QgsExpression::Node
|
||||
|
@ -2540,15 +2540,87 @@ int QgsExpression::NodeBinaryOperator::precedence() const
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool QgsExpression::NodeBinaryOperator::leftAssociative() const
|
||||
{
|
||||
// see left/right in qgsexpressionparser.yy
|
||||
switch ( mOp )
|
||||
{
|
||||
case boOr:
|
||||
case boAnd:
|
||||
case boEQ:
|
||||
case boNE:
|
||||
case boLE:
|
||||
case boGE:
|
||||
case boLT:
|
||||
case boGT:
|
||||
case boRegexp:
|
||||
case boLike:
|
||||
case boILike:
|
||||
case boNotLike:
|
||||
case boNotILike:
|
||||
case boIs:
|
||||
case boIsNot:
|
||||
case boPlus:
|
||||
case boMinus:
|
||||
case boMul:
|
||||
case boDiv:
|
||||
case boIntDiv:
|
||||
case boMod:
|
||||
case boConcat:
|
||||
return true;
|
||||
|
||||
case boPow:
|
||||
return false;
|
||||
}
|
||||
Q_ASSERT( 0 && "unexpected binary operator" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool QgsExpression::NodeBinaryOperator::rightAssociative() const
|
||||
{
|
||||
// see left/right in qgsexpressionparser.yy
|
||||
switch ( mOp )
|
||||
{
|
||||
case boOr:
|
||||
case boAnd:
|
||||
case boEQ:
|
||||
case boNE:
|
||||
case boLE:
|
||||
case boGE:
|
||||
case boLT:
|
||||
case boGT:
|
||||
case boRegexp:
|
||||
case boLike:
|
||||
case boILike:
|
||||
case boNotLike:
|
||||
case boNotILike:
|
||||
case boIs:
|
||||
case boIsNot:
|
||||
case boPlus:
|
||||
case boMul:
|
||||
case boMod:
|
||||
case boConcat:
|
||||
case boPow:
|
||||
return true;
|
||||
|
||||
case boMinus:
|
||||
case boDiv:
|
||||
case boIntDiv:
|
||||
return false;
|
||||
}
|
||||
Q_ASSERT( 0 && "unexpected binary operator" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString QgsExpression::NodeBinaryOperator::dump() const
|
||||
{
|
||||
QgsExpression::NodeBinaryOperator *lOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpLeft );
|
||||
QgsExpression::NodeBinaryOperator *rOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpRight );
|
||||
|
||||
QString fmt;
|
||||
fmt += lOp && lOp->precedence() < precedence() ? "(%1)" : "%1";
|
||||
fmt += lOp && ( lOp->precedence() < precedence() || !lOp->leftAssociative() ) ? "(%1)" : "%1";
|
||||
fmt += " %2 ";
|
||||
fmt += rOp && rOp->precedence() <= precedence() ? "(%3)" : "%3";
|
||||
fmt += rOp && ( rOp->precedence() < precedence() || !rOp->rightAssociative() ) ? "(%3)" : "%3";
|
||||
|
||||
return fmt.arg( mOpLeft->dump() ).arg( BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
|
||||
}
|
||||
|
@ -513,6 +513,8 @@ class CORE_EXPORT QgsExpression
|
||||
virtual void accept( Visitor& v ) const override { v.visit( *this ); }
|
||||
|
||||
int precedence() const;
|
||||
bool leftAssociative() const;
|
||||
bool rightAssociative() const;
|
||||
|
||||
protected:
|
||||
bool compare( double diff );
|
||||
|
@ -523,6 +523,9 @@ class TestQgsExpression: public QObject
|
||||
|
||||
QgsExpression e2( e1.dump() );
|
||||
QCOMPARE( e2.evaluate().toInt(), 21 );
|
||||
|
||||
QgsExpression e3( "(2^3)^2" );
|
||||
QCOMPARE( QgsExpression( e3.dump() ).evaluate().toInt(), 64 );
|
||||
}
|
||||
|
||||
void eval_columns()
|
||||
|
Loading…
x
Reference in New Issue
Block a user