-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add basic operator support to arithmetic and string expressions #2726
Conversation
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
@@ -17,16 +17,28 @@ expression | |||
; | |||
|
|||
stringExpression | |||
: function | |||
: stringExpression DOT stringExpression |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we not able to reuse +
for both strings and arithmetic?
…ectly Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
| arithmeticTerm | ||
; | ||
|
||
arithmeticTerm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you call this a term?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got the following grammar from googling
<Exp> ::= <Exp> + <Term> |
<Exp> - <Term> |
<Term>
<Term> ::= <Term> * <Factor> |
<Term> / <Factor> |
<Factor>
<Factor> ::= x | y | ... |
( <Exp> ) |
- <Factor>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should probably find another name. A term is more generic than two numbers multiplied together.
https://simple.wikipedia.org/wiki/Term_(mathematics)
There might be better names, but perhaps you can split this into a "factor term" and a "summed term?"
@@ -8,7 +8,9 @@ | |||
import org.antlr.v4.runtime.RuleContext; | |||
|
|||
interface Operator<T> { | |||
int getNumberOfOperands(); | |||
default int getNumberOfOperands(final RuleContext ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I like this.
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
Codecov Report
@@ Coverage Diff @@
## main #2726 +/- ##
============================================
+ Coverage 93.60% 94.11% +0.50%
- Complexity 2270 2439 +169
============================================
Files 264 278 +14
Lines 6337 6744 +407
Branches 528 550 +22
============================================
+ Hits 5932 6347 +415
+ Misses 266 257 -9
- Partials 139 140 +1
|
@@ -18,11 +18,6 @@ protected BinaryOperator(final int symbol, final int shouldEvaluateRuleIndex) { | |||
displayName = DataPrepperExpressionParser.VOCABULARY.getDisplayName(symbol); | |||
} | |||
|
|||
@Override | |||
public int getNumberOfOperands() { | |||
return NUMBER_OF_OPERANDS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove line 9 in this file now.
We should leverage a single source of truth for a class. The evaluate method uses a hardcoded number to enforce the number of operands. Can we update the evaluate
method to leverage the default method now as well?
Map.of( | ||
Integer.class, (lhs, rhs) -> (double)lhs / (double)(int)rhs, | ||
Float.class, (lhs, rhs) -> (double)lhs / (Float) rhs, | ||
Long.class, (lhs, rhs) -> (double)lhs / (double)(long)rhs, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the lhs
cast to only a double where the rhs
is cast to a long
and then a double
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because LHS is always double (final Map<Class<? extends Number>, BiFunction<Object, Object, Number>> doubleOperations
) and RHS has entries for 4 different types.
if (expectedClass == null) { | ||
assertThrows(ExpressionEvaluationException.class, () -> evaluator.evaluate(expression, event)); | ||
} else { | ||
Object result = evaluator.evaluate(expression, event); | ||
assertThat(result, not(instanceOf(expectedClass))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should separate out these tests. These are two separate behaviors that should be handled separately.
docs/expression_syntax.md
Outdated
| 3 | `*`, `/` | Multiple and Divison Operators | left-to-right | | ||
| 2 | `==`, `!=` | Equality Operators | left-to-right | | ||
| 2 | `+`, `-` | Addition and Subtraction Operators | left-to-right | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we place these operations on separate levels from the the relational and equality operators? I believe we need to evaluate these operators before we can compare relataional or equality operators.
At the moment according to this documentation the following statement would result in an error with the current priority order: 2 + 4 > 5
Please confirm the priority order for these new operators and the behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes do not support expressions like 2 + 4 > 5
for now. It is a relatively simple change from here but did not include it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we don't support that expression type right now the documentation is miss leading and violates the standard order of operations. We need to correct this.
| `==`, `!=` | Equality Operators | No | `/status == 200`<br>`/status_code==200` | | | ||
| `and`, `or`, `not` | Conditional Operators | Yes | `/a<300 and /b>200` | `/b<300and/b>200` | | ||
| `,` | Set Value Delimiter | No | `/a in {200, 202}`<br>`/a in {200,202}`<br>`/a in {200 , 202}` | `/a in {200,}` | | ||
| `+`, `-` | Add and Subtract Operators | No | `/status_code + length(/message) - 2` | | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we indicate +
support concatenation as well?
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
| arithmeticFactor | ||
; | ||
|
||
arithmeticFactor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might this be the arithmeticTerm
?
Then what you have as arithmeticTerm
could be an arithmeticFactor
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This page for the C grammar calls these "multiplicative_expression" and "additive_expression".
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Looks great!
Description
Adds support for basic operators to arithmetic and string expressions.
Arithmetic operators supported are
+, -, *, /
Some example arithmetic expressions supported with this change are
/key1 + /key2 +5
length(/message) - getMetadata("attr") + 10
10.2 + 20 * 6.5
(10 + 20) * 6
String operator supported
+
for concatenation.Example expressions with string concatenation operator
/key1 + /key2
/message + "suffix"
getMetadata("attr") + /message
Resolves #2685 #2686
Issues Resolved
Resolves #2685 #2686
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.