METRON-980: Short circuit operations for Stellar closes apache/metron#606
Project: http://git-wip-us.apache.org/repos/asf/metron/repo Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/30d0e2a6 Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/30d0e2a6 Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/30d0e2a6 Branch: refs/heads/master Commit: 30d0e2a6faa1c1205522758e5fd15f35ebc9fcbb Parents: 7d6121b Author: cstella <ceste...@gmail.com> Authored: Fri Jun 9 11:48:27 2017 -0400 Committer: cstella <ceste...@gmail.com> Committed: Fri Jun 9 11:48:27 2017 -0400 ---------------------------------------------------------------------- .../profiler/client/window/WindowProcessor.java | 2 +- metron-platform/metron-common/README.md | 1 + .../metron/common/stellar/generated/Stellar.g4 | 16 +- .../org/apache/metron/common/dsl/Token.java | 14 + .../common/stellar/BaseStellarProcessor.java | 1 + .../metron/common/stellar/FrameContext.java | 45 ++ .../metron/common/stellar/StellarCompiler.java | 287 +++++-- .../stellar/evaluators/ArithmeticEvaluator.java | 42 +- ...mparisonExpressionWithOperatorEvaluator.java | 9 +- .../evaluators/DoubleLiteralEvaluator.java | 5 +- .../evaluators/FloatLiteralEvaluator.java | 5 +- .../stellar/evaluators/IntLiteralEvaluator.java | 5 +- .../evaluators/LongLiteralEvaluator.java | 5 +- .../stellar/evaluators/NumberEvaluator.java | 3 +- .../evaluators/NumberLiteralEvaluator.java | 8 +- .../stellar/generated/StellarBaseListener.java | 36 + .../stellar/generated/StellarListener.java | 30 + .../common/stellar/generated/StellarParser.java | 774 +++++++++++-------- .../dsl/functions/FunctionalFunctionsTest.java | 17 + .../common/stellar/StellarInterpreterTest.java | 24 +- .../metron/common/stellar/StellarTest.java | 101 ++- .../evaluators/ArithmeticEvaluatorTest.java | 58 +- ...isonExpressionWithOperatorEvaluatorTest.java | 10 +- .../evaluators/DoubleLiteralEvaluatorTest.java | 8 +- .../evaluators/FloatLiteralEvaluatorTest.java | 8 +- .../evaluators/IntLiteralEvaluatorTest.java | 8 +- .../evaluators/LongLiteralEvaluatorTest.java | 8 +- .../evaluators/NumberLiteralEvaluatorTest.java | 18 +- 28 files changed, 1029 insertions(+), 519 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/window/WindowProcessor.java ---------------------------------------------------------------------- diff --git a/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/window/WindowProcessor.java b/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/window/WindowProcessor.java index 16a7513..1ae4aaf 100644 --- a/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/window/WindowProcessor.java +++ b/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/window/WindowProcessor.java @@ -89,7 +89,7 @@ public class WindowProcessor extends WindowBaseListener { if(checkForException(ctx)) { return; } - stack.push(new Token<>(ctx.getText().substring(1), String.class)); + stack.push(new Token<>(ctx.getText().substring(1), String.class )); } /** http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/README.md ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/README.md b/metron-platform/metron-common/README.md index 9e1de7a..95f59ba 100644 --- a/metron-platform/metron-common/README.md +++ b/metron-platform/metron-common/README.md @@ -26,6 +26,7 @@ The query language supports the following: * The literal `"\"foo\""` would represent `"foo"` * The literal `'foo \\ bar'` would represent `foo \ bar` * Simple boolean operations: `and`, `not`, `or` + * Boolean expressions are short-circuited (e.g. `true or FUNC()` would never execute `FUNC`) * Simple arithmetic operations: `*`, `/`, `+`, `-` on real numbers or integers * Simple comparison operations `<`, `>`, `<=`, `>=` * Simple equality comparison operations `==`, `!=` http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4 ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4 b/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4 index 8602fde..3577377 100644 --- a/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4 +++ b/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4 @@ -139,9 +139,21 @@ transformation_expr: | in_expr #InExpression ; +if_expr: + logical_expr + ; + +then_expr: + transformation_expr + ; + +else_expr: + transformation_expr + ; + conditional_expr : - logical_expr QUESTION transformation_expr COLON transformation_expr #TernaryFuncWithoutIf - | IF logical_expr THEN transformation_expr ELSE transformation_expr #TernaryFuncWithIf + if_expr QUESTION then_expr COLON else_expr #TernaryFuncWithoutIf + | IF if_expr THEN then_expr ELSE else_expr #TernaryFuncWithIf ; logical_expr: http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/Token.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/Token.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/Token.java index 4c94be0..cf168a4 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/Token.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/Token.java @@ -18,13 +18,27 @@ package org.apache.metron.common.dsl; +import org.apache.metron.common.stellar.FrameContext; + public class Token<T> { T value; Class<T> underlyingType; + FrameContext.Context multiArgContext; + public Token(T value, Class<T> clazz) { + this(value, clazz, null); + } + + public Token(T value, Class<T> clazz, FrameContext.Context multiArgContext) { this.value = value; this.underlyingType = clazz; + this.multiArgContext = multiArgContext; } + + public FrameContext.Context getMultiArgContext() { + return multiArgContext; + } + public T getValue() { return value; } http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java index 8f4af93..5bf4a64 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java @@ -24,6 +24,7 @@ import com.google.common.cache.CacheLoader; import com.google.common.util.concurrent.UncheckedExecutionException; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.TokenStream; import java.util.HashSet; http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/FrameContext.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/FrameContext.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/FrameContext.java new file mode 100644 index 0000000..16bc07a --- /dev/null +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/FrameContext.java @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.metron.common.stellar; + +public enum FrameContext { + BOOLEAN_AND, + BOOLEAN_OR; + + public static class Context { + private FrameContext variety; + public Context(FrameContext variety) { + this.variety = variety; + } + + public FrameContext getVariety() { + return variety; + } + + @Override + public String toString() { + return "Context{" + + "variety=" + variety + + '}'; + } + } + + public Context create() { + return new Context(this); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java index b289f48..136728d 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java @@ -48,6 +48,15 @@ public class StellarCompiler extends StellarBaseListener { private final NumberLiteralEvaluator numberLiteralEvaluator; private final ComparisonExpressionWithOperatorEvaluator comparisonExpressionWithOperatorEvaluator; + public interface ShortCircuitOp {} + + public static class ShortCircuitFrame {} + public static class BooleanArg implements ShortCircuitOp {} + public static class IfExpr implements ShortCircuitOp {} + public static class ThenExpr implements ShortCircuitOp {} + public static class ElseExpr implements ShortCircuitOp {} + public static class EndConditional implements ShortCircuitOp {} + public static class ExpressionState { Context context; FunctionResolver functionResolver; @@ -64,10 +73,18 @@ public class StellarCompiler extends StellarBaseListener { public static class Expression implements Serializable { final Deque<Token<?>> tokenDeque; + final Deque<FrameContext.Context> multiArgumentState; final Set<String> variablesUsed; public Expression(Deque<Token<?>> tokenDeque) { this.tokenDeque = tokenDeque; this.variablesUsed = new HashSet<>(); + this.multiArgumentState = new ArrayDeque<>(); + } + + public void clear() { + tokenDeque.clear(); + variablesUsed.clear(); + multiArgumentState.clear(); } public Deque<Token<?>> getTokenDeque() { @@ -76,14 +93,77 @@ public class StellarCompiler extends StellarBaseListener { public Object apply(ExpressionState state) { Deque<Token<?>> instanceDeque = new ArrayDeque<>(); - for(Iterator<Token<?>> it = getTokenDeque().descendingIterator();it.hasNext();) { - Token<?> token = it.next(); - if(token.getUnderlyingType() == DeferredFunction.class) { - DeferredFunction func = (DeferredFunction) token.getValue(); - func.apply(instanceDeque, state); - } - else { - instanceDeque.push(token); + { + boolean skipElse = false; + Token<?> token = null; + for (Iterator<Token<?>> it = getTokenDeque().descendingIterator(); it.hasNext(); ) { + token = it.next(); + //if we've skipped an else previously, then we need to skip the deferred tokens associated with the else. + if(skipElse && token.getUnderlyingType() == ElseExpr.class) { + while(it.hasNext()) { + token = it.next(); + if(token.getUnderlyingType() == EndConditional.class) { + break; + } + } + skipElse = false; + } + /* + curr is the current value on the stack. This is the non-deferred actual evaluation for this expression + and with the current context. + */ + Token<?> curr = instanceDeque.peek(); + if( curr != null + && curr.getValue() != null && curr.getValue() instanceof Boolean + && ShortCircuitOp.class.isAssignableFrom(token.getUnderlyingType()) + ) { + //if we have a boolean as the current value and the next non-contextual token is a short circuit op + //then we need to short circuit possibly + if(token.getUnderlyingType() == BooleanArg.class) { + if (curr.getMultiArgContext() != null + && curr.getMultiArgContext().getVariety() == FrameContext.BOOLEAN_OR + && (Boolean) (curr.getValue()) + ) { + //short circuit the or + FrameContext.Context context = curr.getMultiArgContext(); + shortCircuit(it, context); + } else if (curr.getMultiArgContext() != null + && curr.getMultiArgContext().getVariety() == FrameContext.BOOLEAN_AND + && !(Boolean) (curr.getValue()) + ) { + //short circuit the and + FrameContext.Context context = curr.getMultiArgContext(); + shortCircuit(it, context); + } + } + else if(token.getUnderlyingType() == IfExpr.class) { + //short circuit the if/then/else + instanceDeque.pop(); + if((Boolean)curr.getValue()) { + //choose then + skipElse = true; + } + else { + //choose else + while(it.hasNext()) { + Token<?> t = it.next(); + if(t.getUnderlyingType() == ElseExpr.class) { + break; + } + } + } + } + } + if (token.getUnderlyingType() == DeferredFunction.class) { + DeferredFunction func = (DeferredFunction) token.getValue(); + func.apply(instanceDeque, state); + } + else if(token.getUnderlyingType() != ShortCircuitFrame.class + && !ShortCircuitOp.class.isAssignableFrom(token.getUnderlyingType()) + ) { + instanceDeque.push(token); + } + } } @@ -100,6 +180,15 @@ public class StellarCompiler extends StellarBaseListener { throw new ParseException("Invalid parse, found " + token); } } + + public void shortCircuit(Iterator<Token<?>> it, FrameContext.Context context) { + while (it.hasNext()) { + Token<?> token = it.next(); + if (token.getUnderlyingType() == ShortCircuitFrame.class && token.getMultiArgContext() == context) { + break; + } + } + } } interface DeferredFunction { @@ -130,7 +219,7 @@ public class StellarCompiler extends StellarBaseListener { @Override public void enterTransformation(StellarParser.TransformationContext ctx) { - expression.tokenDeque.clear(); + expression.clear(); } private boolean handleIn(final Token<?> left, final Token<?> right) { @@ -162,39 +251,43 @@ public class StellarCompiler extends StellarBaseListener { @Override public void exitNullConst(StellarParser.NullConstContext ctx) { - expression.tokenDeque.push(new Token<>(null, Object.class)); + expression.tokenDeque.push(new Token<>(null, Object.class, getArgContext())); } @Override public void exitArithExpr_plus(StellarParser.ArithExpr_plusContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>((tokenDeque, state) -> { Pair<Token<? extends Number>, Token<? extends Number>> p = getArithExpressionPair(tokenDeque); - tokenDeque.push(arithmeticEvaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.addition(), p)); - }, DeferredFunction.class)); + tokenDeque.push(arithmeticEvaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.addition(context), p)); + }, DeferredFunction.class, context)); } @Override public void exitArithExpr_minus(StellarParser.ArithExpr_minusContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { Pair<Token<? extends Number>, Token<? extends Number>> p = getArithExpressionPair(tokenDeque); - tokenDeque.push(arithmeticEvaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.subtraction(), p)); - }, DeferredFunction.class)); + tokenDeque.push(arithmeticEvaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.subtraction(context), p)); + }, DeferredFunction.class, context)); } @Override public void exitArithExpr_div(StellarParser.ArithExpr_divContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { Pair<Token<? extends Number>, Token<? extends Number>> p = getArithExpressionPair(tokenDeque); - tokenDeque.push(arithmeticEvaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.division(), p)); - }, DeferredFunction.class)); + tokenDeque.push(arithmeticEvaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.division(context), p)); + }, DeferredFunction.class, context)); } @Override public void exitArithExpr_mul(StellarParser.ArithExpr_mulContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { Pair<Token<? extends Number>, Token<? extends Number>> p = getArithExpressionPair(tokenDeque); - tokenDeque.push(arithmeticEvaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.multiplication(), p)); - }, DeferredFunction.class)); + tokenDeque.push(arithmeticEvaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.multiplication(context), p)); + }, DeferredFunction.class, context)); } @SuppressWarnings("unchecked") @@ -204,61 +297,62 @@ public class StellarCompiler extends StellarBaseListener { return Pair.of(left, right); } - private void handleConditional() { - expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { - Token<?> elseExpr = popDeque(tokenDeque); - Token<?> thenExpr = popDeque(tokenDeque); - Token<?> ifExpr = popDeque(tokenDeque); - @SuppressWarnings("unchecked") boolean b = ((Token<Boolean>) ifExpr).getValue(); - if (b) { - tokenDeque.push(thenExpr); - } else { - tokenDeque.push(elseExpr); - } - }, DeferredFunction.class)); + @Override + public void exitIf_expr(StellarParser.If_exprContext ctx) { + expression.tokenDeque.push(new Token<>(new IfExpr(), IfExpr.class, getArgContext())); } @Override - public void exitTernaryFuncWithoutIf(StellarParser.TernaryFuncWithoutIfContext ctx) { - handleConditional(); + public void enterThen_expr(StellarParser.Then_exprContext ctx) { + expression.tokenDeque.push(new Token<>(new ThenExpr(), ThenExpr.class, getArgContext())); } @Override - public void exitTernaryFuncWithIf(StellarParser.TernaryFuncWithIfContext ctx) { - handleConditional(); + public void enterElse_expr(StellarParser.Else_exprContext ctx) { + expression.tokenDeque.push(new Token<>(new ElseExpr(), ElseExpr.class, getArgContext())); + } + + @Override + public void exitElse_expr(StellarParser.Else_exprContext ctx) { + expression.tokenDeque.push(new Token<>(new EndConditional(), EndConditional.class, getArgContext())); } @Override public void exitInExpressionStatement(StellarParser.InExpressionStatementContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { Token<?> left = popDeque(tokenDeque); Token<?> right = popDeque(tokenDeque); - tokenDeque.push(new Token<>(handleIn(left, right), Boolean.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(handleIn(left, right), Boolean.class, context)); + }, DeferredFunction.class, context)); } + @Override public void exitNInExpressionStatement(StellarParser.NInExpressionStatementContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { Token<?> left = popDeque(tokenDeque); Token<?> right = popDeque(tokenDeque); - tokenDeque.push(new Token<>(!handleIn(left, right), Boolean.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(!handleIn(left, right), Boolean.class, context)); + }, DeferredFunction.class, context)); } @Override public void exitNotFunc(StellarParser.NotFuncContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { Token<Boolean> arg = (Token<Boolean>) popDeque(tokenDeque); - tokenDeque.push(new Token<>(!arg.getValue(), Boolean.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(!arg.getValue(), Boolean.class, context)); + }, DeferredFunction.class, context)); } @Override public void exitVariable(StellarParser.VariableContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { - tokenDeque.push(new Token<>(state.variableResolver.resolve(ctx.getText()), Object.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(state.variableResolver.resolve(ctx.getText()), Object.class, context)); + }, DeferredFunction.class, context)); expression.variablesUsed.add(ctx.getText()); } @@ -266,46 +360,77 @@ public class StellarCompiler extends StellarBaseListener { public void exitStringLiteral(StellarParser.StringLiteralContext ctx) { String rawToken = ctx.getText(); String literal = StringEscapeUtils.UNESCAPE_JSON.translate(rawToken); - expression.tokenDeque.push(new Token<>(literal.substring(1, literal.length()-1), String.class)); + expression.tokenDeque.push(new Token<>(literal.substring(1, literal.length()-1), String.class, getArgContext())); } @Override public void exitIntLiteral(StellarParser.IntLiteralContext ctx) { - expression.tokenDeque.push(numberLiteralEvaluator.evaluate(ctx)); + expression.tokenDeque.push(numberLiteralEvaluator.evaluate(ctx, getArgContext())); } @Override public void exitDoubleLiteral(StellarParser.DoubleLiteralContext ctx) { - expression.tokenDeque.push(numberLiteralEvaluator.evaluate(ctx)); + expression.tokenDeque.push(numberLiteralEvaluator.evaluate(ctx, getArgContext())); } @Override public void exitFloatLiteral(StellarParser.FloatLiteralContext ctx) { - expression.tokenDeque.push(numberLiteralEvaluator.evaluate(ctx)); + expression.tokenDeque.push(numberLiteralEvaluator.evaluate(ctx, getArgContext())); } @Override public void exitLongLiteral(StellarParser.LongLiteralContext ctx) { - expression.tokenDeque.push(numberLiteralEvaluator.evaluate(ctx)); + expression.tokenDeque.push(numberLiteralEvaluator.evaluate(ctx, getArgContext())); + } + + @Override + public void enterB_expr(StellarParser.B_exprContext ctx) { + //Enter is not guaranteed to be called by Antlr for logical labels, so we need to + //emulate it like this. See https://github.com/antlr/antlr4/issues/802 + if(ctx.getParent() instanceof StellarParser.LogicalExpressionOrContext) { + expression.multiArgumentState.push(FrameContext.BOOLEAN_OR.create()); + } + else if(ctx.getParent() instanceof StellarParser.LogicalExpressionAndContext) { + expression.multiArgumentState.push(FrameContext.BOOLEAN_AND.create()); + } + } + + @Override + public void exitB_expr(StellarParser.B_exprContext ctx) { + if(ctx.getParent() instanceof StellarParser.LogicalExpressionOrContext + || ctx.getParent() instanceof StellarParser.LogicalExpressionAndContext + ) + { + //we want to know when the argument to the boolean expression is complete + expression.tokenDeque.push(new Token<>(new BooleanArg(), BooleanArg.class, getArgContext())); + } } @Override public void exitLogicalExpressionAnd(StellarParser.LogicalExpressionAndContext ctx) { + final FrameContext.Context context = getArgContext(); + popArgContext(); + final FrameContext.Context parentContext = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { Token<?> left = popDeque(tokenDeque); Token<?> right = popDeque(tokenDeque); - tokenDeque.push(new Token<>(booleanOp(left, right, (l, r) -> l && r, "&&"), Boolean.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(booleanOp(left, right, (l, r) -> l && r, "&&"), Boolean.class, parentContext)); + }, DeferredFunction.class, context)); + expression.tokenDeque.push(new Token<>(new ShortCircuitFrame(), ShortCircuitFrame.class, context)); } @Override public void exitLogicalExpressionOr(StellarParser.LogicalExpressionOrContext ctx) { + final FrameContext.Context context = getArgContext(); + popArgContext(); + final FrameContext.Context parentContext = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { Token<?> left = popDeque(tokenDeque); Token<?> right = popDeque(tokenDeque); - tokenDeque.push(new Token<>(booleanOp(left, right, (l, r) -> l || r, "||"), Boolean.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(booleanOp(left, right, (l, r) -> l || r, "||"), Boolean.class, parentContext)); + }, DeferredFunction.class, context)); + expression.tokenDeque.push(new Token<>(new ShortCircuitFrame(), ShortCircuitFrame.class, context)); } @Override @@ -321,7 +446,7 @@ public class StellarCompiler extends StellarBaseListener { default: throw new ParseException("Unable to process " + ctx.getText() + " as a boolean constant"); } - expression.tokenDeque.push(new Token<>(b, Boolean.class)); + expression.tokenDeque.push(new Token<>(b, Boolean.class, getArgContext())); } private boolean booleanOp(final Token<?> left, final Token<?> right, final BooleanOp op, final String opName) { @@ -356,7 +481,7 @@ public class StellarCompiler extends StellarBaseListener { @Override public void exitLambda_variable(StellarParser.Lambda_variableContext ctx) { - expression.tokenDeque.push(new Token<>(ctx.getText(), String.class)); + expression.tokenDeque.push(new Token<>(ctx.getText(), String.class, getArgContext())); } private void enterLambdaVariables() { @@ -369,7 +494,7 @@ public class StellarCompiler extends StellarBaseListener { for(; !expression.tokenDeque.isEmpty() && t != LAMBDA_VARIABLES; t = expression.tokenDeque.pop()) { variables.addFirst(t.getValue().toString()); } - expression.tokenDeque.push(new Token<>(variables, List.class)); + expression.tokenDeque.push(new Token<>(variables, List.class, getArgContext())); } private void enterLambda() { @@ -377,6 +502,7 @@ public class StellarCompiler extends StellarBaseListener { } private void exitLambda(boolean hasArgs) { + final FrameContext.Context context = getArgContext(); Token<?> t = expression.tokenDeque.pop(); final Deque<Token<?>> instanceDeque = new ArrayDeque<>(); for(; !expression.tokenDeque.isEmpty() && t != EXPRESSION_REFERENCE; t = expression.tokenDeque.pop()) { @@ -385,8 +511,8 @@ public class StellarCompiler extends StellarBaseListener { final List<String> variables = hasArgs? (List<String>) instanceDeque.removeLast().getValue() :new ArrayList<>(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { LambdaExpression expr = new LambdaExpression(variables, instanceDeque, state); - tokenDeque.push(new Token<>(expr, Object.class)); - }, DeferredFunction.class) ); + tokenDeque.push(new Token<>(expr, Object.class, context)); + }, DeferredFunction.class, context) ); } @Override @@ -411,7 +537,7 @@ public class StellarCompiler extends StellarBaseListener { @Override public void exitTransformationFunc(StellarParser.TransformationFuncContext ctx) { - + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { // resolve and initialize the function String functionName = ctx.getChild(0).getText(); @@ -421,8 +547,8 @@ public class StellarCompiler extends StellarBaseListener { // fetch the args, execute, and push result onto the stack List<Object> args = getFunctionArguments(popDeque(tokenDeque)); Object result = function.apply(args, state.context); - tokenDeque.push(new Token<>(result, Object.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(result, Object.class, context)); + }, DeferredFunction.class, context)); } /** @@ -474,22 +600,24 @@ public class StellarCompiler extends StellarBaseListener { @Override public void exitExistsFunc(StellarParser.ExistsFuncContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { String variable = ctx.getChild(2).getText(); boolean exists = state.variableResolver.resolve(variable) != null; - tokenDeque.push(new Token<>(exists, Boolean.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(exists, Boolean.class, context)); + }, DeferredFunction.class, context)); String variable = ctx.getChild(2).getText(); expression.variablesUsed.add(variable); } @Override public void enterFunc_args(StellarParser.Func_argsContext ctx) { - expression.tokenDeque.push(new Token<>(new FunctionMarker(), FunctionMarker.class)); + expression.tokenDeque.push(new Token<>(new FunctionMarker(), FunctionMarker.class, getArgContext())); } @Override public void exitFunc_args(StellarParser.Func_argsContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>((tokenDeque, state) -> { LinkedList<Object> args = new LinkedList<>(); while (true) { @@ -500,17 +628,18 @@ public class StellarCompiler extends StellarBaseListener { args.addFirst(token.getValue()); } } - tokenDeque.push(new Token<>(args, List.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(args, List.class, context)); + }, DeferredFunction.class, context)); } @Override public void enterMap_entity(StellarParser.Map_entityContext ctx) { - expression.tokenDeque.push(new Token<>(new FunctionMarker(), FunctionMarker.class)); + expression.tokenDeque.push(new Token<>(new FunctionMarker(), FunctionMarker.class, getArgContext())); } @Override public void exitMap_entity(StellarParser.Map_entityContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { HashMap<String, Object> args = new HashMap<>(); Object value = null; @@ -526,12 +655,13 @@ public class StellarCompiler extends StellarBaseListener { } } } - tokenDeque.push(new Token<>(args, Map.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(args, Map.class, context)); + }, DeferredFunction.class, context)); } @Override public void exitList_entity(StellarParser.List_entityContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { LinkedList<Object> args = new LinkedList<>(); while (true) { @@ -542,24 +672,37 @@ public class StellarCompiler extends StellarBaseListener { args.addFirst(token.getValue()); } } - tokenDeque.push(new Token<>(args, List.class)); - }, DeferredFunction.class)); + tokenDeque.push(new Token<>(args, List.class, context)); + }, DeferredFunction.class, context)); } + + @Override public void exitComparisonExpressionWithOperator(StellarParser.ComparisonExpressionWithOperatorContext ctx) { + final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> { StellarParser.Comp_operatorContext op = ctx.comp_operator(); Token<?> right = popDeque(tokenDeque); Token<?> left = popDeque(tokenDeque); - tokenDeque.push(comparisonExpressionWithOperatorEvaluator.evaluate(left, right, (StellarParser.ComparisonOpContext) op)); - }, DeferredFunction.class)); + tokenDeque.push(comparisonExpressionWithOperatorEvaluator.evaluate(left, right, (StellarParser.ComparisonOpContext) op, context)); + }, DeferredFunction.class, context)); } @Override public void enterList_entity(StellarParser.List_entityContext ctx) { - expression.tokenDeque.push(new Token<>(new FunctionMarker(), FunctionMarker.class)); + expression.tokenDeque.push(new Token<>(new FunctionMarker(), FunctionMarker.class, getArgContext())); + } + + private void popArgContext() { + if(!expression.multiArgumentState.isEmpty()) { + expression.multiArgumentState.pop(); + } + } + + private FrameContext.Context getArgContext() { + return expression.multiArgumentState.isEmpty()?null:expression.multiArgumentState.peek(); } private Token<?> popDeque(Deque<Token<?>> tokenDeque) { http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java index f1264e2..b458f9c 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java @@ -19,8 +19,8 @@ package org.apache.metron.common.stellar.evaluators; import org.apache.commons.lang3.tuple.Pair; -import org.apache.metron.common.dsl.ParseException; import org.apache.metron.common.dsl.Token; +import org.apache.metron.common.stellar.FrameContext; import java.util.function.BiFunction; @@ -44,58 +44,58 @@ public enum ArithmeticEvaluator { * types is taken for the Java spec: http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.6.2 */ public static final class ArithmeticEvaluatorFunctions { - public static BiFunction<Number, Number, Token<? extends Number>> addition() { + public static BiFunction<Number, Number, Token<? extends Number>> addition(final FrameContext.Context context) { return (Number l, Number r) -> { if (l instanceof Double || r instanceof Double) { - return new Token<>(l.doubleValue() + r.doubleValue(), Double.class); + return new Token<>(l.doubleValue() + r.doubleValue(), Double.class, context); } else if (l instanceof Float || r instanceof Float) { - return new Token<>(l.floatValue() + r.floatValue(), Float.class); + return new Token<>(l.floatValue() + r.floatValue(), Float.class, context); } else if (l instanceof Long || r instanceof Long) { - return new Token<>(l.longValue() + r.longValue(), Long.class); + return new Token<>(l.longValue() + r.longValue(), Long.class, context); } else { - return new Token<>(l.intValue() + r.intValue(), Integer.class); + return new Token<>(l.intValue() + r.intValue(), Integer.class, context); } }; } - public static BiFunction<Number, Number, Token<? extends Number>> multiplication() { + public static BiFunction<Number, Number, Token<? extends Number>> multiplication(final FrameContext.Context context) { return (Number l, Number r) -> { if (l instanceof Double || r instanceof Double) { - return new Token<>(l.doubleValue() * r.doubleValue(), Double.class); + return new Token<>(l.doubleValue() * r.doubleValue(), Double.class, context); } else if (l instanceof Float || r instanceof Float) { - return new Token<>(l.floatValue() * r.floatValue(), Float.class); + return new Token<>(l.floatValue() * r.floatValue(), Float.class, context); } else if (l instanceof Long || r instanceof Long) { - return new Token<>(l.longValue() * r.longValue(), Long.class); + return new Token<>(l.longValue() * r.longValue(), Long.class, context); } else { - return new Token<>(l.intValue() * r.intValue(), Integer.class); + return new Token<>(l.intValue() * r.intValue(), Integer.class, context); } }; } - public static BiFunction<Number, Number, Token<? extends Number>> subtraction() { + public static BiFunction<Number, Number, Token<? extends Number>> subtraction(final FrameContext.Context context) { return (Number l, Number r) -> { if (l instanceof Double || r instanceof Double) { - return new Token<>(l.doubleValue() - r.doubleValue(), Double.class); + return new Token<>(l.doubleValue() - r.doubleValue(), Double.class, context); } else if (l instanceof Float || r instanceof Float) { - return new Token<>(l.floatValue() - r.floatValue(), Float.class); + return new Token<>(l.floatValue() - r.floatValue(), Float.class, context); } else if (l instanceof Long || r instanceof Long) { - return new Token<>(l.longValue() - r.longValue(), Long.class); + return new Token<>(l.longValue() - r.longValue(), Long.class, context); } else { - return new Token<>(l.intValue() - r.intValue(), Integer.class); + return new Token<>(l.intValue() - r.intValue(), Integer.class, context); } }; } - public static BiFunction<Number, Number, Token<? extends Number>> division() { + public static BiFunction<Number, Number, Token<? extends Number>> division(FrameContext.Context context) { return (Number l, Number r) -> { if (l instanceof Double || r instanceof Double) { - return new Token<>(l.doubleValue() / r.doubleValue(), Double.class); + return new Token<>(l.doubleValue() / r.doubleValue(), Double.class, context); } else if (l instanceof Float || r instanceof Float) { - return new Token<>(l.floatValue() / r.floatValue(), Float.class); + return new Token<>(l.floatValue() / r.floatValue(), Float.class, context); } else if (l instanceof Long || r instanceof Long) { - return new Token<>(l.longValue() / r.longValue(), Long.class); + return new Token<>(l.longValue() / r.longValue(), Long.class, context); } else { - return new Token<>(l.intValue() / r.intValue(), Integer.class); + return new Token<>(l.intValue() / r.intValue(), Integer.class, context); } }; } http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluator.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluator.java index 4862684..e213eb5 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluator.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluator.java @@ -20,6 +20,7 @@ package org.apache.metron.common.stellar.evaluators; import org.apache.metron.common.dsl.ParseException; import org.apache.metron.common.dsl.Token; +import org.apache.metron.common.stellar.FrameContext; import org.apache.metron.common.stellar.generated.StellarParser; /** @@ -81,13 +82,13 @@ public enum ComparisonExpressionWithOperatorEvaluator { * @param op The operator in the Stellar expression. * @return A token with type boolean. This is based on the comparison of the {@code right} and {@code left} values. */ - public Token<Boolean> evaluate(final Token<?> left, final Token<?> right, final StellarParser.ComparisonOpContext op) { + public Token<Boolean> evaluate(final Token<?> left, final Token<?> right, final StellarParser.ComparisonOpContext op, FrameContext.Context context) { if (op.EQ() != null) { - return new Token<>(Strategy.EQUALITY_OPERATORS.evaluator().evaluate(left, right, op), Boolean.class); + return new Token<>(Strategy.EQUALITY_OPERATORS.evaluator().evaluate(left, right, op), Boolean.class, context); } else if (op.NEQ() != null) { - return new Token<>(!Strategy.EQUALITY_OPERATORS.evaluator().evaluate(left, right, op), Boolean.class); + return new Token<>(!Strategy.EQUALITY_OPERATORS.evaluator().evaluate(left, right, op), Boolean.class, context); } else if (op.LT() != null || op.GT() != null || op.LTE() != null || op.GTE() != null) { - return new Token<>(Strategy.COMPARISON_OPERATORS.evaluator().evaluate(left, right, op), Boolean.class); + return new Token<>(Strategy.COMPARISON_OPERATORS.evaluator().evaluate(left, right, op), Boolean.class, context); } throw new ParseException("Unsupported operations. The following expression is invalid: " + left.getValue() + op.getText() + right.getValue()); http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluator.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluator.java index 1bd1a49..653b56c 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluator.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluator.java @@ -19,15 +19,16 @@ package org.apache.metron.common.stellar.evaluators; import org.apache.metron.common.dsl.Token; +import org.apache.metron.common.stellar.FrameContext; import org.apache.metron.common.stellar.generated.StellarParser; public class DoubleLiteralEvaluator implements NumberEvaluator<StellarParser.DoubleLiteralContext> { @Override - public Token<Double> evaluate(StellarParser.DoubleLiteralContext context) { + public Token<Double> evaluate(StellarParser.DoubleLiteralContext context, FrameContext.Context contextVariety) { if (context == null) { throw new IllegalArgumentException("Cannot evaluate a context that is null."); } - return new Token<>(Double.parseDouble(context.getText()), Double.class); + return new Token<>(Double.parseDouble(context.getText()), Double.class, contextVariety); } } http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluator.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluator.java index 60b312b..4489d30 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluator.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluator.java @@ -19,15 +19,16 @@ package org.apache.metron.common.stellar.evaluators; import org.apache.metron.common.dsl.Token; +import org.apache.metron.common.stellar.FrameContext; import org.apache.metron.common.stellar.generated.StellarParser; public class FloatLiteralEvaluator implements NumberEvaluator<StellarParser.FloatLiteralContext> { @Override - public Token<Float> evaluate(StellarParser.FloatLiteralContext context) { + public Token<Float> evaluate(StellarParser.FloatLiteralContext context, FrameContext.Context contextVariety) { if (context == null) { throw new IllegalArgumentException("Cannot evaluate a context that is null."); } - return new Token<>(Float.parseFloat(context.getText()), Float.class); + return new Token<>(Float.parseFloat(context.getText()), Float.class, contextVariety); } } http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluator.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluator.java index c928a9a..00e62e6 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluator.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluator.java @@ -19,15 +19,16 @@ package org.apache.metron.common.stellar.evaluators; import org.apache.metron.common.dsl.Token; +import org.apache.metron.common.stellar.FrameContext; import org.apache.metron.common.stellar.generated.StellarParser; public class IntLiteralEvaluator implements NumberEvaluator<StellarParser.IntLiteralContext> { @Override - public Token<Integer> evaluate(StellarParser.IntLiteralContext context) { + public Token<Integer> evaluate(StellarParser.IntLiteralContext context, FrameContext.Context contextVariety) { if (context == null) { throw new IllegalArgumentException("Cannot evaluate a context that is null."); } - return new Token<>(Integer.parseInt(context.getText()), Integer.class); + return new Token<>(Integer.parseInt(context.getText()), Integer.class, contextVariety); } } http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluator.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluator.java index 05ee162..338adc4 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluator.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluator.java @@ -20,11 +20,12 @@ package org.apache.metron.common.stellar.evaluators; import org.apache.metron.common.dsl.ParseException; import org.apache.metron.common.dsl.Token; +import org.apache.metron.common.stellar.FrameContext; import org.apache.metron.common.stellar.generated.StellarParser; public class LongLiteralEvaluator implements NumberEvaluator<StellarParser.LongLiteralContext> { @Override - public Token<Long> evaluate(StellarParser.LongLiteralContext context) { + public Token<Long> evaluate(StellarParser.LongLiteralContext context, FrameContext.Context contextVariety) { if (context == null) { throw new IllegalArgumentException("Cannot evaluate a context that is null."); } @@ -32,7 +33,7 @@ public class LongLiteralEvaluator implements NumberEvaluator<StellarParser.LongL String value = context.getText(); if (value.endsWith("l") || value.endsWith("L")) { value = value.substring(0, value.length() - 1); // Drop the 'L' or 'l'. Long.parseLong does not accept a string with either of these. - return new Token<>(Long.parseLong(value), Long.class); + return new Token<>(Long.parseLong(value), Long.class, contextVariety); } else { // Technically this should never happen, but just being safe. throw new ParseException("Invalid format for long. Failed trying to parse a long with the following value: " + value); http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberEvaluator.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberEvaluator.java index 0007b72..2c18f9d 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberEvaluator.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberEvaluator.java @@ -19,8 +19,9 @@ package org.apache.metron.common.stellar.evaluators; import org.apache.metron.common.dsl.Token; +import org.apache.metron.common.stellar.FrameContext; import org.apache.metron.common.stellar.generated.StellarParser; public interface NumberEvaluator<T extends StellarParser.Arithmetic_operandsContext> { - Token<? extends Number> evaluate(T context); + Token<? extends Number> evaluate(T context, FrameContext.Context contextVariety); } http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluator.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluator.java index 83d795f..0ec3859 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluator.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluator.java @@ -20,6 +20,7 @@ package org.apache.metron.common.stellar.evaluators; import org.apache.metron.common.dsl.ParseException; import org.apache.metron.common.dsl.Token; +import org.apache.metron.common.stellar.FrameContext; import org.apache.metron.common.stellar.generated.StellarParser; import java.util.HashMap; @@ -53,17 +54,18 @@ public enum NumberLiteralEvaluator { Token<? extends Number> evaluate(StellarParser.Arithmetic_operandsContext context , Map<Class<? extends StellarParser.Arithmetic_operandsContext>, NumberEvaluator> instanceMap + , FrameContext.Context contextVariety ) { NumberEvaluator evaluator = instanceMap.get(context.getClass()); if(evaluator == null) { throw new ParseException("Does not support evaluation for type " + context.getClass()); } - return evaluator.evaluate(context); + return evaluator.evaluate(context, contextVariety); } - public Token<? extends Number> evaluate(StellarParser.Arithmetic_operandsContext context) { - return evaluate(context, Strategy.strategyMap); + public Token<? extends Number> evaluate(StellarParser.Arithmetic_operandsContext context, FrameContext.Context contextVariety) { + return evaluate(context, Strategy.strategyMap, contextVariety); } } http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java index 2be710b..3ca1daa 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java @@ -133,6 +133,42 @@ public class StellarBaseListener implements StellarListener { * * <p>The default implementation does nothing.</p> */ + @Override public void enterIf_expr(StellarParser.If_exprContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void exitIf_expr(StellarParser.If_exprContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void enterThen_expr(StellarParser.Then_exprContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void exitThen_expr(StellarParser.Then_exprContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void enterElse_expr(StellarParser.Else_exprContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void exitElse_expr(StellarParser.Else_exprContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ @Override public void enterTernaryFuncWithoutIf(StellarParser.TernaryFuncWithoutIfContext ctx) { } /** * {@inheritDoc} http://git-wip-us.apache.org/repos/asf/metron/blob/30d0e2a6/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java index 66493f7..6c00691 100644 --- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java +++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java @@ -123,6 +123,36 @@ public interface StellarListener extends ParseTreeListener { */ void exitInExpression(StellarParser.InExpressionContext ctx); /** + * Enter a parse tree produced by {@link StellarParser#if_expr}. + * @param ctx the parse tree + */ + void enterIf_expr(StellarParser.If_exprContext ctx); + /** + * Exit a parse tree produced by {@link StellarParser#if_expr}. + * @param ctx the parse tree + */ + void exitIf_expr(StellarParser.If_exprContext ctx); + /** + * Enter a parse tree produced by {@link StellarParser#then_expr}. + * @param ctx the parse tree + */ + void enterThen_expr(StellarParser.Then_exprContext ctx); + /** + * Exit a parse tree produced by {@link StellarParser#then_expr}. + * @param ctx the parse tree + */ + void exitThen_expr(StellarParser.Then_exprContext ctx); + /** + * Enter a parse tree produced by {@link StellarParser#else_expr}. + * @param ctx the parse tree + */ + void enterElse_expr(StellarParser.Else_exprContext ctx); + /** + * Exit a parse tree produced by {@link StellarParser#else_expr}. + * @param ctx the parse tree + */ + void exitElse_expr(StellarParser.Else_exprContext ctx); + /** * Enter a parse tree produced by the {@code TernaryFuncWithoutIf} * labeled alternative in {@link StellarParser#conditional_expr}. * @param ctx the parse tree