From 2c0bc69f71a422a6ac10d34b7d965d0dd835a6cc Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Wed, 28 Sep 2022 19:32:17 +0200 Subject: Right precedence for ^ --- .../searchlib/rankingexpression/rule/OperationNode.java | 6 +++--- .../yahoo/searchlib/rankingexpression/rule/Operator.java | 15 +++++++-------- .../rankingexpression/evaluation/EvaluationTestCase.java | 1 + 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'searchlib') diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/OperationNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/OperationNode.java index d08e2270935..0512e1dad2f 100755 --- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/OperationNode.java +++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/OperationNode.java @@ -68,14 +68,14 @@ public final class OperationNode extends CompositeNode { */ private boolean nonDefaultPrecedence(CompositeNode parent) { if ( parent == null) return false; - if ( ! (parent instanceof OperationNode arithmeticParent)) return false; + if ( ! (parent instanceof OperationNode operationParent)) return false; // The line below can only be correct in both only have one operator. // Getting this correct is impossible without more work. // So for now we only handle the simple case correctly, and use a safe approach by adding // extra parenthesis just in case.... - return arithmeticParent.operators.get(0).hasPrecedenceOver(this.operators.get(0)) - || ((arithmeticParent.operators.size() > 1) || (operators.size() > 1)); + return operationParent.operators.get(0).hasPrecedenceOver(this.operators.get(0)) + || ((operationParent.operators.size() > 1) || (operators.size() > 1)); } @Override diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/Operator.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/Operator.java index 63144f0ef4a..02af88b2c58 100644 --- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/Operator.java +++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/Operator.java @@ -35,27 +35,26 @@ public enum Operator { public static final List operatorsByPrecedence = Arrays.stream(Operator.values()).toList(); private final String image; - private final boolean bindsRight; // TODO: Implement + private final boolean rightPrecedence; private final BiFunction function; Operator(String image, BiFunction function) { this(image, false, function); } - Operator(String image, boolean bindsRight, BiFunction function) { + Operator(String image, boolean rightPrecedence, BiFunction function) { this.image = image; - this.bindsRight = bindsRight; + this.rightPrecedence = rightPrecedence; this.function = function; } /** Returns true if this operator has precedence over the given operator */ - public boolean hasPrecedenceOver(Operator op) { - return operatorsByPrecedence.indexOf(this) > operatorsByPrecedence.indexOf(op); + public boolean hasPrecedenceOver(Operator other) { + if (operatorsByPrecedence.indexOf(this) == operatorsByPrecedence.indexOf(other)) + return rightPrecedence; + return operatorsByPrecedence.indexOf(this) > operatorsByPrecedence.indexOf(other); } - /** Returns true if a sequence of these operations should be evaluated from right to left rather than left to right. */ - public boolean bindsRight() { return bindsRight; } - public final Value evaluate(Value x, Value y) { return function.apply(x, y); } diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java index dac7393a168..2986c8b8808 100644 --- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java +++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java @@ -88,6 +88,7 @@ public class EvaluationTestCase { tester.assertEvaluates(10.0, "3 ^ 2 + 1"); tester.assertEvaluates(18.0, "2 * 3 ^ 2"); tester.assertEvaluates(-4, "1 - 2 - 3"); // Means 1 + -2 + -3 + tester.assertEvaluates(Math.pow(4, 9), "4^3^2"); // Right precedence, by 51% majority // Conditionals tester.assertEvaluates(2 * (3 * 4 + 3) * (4 * 5 - 4 * 200) / 10, "2*(3*4+3)*(4*5-4*200)/10"); -- cgit v1.2.3