File tree Expand file tree Collapse file tree 4 files changed +81
-2
lines changed Expand file tree Collapse file tree 4 files changed +81
-2
lines changed Original file line number Diff line number Diff line change @@ -378,6 +378,8 @@ class QgsExpression
378
378
virtual void accept( QgsExpression::Visitor& v ) const;
379
379
380
380
int precedence() const;
381
+ bool leftAssociative() const;
382
+ bool rightAssociative() const;
381
383
};
382
384
383
385
class NodeInOperator : QgsExpression::Node
Original file line number Diff line number Diff line change @@ -2540,15 +2540,87 @@ int QgsExpression::NodeBinaryOperator::precedence() const
2540
2540
return -1 ;
2541
2541
}
2542
2542
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
+
2543
2615
QString QgsExpression::NodeBinaryOperator::dump () const
2544
2616
{
2545
2617
QgsExpression::NodeBinaryOperator *lOp = dynamic_cast <QgsExpression::NodeBinaryOperator *>( mOpLeft );
2546
2618
QgsExpression::NodeBinaryOperator *rOp = dynamic_cast <QgsExpression::NodeBinaryOperator *>( mOpRight );
2547
2619
2548
2620
QString fmt;
2549
- fmt += lOp && lOp->precedence () < precedence () ? " (%1)" : " %1" ;
2621
+ fmt += lOp && ( lOp->precedence () < precedence () || !lOp-> leftAssociative () ) ? " (%1)" : " %1" ;
2550
2622
fmt += " %2 " ;
2551
- fmt += rOp && rOp->precedence () <= precedence () ? " (%3)" : " %3" ;
2623
+ fmt += rOp && ( rOp->precedence () < precedence () || !rOp-> rightAssociative () ) ? " (%3)" : " %3" ;
2552
2624
2553
2625
return fmt.arg ( mOpLeft ->dump () ).arg ( BinaryOperatorText[mOp ] ).arg ( mOpRight ->dump () );
2554
2626
}
Original file line number Diff line number Diff line change @@ -513,6 +513,8 @@ class CORE_EXPORT QgsExpression
513
513
virtual void accept ( Visitor& v ) const override { v.visit ( *this ); }
514
514
515
515
int precedence () const ;
516
+ bool leftAssociative () const ;
517
+ bool rightAssociative () const ;
516
518
517
519
protected:
518
520
bool compare ( double diff );
Original file line number Diff line number Diff line change @@ -523,6 +523,9 @@ class TestQgsExpression: public QObject
523
523
524
524
QgsExpression e2 ( e1 .dump () );
525
525
QCOMPARE ( e2 .evaluate ().toInt (), 21 );
526
+
527
+ QgsExpression e3 ( " (2^3)^2" );
528
+ QCOMPARE ( QgsExpression ( e3 .dump () ).evaluate ().toInt (), 64 );
526
529
}
527
530
528
531
void eval_columns ()
You can’t perform that action at this time.
0 commit comments