Skip to content

Commit a518e9f

Browse files
3nidsm-kuhn
authored andcommittedJun 16, 2015
[fix #11475] expressions: add left and right associavity for dump of binary operators
complete test for left associativity
1 parent 0bf1135 commit a518e9f

File tree

4 files changed

+81
-2
lines changed

4 files changed

+81
-2
lines changed
 

‎python/core/qgsexpression.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ class QgsExpression
378378
virtual void accept( QgsExpression::Visitor& v ) const;
379379

380380
int precedence() const;
381+
bool leftAssociative() const;
382+
bool rightAssociative() const;
381383
};
382384

383385
class NodeInOperator : QgsExpression::Node

‎src/core/qgsexpression.cpp

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,15 +2540,87 @@ int QgsExpression::NodeBinaryOperator::precedence() const
25402540
return -1;
25412541
}
25422542

2543+
bool QgsExpression::NodeBinaryOperator::leftAssociative() const
2544+
{
2545+
// see left/right in qgsexpressionparser.yy
2546+
switch ( mOp )
2547+
{
2548+
case boOr:
2549+
case boAnd:
2550+
case boEQ:
2551+
case boNE:
2552+
case boLE:
2553+
case boGE:
2554+
case boLT:
2555+
case boGT:
2556+
case boRegexp:
2557+
case boLike:
2558+
case boILike:
2559+
case boNotLike:
2560+
case boNotILike:
2561+
case boIs:
2562+
case boIsNot:
2563+
case boPlus:
2564+
case boMinus:
2565+
case boMul:
2566+
case boDiv:
2567+
case boIntDiv:
2568+
case boMod:
2569+
case boConcat:
2570+
return true;
2571+
2572+
case boPow:
2573+
return false;
2574+
}
2575+
Q_ASSERT( 0 && "unexpected binary operator" );
2576+
return -1;
2577+
}
2578+
2579+
bool QgsExpression::NodeBinaryOperator::rightAssociative() const
2580+
{
2581+
// see left/right in qgsexpressionparser.yy
2582+
switch ( mOp )
2583+
{
2584+
case boOr:
2585+
case boAnd:
2586+
case boEQ:
2587+
case boNE:
2588+
case boLE:
2589+
case boGE:
2590+
case boLT:
2591+
case boGT:
2592+
case boRegexp:
2593+
case boLike:
2594+
case boILike:
2595+
case boNotLike:
2596+
case boNotILike:
2597+
case boIs:
2598+
case boIsNot:
2599+
case boPlus:
2600+
case boMul:
2601+
case boMod:
2602+
case boConcat:
2603+
case boPow:
2604+
return true;
2605+
2606+
case boMinus:
2607+
case boDiv:
2608+
case boIntDiv:
2609+
return false;
2610+
}
2611+
Q_ASSERT( 0 && "unexpected binary operator" );
2612+
return -1;
2613+
}
2614+
25432615
QString QgsExpression::NodeBinaryOperator::dump() const
25442616
{
25452617
QgsExpression::NodeBinaryOperator *lOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpLeft );
25462618
QgsExpression::NodeBinaryOperator *rOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpRight );
25472619

25482620
QString fmt;
2549-
fmt += lOp && lOp->precedence() < precedence() ? "(%1)" : "%1";
2621+
fmt += lOp && ( lOp->precedence() < precedence() || !lOp->leftAssociative() ) ? "(%1)" : "%1";
25502622
fmt += " %2 ";
2551-
fmt += rOp && rOp->precedence() <= precedence() ? "(%3)" : "%3";
2623+
fmt += rOp && ( rOp->precedence() < precedence() || !rOp->rightAssociative() ) ? "(%3)" : "%3";
25522624

25532625
return fmt.arg( mOpLeft->dump() ).arg( BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
25542626
}

‎src/core/qgsexpression.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ class CORE_EXPORT QgsExpression
513513
virtual void accept( Visitor& v ) const override { v.visit( *this ); }
514514

515515
int precedence() const;
516+
bool leftAssociative() const;
517+
bool rightAssociative() const;
516518

517519
protected:
518520
bool compare( double diff );

‎tests/src/core/testqgsexpression.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,9 @@ class TestQgsExpression: public QObject
523523

524524
QgsExpression e2( e1.dump() );
525525
QCOMPARE( e2.evaluate().toInt(), 21 );
526+
527+
QgsExpression e3( "(2^3)^2" );
528+
QCOMPARE( QgsExpression( e3.dump() ).evaluate().toInt(), 64 );
526529
}
527530

528531
void eval_columns()

0 commit comments

Comments
 (0)
Please sign in to comment.