summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchaochaoc <[email protected]>2024-07-23 11:26:47 +0800
committerchaochaoc <[email protected]>2024-07-23 11:26:47 +0800
commitc2d05f2f9ed79533e26afadfb6152cd3a79192b4 (patch)
tree52b34bc7959f1d0a9e45a59e31f2a17543912996
parent0e8005ae3b8b45480e4d511c600700ac8de897ae (diff)
[GAL-625] feat: remove the impl of antlr4 Token method.
-rw-r--r--groot-core/src/main/antlr4/com/geedgenetworks/core/expressions/parser/EvalExpression.g4163
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/ArithmeticOperator.java14
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/BooleanExpression.java171
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/ComparisonOperator.java11
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/EvalExpressionResolver.java299
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/Expression.java10
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/ExpressionVisitor.java28
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/InvalidProgramException.java16
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/PredicateOperator.java7
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/ValueExpression.java233
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/CalcCodeConvertor.java92
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/CodeGeneratorContext.java195
-rw-r--r--groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/EvalCodeGenerator.java236
-rw-r--r--groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/EvalExpressionResolverTest.java89
-rw-r--r--groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/codegen/CalcCodeConvertorTest.java140
-rw-r--r--groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/codegen/EvalCodeGeneratorTest.java34
16 files changed, 0 insertions, 1738 deletions
diff --git a/groot-core/src/main/antlr4/com/geedgenetworks/core/expressions/parser/EvalExpression.g4 b/groot-core/src/main/antlr4/com/geedgenetworks/core/expressions/parser/EvalExpression.g4
deleted file mode 100644
index ee7cd5a..0000000
--- a/groot-core/src/main/antlr4/com/geedgenetworks/core/expressions/parser/EvalExpression.g4
+++ /dev/null
@@ -1,163 +0,0 @@
-grammar EvalExpression;
-
-@members {
- /**
- * Verify whether current token is a valid decimal token (which contains dot).
- * Returns true if the character that follows the token is not a digit or letter or underscore.
- *
- * For example:
- * For char stream "2.3", "2." is not a valid decimal token, because it is followed by digit '3'.
- * For char stream "2.3_", "2.3" is not a valid decimal token, because it is followed by '_'.
- * For char stream "2.3W", "2.3" is not a valid decimal token, because it is followed by 'W'.
- * For char stream "12.0D 34.E2+0.12 " 12.0D is a valid decimal token because it is folllowed
- * by a space. 34.E2 is a valid decimal token because it is followed by symbol '+'
- * which is not a digit or letter or underscore.
- */
- public boolean isValidDecimal() {
- int nextChar = _input.LA(1);
- if (nextChar >= 'A' && nextChar <= 'Z' || nextChar >= '0' && nextChar <= '9' ||
- nextChar == '_') {
- return false;
- } else {
- return true;
- }
- }
-}
-
-statement
- : valueExpression #assignValue
- | booleanExpression '?' trueValue=valueExpression ':' falseValue=valueExpression #predicated
- ;
-
-booleanExpression
- : left=valueExpression operator=comparisonOperator right=valueExpression #valueComparison
- | left=booleanExpression operator=predicateOperator right=booleanExpression #logicalComparison
- | NOT booleanExpression #notComparison
- ;
-
-valueExpression
- : constant #constantValue
- | identifier #variable
- | left=valueExpression operator=arithmeticOperator right=valueExpression #arithmeticValue
- ;
-
-constant
- : NULL #nullLiteral
- | number #numericLiteral
- | (TRUE | FALSE) #booleanLiteral
- | STRING #stringLiteral
- ;
-
-identifier
- : IDENTIFIER
- ;
-
-number
- : MINUS? INTEGER_VALUE #integerLiteral
- | MINUS? BIGINT_LITERAL #bigIntLiteral
- | MINUS? SMALLINT_LITERAL #smallIntLiteral
- | MINUS? DOUBLE_LITERAL #doubleLiteral
- | MINUS? FLOAT_LITERAL #floatLiteral
- | MINUS? BIGDECIMAL_LITERAL #bigDecimalLiteral
- ;
-
-comparisonOperator
- : EQ | NEQ | LT | LTE | GT | GTE
- ;
-
-arithmeticOperator
- : PLUS | MINUS | ASTERISK | SLASH | PERCENT
- | LEFT_SHIFT | RIGHT_SHIFT | BITWISE_AND | BITWISE_OR
- ;
-
-predicateOperator
- : OR | AND
- ;
-
-NULL: 'NULL';
-
-EQ : '=' | '==';
-NEQ : '<>' | '!=';
-LT : '<';
-LTE : '<=' | '!>';
-GT : '>';
-GTE : '>=' | '!<';
-
-PLUS: '+';
-MINUS: '-';
-ASTERISK: '*';
-SLASH: '/';
-PERCENT: '%';
-LEFT_SHIFT: '<<';
-RIGHT_SHIFT: '>>';
-BITWISE_OR: '|';
-BITWISE_AND: '&';
-
-AND: '&&';
-OR: '||';
-NOT: '!';
-
-TRUE: 'TRUE';
-FALSE: 'FALSE';
-
-STRING
- : '\'' ( ~('\''|'\\') | ('\\' .) )* '\''
- | '"' ( ~('"'|'\\') | ('\\' .) )* '"'
- ;
-
-BIGINT_LITERAL
- : DIGIT+ 'L'
- ;
-
-SMALLINT_LITERAL
- : DIGIT+ 'S'
- ;
-
-INTEGER_VALUE
- : DIGIT+
- ;
-
-FLOAT_LITERAL
- : DIGIT+ EXPONENT? 'F'
- | DECIMAL_DIGITS EXPONENT? 'F' {isValidDecimal()}?
- ;
-
-DOUBLE_LITERAL
- : DIGIT+ EXPONENT? 'D'
- | DECIMAL_DIGITS EXPONENT? 'D' {isValidDecimal()}?
- ;
-
-BIGDECIMAL_LITERAL
- : DIGIT+ EXPONENT? 'BD'
- | DECIMAL_DIGITS EXPONENT? 'BD' {isValidDecimal()}?
- ;
-
-IDENTIFIER
- : (LETTER | DIGIT | '_')+
- ;
-
-fragment DECIMAL_DIGITS
- : DIGIT+ '.' DIGIT*
- | '.' DIGIT+
- ;
-
-fragment EXPONENT
- : 'E' [+-]? DIGIT+
- ;
-
-
-fragment LETTER
- : [a-zA-Z]
- ;
-
-fragment DIGIT
- : [0-9]
- ;
-
-WS
- : [ \r\n\t]+ -> channel(HIDDEN)
- ;
-
-UNRECOGNIZED
- : .
- ; \ No newline at end of file
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/ArithmeticOperator.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/ArithmeticOperator.java
deleted file mode 100644
index 36846b3..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/ArithmeticOperator.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.geedgenetworks.core.expressions;
-
-/** Enumeration representing arithmetic operators. */
-public enum ArithmeticOperator {
- PLUS,
- MINUS,
- ASTERISK,
- SLASH,
- PERCENT,
- LEFT_SHIFT,
- RIGHT_SHIFT,
- BITWISE_AND,
- BITWISE_OR
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/BooleanExpression.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/BooleanExpression.java
deleted file mode 100644
index 0200e6e..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/BooleanExpression.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package com.geedgenetworks.core.expressions;
-
-import com.google.common.collect.Lists;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Boolean expression.
- *
- * @author chaoc
- * @since 1.0
- */
-public abstract class BooleanExpression implements Expression {
-
- public static class ComparisonExpression extends BooleanExpression {
-
- private final ComparisonOperator operator;
-
- private final ValueExpression left;
- private final ValueExpression right;
-
- public ComparisonExpression(
- ComparisonOperator operator, ValueExpression left, ValueExpression right) {
- this.operator = operator;
- this.left = left;
- this.right = right;
- }
-
- public ComparisonOperator getOperator() {
- return operator;
- }
-
- public ValueExpression getLeft() {
- return left;
- }
-
- public ValueExpression getRight() {
- return right;
- }
-
- @Override
- public List<Expression> getChildren() {
- return Lists.newArrayList(left, right);
- }
-
- @Override
- public <R> R accept(ExpressionVisitor<R> visitor) {
- return visitor.visit(this);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- ComparisonExpression that = (ComparisonExpression) o;
- return operator == that.operator
- && Objects.equals(left, that.left)
- && Objects.equals(right, that.right);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(operator, left, right);
- }
-
- @Override
- public String toString() {
- return "[" + left + " " + operator + " " + right + "]";
- }
- }
-
- public static class PredicateExpression extends BooleanExpression {
-
- private final PredicateOperator operator;
-
- private final BooleanExpression left;
- private final BooleanExpression right;
-
- public PredicateExpression(
- PredicateOperator operator, BooleanExpression left, BooleanExpression right) {
- this.operator = operator;
- this.left = left;
- this.right = right;
- }
-
- public PredicateOperator getOperator() {
- return operator;
- }
-
- public BooleanExpression getLeft() {
- return left;
- }
-
- public BooleanExpression getRight() {
- return right;
- }
-
- @Override
- public List<Expression> getChildren() {
- return Lists.newArrayList(left, right);
- }
-
- @Override
- public <R> R accept(ExpressionVisitor<R> visitor) {
- return visitor.visit(this);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- PredicateExpression that = (PredicateExpression) o;
- return operator == that.operator
- && Objects.equals(left, that.left)
- && Objects.equals(right, that.right);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(operator, left, right);
- }
-
- @Override
- public String toString() {
- return "[" + left + " " + operator + " " + right + "]";
- }
- }
-
- public static class NotExpression extends BooleanExpression {
-
- private final BooleanExpression expression;
-
- public NotExpression(BooleanExpression expression) {
- this.expression = expression;
- }
-
- public BooleanExpression getExpression() {
- return expression;
- }
-
- @Override
- public List<Expression> getChildren() {
- return Collections.singletonList(expression);
- }
-
- @Override
- public <R> R accept(ExpressionVisitor<R> visitor) {
- return visitor.visit(expression);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- NotExpression that = (NotExpression) o;
- return Objects.equals(expression, that.expression);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(expression);
- }
-
- @Override
- public String toString() {
- return "! " + expression;
- }
- }
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/ComparisonOperator.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/ComparisonOperator.java
deleted file mode 100644
index 5ab1a5d..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/ComparisonOperator.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.geedgenetworks.core.expressions;
-
-/** Enumeration representing comparison operators. */
-public enum ComparisonOperator {
- EQ,
- NEQ,
- LT,
- LTE,
- GT,
- GTE
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/EvalExpressionResolver.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/EvalExpressionResolver.java
deleted file mode 100644
index 95015ae..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/EvalExpressionResolver.java
+++ /dev/null
@@ -1,299 +0,0 @@
-package com.geedgenetworks.core.expressions;
-
-import com.geedgenetworks.core.expressions.parser.EvalExpressionBaseVisitor;
-import com.geedgenetworks.core.expressions.parser.EvalExpressionLexer;
-import com.geedgenetworks.core.expressions.parser.EvalExpressionParser;
-import com.google.common.base.Strings;
-import org.antlr.v4.runtime.*;
-import org.antlr.v4.runtime.atn.PredictionMode;
-import org.apache.commons.lang3.StringUtils;
-
-import java.math.BigDecimal;
-
-/**
- * This class represents an evaluator for expressions using a visitor pattern. It can evaluate
- * arithmetic, logical, and comparison expressions, as well as handle variables and literals.
- *
- * @author chaoc
- * @version 1.0
- */
-@SuppressWarnings("Duplicates")
-public class EvalExpressionResolver extends EvalExpressionBaseVisitor<Object> {
-
- public Expression resolve(final String expr) {
- EvalExpressionLexer lexer = new EvalExpressionLexer(CharStreams.fromString(expr));
- lexer.removeErrorListeners();
-
- EvalExpressionParser parser = new EvalExpressionParser(new CommonTokenStream(lexer));
- parser.getInterpreter().setPredictionMode(PredictionMode.LL);
- parser.setErrorHandler(
- new DefaultErrorStrategy() {
-
- @Override
- protected void reportInputMismatch(
- Parser recognizer, InputMismatchException e) {
- Token currentToken = recognizer.getCurrentToken();
- String message = "Miss matched input: ";
- message += this.getTokenErrorDisplay(e.getOffendingToken());
- message += ";\n";
- message +=
- "Expect: "
- + e.getExpectedTokens()
- .toString(recognizer.getVocabulary());
- message += "\n";
- message += StringUtils.split(expr, "\n")[currentToken.getLine() - 1];
- message += "\n";
- message += Strings.repeat(" ", currentToken.getTokenIndex()) + '^';
- throw new SyntaxErrorException(message);
- }
- });
- return (Expression) this.visit(parser.statement());
- }
-
- @Override
- public Object visitAssignValue(EvalExpressionParser.AssignValueContext ctx) {
- return visitValueExpression(ctx.valueExpression());
- }
-
- @Override
- public ValueExpression visitPredicated(EvalExpressionParser.PredicatedContext ctx) {
- BooleanExpression booleanExpression = visitBooleanExpression(ctx.booleanExpression());
- ValueExpression trueValue = visitValueExpression(ctx.trueValue);
- ValueExpression falseValue = visitValueExpression(ctx.falseValue);
- return new ValueExpression.TernaryExpression(booleanExpression, trueValue, falseValue);
- }
-
- @Override
- public BooleanExpression visitValueComparison(EvalExpressionParser.ValueComparisonContext ctx) {
- ValueExpression left = visitValueExpression(ctx.left);
- ValueExpression right = visitValueExpression(ctx.right);
- ComparisonOperator operator = visitComparisonOperator(ctx.operator);
- return new BooleanExpression.ComparisonExpression(operator, left, right);
- }
-
- @Override
- public BooleanExpression visitLogicalComparison(
- EvalExpressionParser.LogicalComparisonContext ctx) {
- BooleanExpression left = visitBooleanExpression(ctx.left);
- BooleanExpression right = visitBooleanExpression(ctx.right);
- PredicateOperator operator = visitPredicateOperator(ctx.operator);
- return new BooleanExpression.PredicateExpression(operator, left, right);
- }
-
- @Override
- public BooleanExpression visitNotComparison(EvalExpressionParser.NotComparisonContext ctx) {
- return new BooleanExpression.NotExpression(visitBooleanExpression(ctx));
- }
-
- @Override
- public ValueExpression.FieldRefExpression visitVariable(
- EvalExpressionParser.VariableContext ctx) {
- String key = visitIdentifier(ctx.identifier());
- return new ValueExpression.FieldRefExpression(key);
- }
-
- @Override
- public String visitIdentifier(EvalExpressionParser.IdentifierContext ctx) {
- if (ctx.IDENTIFIER() != null) {
- return ctx.IDENTIFIER().getText();
- }
- return null;
- }
-
- @Override
- public ValueExpression.ArithmeticExpression visitArithmeticValue(
- EvalExpressionParser.ArithmeticValueContext ctx) {
- ValueExpression left = visitValueExpression(ctx.left);
- ValueExpression right = visitValueExpression(ctx.right);
- ArithmeticOperator operator = visitArithmeticOperator(ctx.operator);
- return new ValueExpression.ArithmeticExpression(operator, left, right);
- }
-
- @Override
- public ValueExpression.ConstantValueExpression<?> visitConstantValue(
- EvalExpressionParser.ConstantValueContext ctx) {
- EvalExpressionParser.ConstantContext context = ctx.constant();
- if (context instanceof EvalExpressionParser.NullLiteralContext) {
- return visitNullLiteral((EvalExpressionParser.NullLiteralContext) context);
- } else if (context instanceof EvalExpressionParser.NumericLiteralContext) {
- return visitNumericLiteral((EvalExpressionParser.NumericLiteralContext) context);
- } else if (context instanceof EvalExpressionParser.BooleanLiteralContext) {
- return visitBooleanLiteral((EvalExpressionParser.BooleanLiteralContext) context);
- } else {
- return visitStringLiteral((EvalExpressionParser.StringLiteralContext) context);
- }
- }
-
- @Override
- public ValueExpression.StringConstantExpression visitNullLiteral(
- EvalExpressionParser.NullLiteralContext ctx) {
- return new ValueExpression.StringConstantExpression(null);
- }
-
- @Override
- public ValueExpression.NumberConstantExpression visitNumericLiteral(
- EvalExpressionParser.NumericLiteralContext ctx) {
- EvalExpressionParser.NumberContext context = ctx.number();
- if (context instanceof EvalExpressionParser.IntegerLiteralContext) {
- return visitIntegerLiteral((EvalExpressionParser.IntegerLiteralContext) context);
- } else if (context instanceof EvalExpressionParser.BigIntLiteralContext) {
- return visitBigIntLiteral((EvalExpressionParser.BigIntLiteralContext) context);
- } else if (context instanceof EvalExpressionParser.SmallIntLiteralContext) {
- return visitSmallIntLiteral((EvalExpressionParser.SmallIntLiteralContext) context);
- } else if (context instanceof EvalExpressionParser.DoubleLiteralContext) {
- return visitDoubleLiteral((EvalExpressionParser.DoubleLiteralContext) context);
- } else if (context instanceof EvalExpressionParser.FloatLiteralContext) {
- return visitFloatLiteral((EvalExpressionParser.FloatLiteralContext) context);
- } else {
- return visitBigDecimalLiteral((EvalExpressionParser.BigDecimalLiteralContext) context);
- }
- }
-
- @Override
- public ValueExpression.BooleanConstantExpression visitBooleanLiteral(
- EvalExpressionParser.BooleanLiteralContext ctx) {
- return new ValueExpression.BooleanConstantExpression(ctx.TRUE() != null);
- }
-
- @Override
- public ValueExpression.StringConstantExpression visitStringLiteral(
- EvalExpressionParser.StringLiteralContext ctx) {
- String text = ctx.STRING().getText();
- return new ValueExpression.StringConstantExpression(
- StringUtils.replacePattern(text, "[\"']", ""));
- }
-
- @Override
- public ValueExpression.NumberConstantExpression visitIntegerLiteral(
- EvalExpressionParser.IntegerLiteralContext ctx) {
- int factor = ctx.MINUS() != null ? -1 : 1;
- int value = factor * Integer.parseInt(ctx.INTEGER_VALUE().getText());
- return new ValueExpression.NumberConstantExpression(value);
- }
-
- @Override
- public ValueExpression.NumberConstantExpression visitBigIntLiteral(
- EvalExpressionParser.BigIntLiteralContext ctx) {
- int factor = ctx.MINUS() != null ? -1 : 1;
- long value = factor * Long.parseLong(ctx.BIGINT_LITERAL().getText().replace("L", ""));
- return new ValueExpression.NumberConstantExpression(value);
- }
-
- @Override
- public ValueExpression.NumberConstantExpression visitSmallIntLiteral(
- EvalExpressionParser.SmallIntLiteralContext ctx) {
- int factor = ctx.MINUS() != null ? -1 : 1;
- short value =
- (short)
- (factor
- * Short.parseShort(
- ctx.SMALLINT_LITERAL().getText().replace("S", "")));
- return new ValueExpression.NumberConstantExpression(value);
- }
-
- @Override
- public ValueExpression.NumberConstantExpression visitDoubleLiteral(
- EvalExpressionParser.DoubleLiteralContext ctx) {
- int factor = ctx.MINUS() != null ? -1 : 1;
- double value = factor * Double.parseDouble(ctx.DOUBLE_LITERAL().getText().replace("D", ""));
- return new ValueExpression.NumberConstantExpression(value);
- }
-
- @Override
- public ValueExpression.NumberConstantExpression visitFloatLiteral(
- EvalExpressionParser.FloatLiteralContext ctx) {
- int factor = ctx.MINUS() != null ? -1 : 1;
- float value = factor * Float.parseFloat(ctx.FLOAT_LITERAL().getText().replace("F", ""));
- return new ValueExpression.NumberConstantExpression(value);
- }
-
- @Override
- public ValueExpression.NumberConstantExpression visitBigDecimalLiteral(
- EvalExpressionParser.BigDecimalLiteralContext ctx) {
- BigDecimal value = new BigDecimal(ctx.BIGDECIMAL_LITERAL().getText().replace("BD", ""));
- return new ValueExpression.NumberConstantExpression(
- ctx.MINUS() == null ? value : value.negate());
- }
-
- @Override
- public ComparisonOperator visitComparisonOperator(
- EvalExpressionParser.ComparisonOperatorContext ctx) {
- if (ctx.EQ() != null) {
- return ComparisonOperator.EQ;
- } else if (ctx.NEQ() != null) {
- return ComparisonOperator.NEQ;
- } else if (ctx.LT() != null) {
- return ComparisonOperator.LT;
- } else if (ctx.LTE() != null) {
- return ComparisonOperator.LTE;
- } else if (ctx.GT() != null) {
- return ComparisonOperator.GT;
- } else {
- return ComparisonOperator.GTE;
- }
- }
-
- @Override
- public ArithmeticOperator visitArithmeticOperator(
- EvalExpressionParser.ArithmeticOperatorContext ctx) {
- if (ctx.PLUS() != null) {
- return ArithmeticOperator.PLUS;
- } else if (ctx.MINUS() != null) {
- return ArithmeticOperator.MINUS;
- } else if (ctx.ASTERISK() != null) {
- return ArithmeticOperator.ASTERISK;
- } else if (ctx.SLASH() != null) {
- return ArithmeticOperator.SLASH;
- } else if (ctx.PERCENT() != null) {
- return ArithmeticOperator.PERCENT;
- } else if (ctx.LEFT_SHIFT() != null) {
- return ArithmeticOperator.LEFT_SHIFT;
- } else if (ctx.RIGHT_SHIFT() != null) {
- return ArithmeticOperator.RIGHT_SHIFT;
- } else if (ctx.BITWISE_AND() != null) {
- return ArithmeticOperator.BITWISE_AND;
- } else if (ctx.BITWISE_OR() != null) {
- return ArithmeticOperator.BITWISE_OR;
- } else {
- throw new IllegalArgumentException("Unsupported operate.");
- }
- }
-
- @Override
- public PredicateOperator visitPredicateOperator(
- EvalExpressionParser.PredicateOperatorContext ctx) {
- if (ctx.AND() != null) {
- return PredicateOperator.AND;
- }
- return PredicateOperator.OR;
- }
-
- // ======================================================================================
- // ----------------------------------- private helper -----------------------------------
-
- private BooleanExpression visitBooleanExpression(
- EvalExpressionParser.BooleanExpressionContext ctx) {
- if (ctx instanceof EvalExpressionParser.LogicalComparisonContext) {
- EvalExpressionParser.LogicalComparisonContext context =
- (EvalExpressionParser.LogicalComparisonContext) ctx;
- BooleanExpression left = visitBooleanExpression(context.left);
- BooleanExpression right = visitBooleanExpression(context.right);
- PredicateOperator operator = visitPredicateOperator(context.operator);
- return new BooleanExpression.PredicateExpression(operator, left, right);
- } else if (ctx instanceof EvalExpressionParser.ValueComparisonContext) {
- return visitValueComparison((EvalExpressionParser.ValueComparisonContext) ctx);
- } else {
- return visitNotComparison((EvalExpressionParser.NotComparisonContext) ctx);
- }
- }
-
- private ValueExpression visitValueExpression(EvalExpressionParser.ValueExpressionContext ctx) {
- if (ctx instanceof EvalExpressionParser.ConstantValueContext) {
- return visitConstantValue((EvalExpressionParser.ConstantValueContext) ctx);
- } else if (ctx instanceof EvalExpressionParser.VariableContext) {
- return visitVariable((EvalExpressionParser.VariableContext) ctx);
- } else {
- return visitArithmeticValue((EvalExpressionParser.ArithmeticValueContext) ctx);
- }
- }
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/Expression.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/Expression.java
deleted file mode 100644
index a95cf37..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/Expression.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.geedgenetworks.core.expressions;
-
-import java.util.List;
-
-public interface Expression {
-
- List<Expression> getChildren();
-
- <R> R accept(ExpressionVisitor<R> visitor);
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/ExpressionVisitor.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/ExpressionVisitor.java
deleted file mode 100644
index 7c1f56e..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/ExpressionVisitor.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.geedgenetworks.core.expressions;
-
-public interface ExpressionVisitor<R> {
-
- R visit(Expression expression);
-
- R visit(ValueExpression expression);
-
- R visit(ValueExpression.FieldRefExpression expression);
-
- R visit(ValueExpression.StringConstantExpression expression);
-
- R visit(ValueExpression.NumberConstantExpression expression);
-
- R visit(ValueExpression.BooleanConstantExpression expression);
-
- R visit(ValueExpression.ArithmeticExpression expression);
-
- R visit(ValueExpression.TernaryExpression expression);
-
- R visit(BooleanExpression expression);
-
- R visit(BooleanExpression.ComparisonExpression expression);
-
- R visit(BooleanExpression.PredicateExpression expression);
-
- R visit(BooleanExpression.NotExpression expression);
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/InvalidProgramException.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/InvalidProgramException.java
deleted file mode 100644
index 65d3109..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/InvalidProgramException.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.geedgenetworks.core.expressions;
-
-/**
- * Program codegen error.
- *
- * @author chaoc
- * @since 1.0
- */
-public class InvalidProgramException extends RuntimeException {
-
- public InvalidProgramException() {}
-
- public InvalidProgramException(String message) {
- super(message);
- }
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/PredicateOperator.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/PredicateOperator.java
deleted file mode 100644
index 026a35d..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/PredicateOperator.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.geedgenetworks.core.expressions;
-
-/** Enumeration representing predicate operators. */
-public enum PredicateOperator {
- OR,
- AND
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/ValueExpression.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/ValueExpression.java
deleted file mode 100644
index 42930d5..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/ValueExpression.java
+++ /dev/null
@@ -1,233 +0,0 @@
-package com.geedgenetworks.core.expressions;
-
-import com.google.common.collect.Lists;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Value expression.
- *
- * @author chaoc
- * @since 1.0
- */
-public abstract class ValueExpression implements Expression {
-
- public static class FieldRefExpression extends ValueExpression {
-
- private final String fieldName;
-
- public FieldRefExpression(String fieldName) {
- this.fieldName = fieldName;
- }
-
- public String getFieldName() {
- return fieldName;
- }
-
- @Override
- public List<Expression> getChildren() {
- return Collections.emptyList();
- }
-
- @Override
- public <R> R accept(ExpressionVisitor<R> visitor) {
- return visitor.visit(this);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- FieldRefExpression that = (FieldRefExpression) o;
- return Objects.equals(fieldName, that.fieldName);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(fieldName);
- }
-
- @Override
- public String toString() {
- return "FieldRef[" + fieldName + ']';
- }
- }
-
- public static class ArithmeticExpression extends ValueExpression {
-
- private final ArithmeticOperator operator;
- private final ValueExpression left;
- private final ValueExpression right;
-
- public ArithmeticExpression(
- ArithmeticOperator operator, ValueExpression left, ValueExpression right) {
- this.operator = operator;
- this.left = left;
- this.right = right;
- }
-
- public ArithmeticOperator getOperator() {
- return operator;
- }
-
- public ValueExpression getLeft() {
- return left;
- }
-
- public ValueExpression getRight() {
- return right;
- }
-
- @Override
- public List<Expression> getChildren() {
- return Lists.newArrayList(left, right);
- }
-
- @Override
- public <R> R accept(ExpressionVisitor<R> visitor) {
- return visitor.visit(this);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- ArithmeticExpression that = (ArithmeticExpression) o;
- return operator == that.operator
- && Objects.equals(left, that.left)
- && Objects.equals(right, that.right);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(operator, left, right);
- }
-
- @Override
- public String toString() {
- return "[" + left + " " + operator + " " + right + "]";
- }
- }
-
- public static class TernaryExpression extends ValueExpression {
-
- private final BooleanExpression expression;
- private final ValueExpression trueValue;
- private final ValueExpression falseValue;
-
- public TernaryExpression(
- BooleanExpression expression,
- ValueExpression trueValue,
- ValueExpression falseValue) {
- this.expression = expression;
- this.trueValue = trueValue;
- this.falseValue = falseValue;
- }
-
- public BooleanExpression getExpression() {
- return expression;
- }
-
- public ValueExpression getTrueValue() {
- return trueValue;
- }
-
- public ValueExpression getFalseValue() {
- return falseValue;
- }
-
- @Override
- public List<Expression> getChildren() {
- return Lists.newArrayList(expression, trueValue, falseValue);
- }
-
- @Override
- public <R> R accept(ExpressionVisitor<R> visitor) {
- return visitor.visit(this);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- TernaryExpression that = (TernaryExpression) o;
- return Objects.equals(expression, that.expression)
- && Objects.equals(trueValue, that.trueValue)
- && Objects.equals(falseValue, that.falseValue);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(expression, trueValue, falseValue);
- }
-
- @Override
- public String toString() {
- return "[" + expression + " ? " + trueValue + " : " + falseValue + ']';
- }
- }
-
- public abstract static class ConstantValueExpression<T> extends ValueExpression {
-
- private final T value;
-
- public ConstantValueExpression(final T value) {
- this.value = value;
- }
-
- public T getValue() {
- return value;
- }
-
- @Override
- public List<Expression> getChildren() {
- return Collections.emptyList();
- }
-
- @Override
- public <R> R accept(ExpressionVisitor<R> visitor) {
- return visitor.visit(this);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- ConstantValueExpression<?> that = (ConstantValueExpression<?>) o;
- return Objects.equals(value, that.value);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(value);
- }
-
- @Override
- public String toString() {
- return "ConstantValue[" + value + "]";
- }
- }
-
- public static class BooleanConstantExpression extends ConstantValueExpression<Boolean> {
-
- public BooleanConstantExpression(final Boolean value) {
- super(value);
- }
- }
-
- public static class StringConstantExpression extends ConstantValueExpression<String> {
-
- public StringConstantExpression(final String value) {
- super(value);
- }
- }
-
- public static class NumberConstantExpression extends ConstantValueExpression<Number> {
-
- public NumberConstantExpression(final Number value) {
- super(value);
- }
- }
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/CalcCodeConvertor.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/CalcCodeConvertor.java
deleted file mode 100644
index 32b7359..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/CalcCodeConvertor.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.geedgenetworks.core.expressions.codegen;
-
-import com.geedgenetworks.core.expressions.Calc;
-import com.geedgenetworks.core.expressions.EvalExpressionResolver;
-import com.geedgenetworks.core.expressions.Expression;
-import com.geedgenetworks.core.expressions.InvalidProgramException;
-import org.codehaus.janino.SimpleCompiler;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Converting a mathematical expression into executable code for evaluation.
- *
- * @author chaoc
- * @since 1.0
- */
-public class CalcCodeConvertor {
-
- private static final AtomicLong COUNTER = new AtomicLong(0);
-
- /**
- * Converts a mathematical expression into an executable Calc object.
- *
- * @param expr The mathematical expression to convert.
- * @return A Calc object capable of evaluating the expression.
- */
- public static Calc convert(final String expr) {
- return convert(Thread.currentThread().getContextClassLoader(), expr);
- }
-
- /**
- * Converts a mathematical expression into an executable Calc object.
- *
- * @param expr The mathematical expression to convert.
- * @param classLoader The parent class loader.
- * @return A Calc object capable of evaluating the expression.
- */
- public static Calc convert(final ClassLoader classLoader, final String expr) {
- EvalExpressionResolver expressionResolver = new EvalExpressionResolver();
- Expression expression = expressionResolver.resolve(expr);
- CodeGeneratorContext ctx = new CodeGeneratorContext();
- expression.accept(new EvalCodeGenerator(ctx));
- String className = "Calc$" + COUNTER.incrementAndGet();
- return compile(classLoader, className, evalCode(ctx, className));
- }
-
- // ======================================================================================
- // ----------------------------------- private helper -----------------------------------
-
- private static String evalCode(final CodeGeneratorContext ctx, final String className) {
- return "public class "
- + className
- + " implements "
- + Calc.class.getCanonicalName()
- + " {\n"
- + "\n"
- + " "
- + ctx.reuseMemberCode()
- + "\n"
- + "\n"
- + " @Override\n"
- + " public Object eval(java.util.Map<String, Object> data) {\n"
- + " "
- + ctx.reuseLocalVariableCode()
- + "\n"
- + " "
- + ctx.evalCode()
- + "\n"
- + " return "
- + ctx.resultTerm()
- + ";\n"
- + " }\n"
- + " }";
- }
-
- private static Calc compile(
- final ClassLoader classLoader, final String className, final String code) {
- SimpleCompiler compiler = new SimpleCompiler();
- compiler.setParentClassLoader(classLoader);
- try {
- compiler.cook(code);
- return compiler.getClassLoader()
- .loadClass(className)
- .asSubclass(Calc.class)
- .getConstructor()
- .newInstance();
- } catch (Exception e) {
- throw new InvalidProgramException(
- "Calc program cannot be compiled. Please check expression syntax.");
- }
- }
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/CodeGeneratorContext.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/CodeGeneratorContext.java
deleted file mode 100644
index cbea78b..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/CodeGeneratorContext.java
+++ /dev/null
@@ -1,195 +0,0 @@
-package com.geedgenetworks.core.expressions.codegen;
-
-import javax.annotation.Nullable;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Provides a context for generating code and managing reusable variables and statements.
- *
- * @author chaoc
- * @since 1.0
- */
-public class CodeGeneratorContext {
-
- public static final String PARAM_NAME = "data";
-
- private static final String FIELD_PREFIX = "value";
-
- private final AtomicLong nameCounter = new AtomicLong(0);
-
- private final Map<Object, String> reusableMember = new HashMap<>();
-
- private final List<String> reusableMemberStatement = new ArrayList<>();
-
- private final Map<Object, String> reusableLocalVariable = new HashMap<>();
-
- private final List<String> reusableLocalVariableStatements = new ArrayList<>();
-
- private final List<String> evalCodeStatements = new ArrayList<>();
-
- /**
- * Adds a local variable statement to the context.
- *
- * @param statement The statement to add.
- */
- public void addLocalVariable(final String statement) {
- this.reusableLocalVariableStatements.add(statement);
- }
-
- /**
- * Adds a reusable constant to the context and returns its name.
- *
- * @param value The constant value to add.
- * @return The name of the added constant.
- */
- public String addReusableConstant(final Object value) {
- if (reusableMember.containsKey(value)) {
- return reusableMember.get(value);
- } else {
- String newName = newName();
- reusableMember.put(value, newName);
- String code =
- String.format(
- "private final %s %s = %s;",
- value.getClass().getCanonicalName(), newName, encodingValue(value));
- reusableMemberStatement.add(code);
- return newName;
- }
- }
-
- /**
- * Adds a reusable local variable to the context and returns its name.
- *
- * @param value The local variable value to add.
- * @return The name of the added local variable.
- */
- public String addReusableLocalVariable(final String value) {
- if (reusableLocalVariable.containsKey(value)) {
- return reusableLocalVariable.get(value);
- } else {
- String newName = newName();
- reusableLocalVariable.put(value, newName);
- addLocalVariable("final " + Object.class.getCanonicalName() + " " + newName + ";");
- return newName;
- }
- }
-
- /**
- * Returns the code for reusing local variables.
- *
- * @return The code for reusing local variables.
- */
- public String reuseLocalVariableCode() {
- return String.join("\n", reusableLocalVariableStatements);
- }
-
- /**
- * Returns the code for reusing member variables.
- *
- * @return The code for reusing member variables.
- */
- public String reuseMemberCode() {
- return String.join("\n", reusableMemberStatement);
- }
-
- /**
- * Returns the code for evaluating expressions.
- *
- * @return The code for evaluating expressions.
- */
- public String evalCode() {
- return String.join("\n", evalCodeStatements);
- }
-
- /**
- * Adds evaluation code statements to the context.
- *
- * @param statement The evaluation code statement to add.
- */
- public void addEvalCodeStatements(final String statement) {
- this.evalCodeStatements.add(statement);
- }
-
- /**
- * Create a new name for variables.
- *
- * @param prefix The prefix used for field name.
- * @return The field name.
- */
- public String newName(String prefix) {
- return prefix + nameCounter.incrementAndGet();
- }
-
- /**
- * Create a new name for variables.
- *
- * @return The field name.
- */
- public String newName() {
- return newName(FIELD_PREFIX);
- }
-
- /**
- * Get result field name.
- *
- * @return The name be used at last time.
- */
- public String resultTerm() {
- return FIELD_PREFIX + nameCounter.get();
- }
-
- public String addLocalBoolVariable() {
- return this.addLocalBoolVariable(false);
- }
-
- public String addLocalBoolVariable(boolean isFinal) {
- return this.addLocalVariable(isFinal, Boolean.class, false);
- }
-
- public String addLocalObjectVariable() {
- return this.addLocalObjectVariable(false);
- }
-
- public String addLocalObjectVariable(boolean isFinal) {
- return this.addLocalVariable(isFinal, Object.class, null);
- }
-
- // ======================================================================================
- // ----------------------------------- private helper -----------------------------------
-
- private String encodingValue(final Object value) {
- if (value instanceof String) {
- return String.format("\"%s\"", value);
- } else if (value instanceof Integer) {
- return String.format(String.format("java.lang.Integer.valueOf(%s)", value));
- } else if (value instanceof Long) {
- return String.format(String.format("java.lang.Long.valueOf(%sL)", value));
- } else if (value instanceof Double) {
- return String.format(String.format("java.lang.Double.valueOf(%s)", value));
- } else if (value instanceof BigDecimal) {
- return String.format(String.format("java.math.BigDecimal.valueOf(%s)", value));
- } else if (value instanceof Boolean) {
- return String.format(String.format("java.lang.Boolean.valueOf(%s)", value));
- } else {
- return value.toString();
- }
- }
-
- private String addLocalVariable(boolean isFinal, Class<?> type, @Nullable Object initValue) {
- String name = newName();
- String code = isFinal ? "final " : "";
- code += type.getCanonicalName();
- code += " " + name;
- if (initValue != null) {
- code += " = " + initValue;
- }
- this.addLocalVariable(code + ";");
- return name;
- }
-}
diff --git a/groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/EvalCodeGenerator.java b/groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/EvalCodeGenerator.java
deleted file mode 100644
index 5bb924c..0000000
--- a/groot-core/src/main/java/com/geedgenetworks/core/expressions/codegen/EvalCodeGenerator.java
+++ /dev/null
@@ -1,236 +0,0 @@
-package com.geedgenetworks.core.expressions.codegen;
-
-import com.geedgenetworks.core.expressions.*;
-
-import static com.geedgenetworks.core.expressions.codegen.CodeGeneratorContext.PARAM_NAME;
-
-/**
- * Generating evaluation code for expressions.
- *
- * @author chaoc
- * @since 1.0
- */
-public class EvalCodeGenerator implements ExpressionVisitor<String> {
-
- private final CodeGeneratorContext ctx;
-
- /**
- * Creates a new EvalCodeGenerator instance with the given code generation context.
- *
- * @param ctx The CodeGeneratorContext to use for code generation.
- */
- public EvalCodeGenerator(final CodeGeneratorContext ctx) {
- this.ctx = ctx;
- }
-
- @Override
- public String visit(Expression expression) {
- if (expression instanceof BooleanExpression) {
- return visit((BooleanExpression) expression);
- } else if (expression instanceof ValueExpression) {
- return visit((ValueExpression) expression);
- }
- throw new IllegalArgumentException("Unsupported expression type, " + expression.getClass());
- }
-
- @Override
- public String visit(ValueExpression expression) {
- if (expression instanceof ValueExpression.FieldRefExpression) {
- return visit((ValueExpression.FieldRefExpression) expression);
- } else if (expression instanceof ValueExpression.StringConstantExpression) {
- return visit((ValueExpression.StringConstantExpression) expression);
- } else if (expression instanceof ValueExpression.NumberConstantExpression) {
- return visit((ValueExpression.NumberConstantExpression) expression);
- } else if (expression instanceof ValueExpression.BooleanConstantExpression) {
- return visit((ValueExpression.BooleanConstantExpression) expression);
- } else if (expression instanceof ValueExpression.ArithmeticExpression) {
- return visit((ValueExpression.ArithmeticExpression) expression);
- } else if (expression instanceof ValueExpression.TernaryExpression) {
- return visit((ValueExpression.TernaryExpression) expression);
- }
- throw new IllegalArgumentException("Unsupported expression type, " + expression.getClass());
- }
-
- @Override
- public String visit(ValueExpression.FieldRefExpression expression) {
- String term = ctx.addReusableLocalVariable(expression.getFieldName());
- ctx.addEvalCodeStatements(
- String.format("%s = %s.get(\"%s\");", term, PARAM_NAME, expression.getFieldName()));
- return term;
- }
-
- @Override
- public String visit(ValueExpression.StringConstantExpression expression) {
- return ctx.addReusableConstant(expression.getValue());
- }
-
- @Override
- public String visit(ValueExpression.NumberConstantExpression expression) {
- return ctx.addReusableConstant(expression.getValue());
- }
-
- @Override
- public String visit(ValueExpression.BooleanConstantExpression expression) {
- return ctx.addReusableConstant(expression.getValue());
- }
-
- @Override
- public String visit(ValueExpression.ArithmeticExpression expression) {
- ArithmeticOperator operator = expression.getOperator();
- String leftTerm = visit(expression.getLeft());
- String rightTerm = visit(expression.getRight());
-
- // Only Plus
- String value1 = ctx.addLocalObjectVariable(true);
- String value2 = ctx.addLocalObjectVariable(true);
-
- String name = ctx.addLocalObjectVariable(false);
- String code = name + " = ";
- switch (operator) {
- case PLUS:
- code += "null;\n";
-
- code += String.format("%s = %s;", value1, leftTerm);
- code += String.format("%s = %s;", value2, rightTerm);
-
- code += String.format("if ( (%s instanceof java.lang.String) || (%s instanceof java.lang.String) ) {\n" +
- "%s = %s.toString() + %s.toString();\n" +
- "}", value1, value2, name, value1, value2);
- code += String.format("else if ( (%s instanceof java.lang.Number) && (%s instanceof java.lang.Number) ) {\n" +
- "%s = ((java.lang.Number)%s).intValue() + ((java.lang.Number)%s).intValue();\n" +
- "}", value1, value2, name, value1, value2);
- code += String.format("else {" +
- "throw new com.geedgenetworks.core.expressions.InvalidProgramException(" +
- "\"Addition operation is not supported, values: [\" + %s + \", \" + %s + \"]\");\n" +
- "}\n", value1, value2);
- break;
- case ASTERISK:
- code += String.format("%s * %s", leftTerm, rightTerm);
- break;
- case MINUS:
- code += String.format("((java.lang.Number)%s).intValue() - ((java.lang.Number)%s).intValue()", leftTerm, rightTerm);
- break;
- case PERCENT:
- code += leftTerm + " % " + rightTerm;
- break;
- case SLASH:
- code += String.format("%s / %s", leftTerm, rightTerm);
- break;
- case LEFT_SHIFT:
- code += String.format("((java.lang.Integer)%s).intValue() << ((java.lang.Integer)%s).intValue()", leftTerm, rightTerm);
- break;
- case RIGHT_SHIFT:
- code += String.format("((java.lang.Integer)%s).intValue() >> ((java.lang.Integer)%s).intValue()", leftTerm, rightTerm);
- break;
- case BITWISE_AND:
- code += String.format("((java.lang.Integer)%s).intValue() & ((java.lang.Integer)%s).intValue()", leftTerm, rightTerm);
- break;
- case BITWISE_OR:
- code += String.format("((java.lang.Integer)%s).intValue() | ((java.lang.Integer)%s).intValue()", leftTerm, rightTerm);
- break;
- }
- ctx.addEvalCodeStatements(code + ";");
- return name;
- }
-
- @Override
- public String visit(ValueExpression.TernaryExpression expression) {
- String boolTerm = visit(expression.getExpression());
- String trueValueTerm = visit(expression.getTrueValue());
- String falseValueTerm = visit(expression.getFalseValue());
- String name = ctx.addLocalObjectVariable();
- ctx.addEvalCodeStatements(
- String.format(
- "%s = (%s) ? %s : %s;", name, boolTerm, trueValueTerm, falseValueTerm));
- return name;
- }
-
- @Override
- public String visit(BooleanExpression expression) {
- if (expression instanceof BooleanExpression.ComparisonExpression) {
- return visit((BooleanExpression.ComparisonExpression) expression);
- } else if (expression instanceof BooleanExpression.PredicateExpression) {
- return visit((BooleanExpression.PredicateExpression) expression);
- } else if (expression instanceof BooleanExpression.NotExpression) {
- return visit((BooleanExpression.NotExpression) expression);
- }
- throw new IllegalArgumentException("Unsupported expression type, " + expression.getClass());
- }
-
- @Override
- public String visit(BooleanExpression.ComparisonExpression expression) {
- String leftTerm = visit(expression.getLeft());
- String rightTerm = visit(expression.getRight());
- String term = ctx.addLocalBoolVariable();
- String code = String.format("%s = %s;", term, false);
- String temp =
- "if ( "
- + leftTerm
- + " instanceof java.lang.Number && "
- + rightTerm
- + " instanceof java.lang.Number ) {\n"
- + " "
- + term
- + " = ( (java.lang.Number) "
- + leftTerm
- + " ).doubleValue()"
- + " %s ( (java.lang.Number) "
- + rightTerm
- + " ).doubleValue();\n"
- + "}";
- switch (expression.getOperator()) {
- case EQ:
- code =
- String.format(
- "%s = java.util.Objects.equals(%s, %s);",
- term, leftTerm, rightTerm);
- break;
- case NEQ:
- code =
- String.format(
- "%s = !java.util.Objects.equals(%s, %s);",
- term, leftTerm, rightTerm);
- break;
- case LTE:
- code = String.format(temp, "<=");
- break;
- case LT:
- code = String.format(temp, "<");
- break;
- case GTE:
- code = String.format(temp, ">=");
- break;
- case GT:
- code = String.format(temp, ">");
- break;
- }
- ctx.addEvalCodeStatements(code);
- return term;
- }
-
- @Override
- public String visit(BooleanExpression.PredicateExpression expression) {
- String leftTerm = visit(expression.getLeft());
- String rightTerm = visit(expression.getRight());
- String term = ctx.addLocalBoolVariable();
- String code = "";
- switch (expression.getOperator()) {
- case AND:
- code = String.format("%s = %s && %s;", term, leftTerm, rightTerm);
- break;
- case OR:
- code = String.format("%s = %s || %s;", term, leftTerm, rightTerm);
- break;
- }
- ctx.addEvalCodeStatements(code);
- return term;
- }
-
- @Override
- public String visit(BooleanExpression.NotExpression expression) {
- String term = visit(expression.getExpression());
- String retTerm = ctx.addLocalBoolVariable();
- ctx.addEvalCodeStatements(String.format("%s = ! %s;", retTerm, term));
- return retTerm;
- }
-}
diff --git a/groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/EvalExpressionResolverTest.java b/groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/EvalExpressionResolverTest.java
deleted file mode 100644
index ccfa03e..0000000
--- a/groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/EvalExpressionResolverTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.geedgenetworks.core.udf.test.eval;
-
-import com.geedgenetworks.core.expressions.*;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import java.math.BigDecimal;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-class EvalExpressionResolverTest {
-
- private static EvalExpressionResolver resolver;
-
- @BeforeAll
- public static void setUp() {
- resolver = new EvalExpressionResolver();
- }
-
- @Test
- public void testValueExpression() {
- // constant
- assertEquals(resolver.resolve("'name'"), new ValueExpression.StringConstantExpression("name"));
- assertEquals(resolver.resolve("5"), new ValueExpression.NumberConstantExpression(5));
- assertEquals(resolver.resolve("5L"), new ValueExpression.NumberConstantExpression(5L));
- assertEquals(resolver.resolve("5D"), new ValueExpression.NumberConstantExpression((double) 5L));
- assertEquals(resolver.resolve("5BD"), new ValueExpression.NumberConstantExpression(BigDecimal.valueOf(5)));
- assertEquals(resolver.resolve("TRUE"), new ValueExpression.BooleanConstantExpression(true));
- assertEquals(resolver.resolve("FALSE"), new ValueExpression.BooleanConstantExpression(false));
-
- // variable
- assertEquals(resolver.resolve("common_client_ip"),
- new ValueExpression.FieldRefExpression("common_client_ip"));
- assertEquals(resolver.resolve("common_client_port"),
- new ValueExpression.FieldRefExpression("common_client_port"));
- }
-
- @Test
- public void testConditionExpression() {
-
- assertEquals(
- resolver.resolve("common_client_port > common_server_port ? common_c2s_pkt_num : common_s2c_pkt_num"),
- new ValueExpression.TernaryExpression(
- new BooleanExpression.ComparisonExpression(ComparisonOperator.GT,
- new ValueExpression.FieldRefExpression("common_client_port"),
- new ValueExpression.FieldRefExpression("common_server_port")),
- new ValueExpression.FieldRefExpression("common_c2s_pkt_num"),
- new ValueExpression.FieldRefExpression("common_s2c_pkt_num"))
- );
- assertEquals(
- resolver.resolve("common_client_port > common_server_port " +
- "? 'C2S:' + common_c2s_pkt_num : 'S2C:' + common_s2c_pkt_num"),
- new ValueExpression.TernaryExpression(
- new BooleanExpression.ComparisonExpression(ComparisonOperator.GT,
- new ValueExpression.FieldRefExpression("common_client_port"),
- new ValueExpression.FieldRefExpression("common_server_port")),
- new ValueExpression.ArithmeticExpression(ArithmeticOperator.PLUS,
- new ValueExpression.StringConstantExpression("C2S:"),
- new ValueExpression.FieldRefExpression("common_c2s_pkt_num")),
- new ValueExpression.ArithmeticExpression(ArithmeticOperator.PLUS,
- new ValueExpression.StringConstantExpression("S2C:"),
- new ValueExpression.FieldRefExpression("common_s2c_pkt_num")))
- );
- assertEquals(
- resolver.resolve("common_c2s_pkt_num > common_s2c_pkt_num " +
- "&& common_c2s_byte_num > common_s2c_byte_num ? common_client_port : common_server_port"),
- new ValueExpression.TernaryExpression(
- new BooleanExpression.PredicateExpression(PredicateOperator.AND,
- new BooleanExpression.ComparisonExpression(ComparisonOperator.GT,
- new ValueExpression.FieldRefExpression("common_c2s_pkt_num"),
- new ValueExpression.FieldRefExpression("common_s2c_pkt_num")),
- new BooleanExpression.ComparisonExpression(ComparisonOperator.GT,
- new ValueExpression.FieldRefExpression("common_c2s_byte_num"),
- new ValueExpression.FieldRefExpression("common_s2c_byte_num"))),
- new ValueExpression.FieldRefExpression("common_client_port"),
- new ValueExpression.FieldRefExpression("common_server_port"))
- );
- assertEquals(
- resolver.resolve("common_c2s_pkt_num & 2"),
- new ValueExpression.ArithmeticExpression(
- ArithmeticOperator.BITWISE_AND,
- new ValueExpression.FieldRefExpression("common_c2s_pkt_num"),
- new ValueExpression.NumberConstantExpression(2)
- )
- );
- }
-
-
-} \ No newline at end of file
diff --git a/groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/codegen/CalcCodeConvertorTest.java b/groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/codegen/CalcCodeConvertorTest.java
deleted file mode 100644
index 01ef9db..0000000
--- a/groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/codegen/CalcCodeConvertorTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package com.geedgenetworks.core.udf.test.eval.codegen;
-
-import com.geedgenetworks.core.expressions.Calc;
-import com.geedgenetworks.core.expressions.InvalidProgramException;
-import com.geedgenetworks.core.expressions.SyntaxErrorException;
-import com.geedgenetworks.core.expressions.codegen.CalcCodeConvertor;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import java.math.BigDecimal;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class CalcCodeConvertorTest {
-
- private static Map<String, Object> origin;
-
- @BeforeAll
- public static void setUp() {
- origin = new HashMap<>();
- origin.put("common_schema_type", "RTP");
- origin.put("common_sessions", 1);
- origin.put("common_stream_dir", 3);
- origin.put("common_vsys_id", 24);
-
- origin.put("common_server_ip", "172.17.200.50");
- origin.put("common_server_port", 36682);
- origin.put("common_s2c_byte_num", 7570);
- origin.put("common_s2c_pkt_num", 5);
-
- origin.put("common_client_ip", "172.17.201.16");
- origin.put("common_client_port", 42924);
- origin.put("common_c2s_byte_num", 1834);
- origin.put("common_c2s_pkt_num", 6);
-
- origin.put("common_out_dest_mac", "02:fc:08:dc:92:d7");
- origin.put("common_out_src_mac", "02:fc:08:dc:91:c3");
- }
-
- @Test
- public void testValueExpression() throws Exception {
- // constant
- assertEquals(CalcCodeConvertor.convert("'name'").eval(origin), "name");
- assertEquals(CalcCodeConvertor.convert("5").eval(origin), 5);
- assertEquals(CalcCodeConvertor.convert("5L").eval(origin), 5L);
- assertEquals(CalcCodeConvertor.convert("5D").eval(origin), (double) 5L);
- assertEquals(CalcCodeConvertor.convert("5BD").eval(origin), BigDecimal.valueOf(5));
- assertEquals(CalcCodeConvertor.convert("TRUE").eval(origin), true);
- assertEquals(CalcCodeConvertor.convert("FALSE").eval(origin), false);
-
- // variable
- assertEquals(CalcCodeConvertor.convert("common_client_ip").eval(origin),
- origin.get("common_client_ip"));
- assertEquals(CalcCodeConvertor.convert("common_client_port").eval(origin),
- origin.get("common_client_port"));
- }
-
- @Test
- public void testConditionExpression() throws Exception {
- int commonClientPort = (int) origin.get("common_client_port");
- int commonServerPort = (int) origin.get("common_server_port");
- int commonC2sPktNum = (int) origin.get("common_c2s_pkt_num");
- int commonS2cPktNum = (int) origin.get("common_s2c_pkt_num");
- int commonC2sByteNum = (int) origin.get("common_c2s_byte_num");
- int commonS2cByteNum = (int) origin.get("common_s2c_byte_num");
- assertEquals(
- CalcCodeConvertor.convert("common_client_port > common_server_port " +
- "? common_c2s_pkt_num : common_s2c_pkt_num").eval(origin),
- commonClientPort > commonServerPort ? commonC2sPktNum : commonS2cPktNum);
- assertEquals(
- CalcCodeConvertor.convert("common_client_port > common_server_port " +
- "? 'C2S:' + common_c2s_pkt_num : 'S2C:' + common_s2c_pkt_num").eval(origin),
- commonClientPort > commonServerPort ? "C2S:" + commonC2sPktNum : "S2C:" + commonS2cPktNum);
- assertEquals(
- CalcCodeConvertor.convert("common_c2s_pkt_num > common_s2c_pkt_num " +
- "&& common_c2s_byte_num > common_s2c_byte_num ? common_client_port : common_server_port").eval(origin),
- commonC2sPktNum > commonS2cPktNum
- && commonC2sByteNum > commonS2cByteNum ? commonClientPort : commonServerPort
- );
-
- }
-
- @Test
- public void testArithmeticExpression() throws Exception {
- final Map<String, Object> map = Collections.emptyMap();
- assertEquals(
- 1, CalcCodeConvertor.convert("5 & 3").eval(map));
- assertEquals(
- 7, CalcCodeConvertor.convert("5 | 3").eval(map));
- assertEquals(
- 20, CalcCodeConvertor.convert("5 << 2").eval(map));
- assertEquals(
- 1, CalcCodeConvertor.convert("5 >> 2").eval(map));
- assertEquals(
- 8, CalcCodeConvertor.convert("5 + 3").eval(map));
- assertEquals(
- 2, CalcCodeConvertor.convert("5 - 3").eval(map));
- assertEquals(
- 15, CalcCodeConvertor.convert("5 * 3").eval(map));
- assertEquals(
- 2, CalcCodeConvertor.convert("5 / 2").eval(map));
- assertEquals(
- 2, CalcCodeConvertor.convert("5 % 3").eval(map));
-
-
- final Map<String, Object> map1 = new HashMap<>();
- map1.put("flags", 8);
-
- assertEquals("B",
- CalcCodeConvertor.convert(" flags & 8 == 9 ? 'A' : 'B'").eval(map1));
- assertEquals("A",
- CalcCodeConvertor.convert(" 5 | flags == 13 ? 'A' : 'B'").eval(map1));
- }
-
- @Test
- public void testFieldArithmeticExpression() throws Exception {
- assertEquals(1,
- CalcCodeConvertor.convert("common_c2s_pkt_num - common_s2c_pkt_num").eval(origin));
-
- assertEquals(17, CalcCodeConvertor.convert("common_c2s_pkt_num + 10 + 1D").eval(origin));
-
- }
-
- @Test
- public void testError() {
- assertThrows(SyntaxErrorException.class,
- () -> CalcCodeConvertor.convert("common_c2s_pkt_num > common_s2c_pkt_num"));
- assertThrows(SyntaxErrorException.class,
- () -> CalcCodeConvertor.convert("2 = 3"));
-
- final Map<String, Object> map = new HashMap<>(origin);
- map.put("has_address", true);
- Calc convert = CalcCodeConvertor.convert("common_c2s_pkt_num + has_address");
- assertThrows(InvalidProgramException.class, () -> convert.eval(map));
- }
-} \ No newline at end of file
diff --git a/groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/codegen/EvalCodeGeneratorTest.java b/groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/codegen/EvalCodeGeneratorTest.java
deleted file mode 100644
index bfbf323..0000000
--- a/groot-core/src/test/java/com/geedgenetworks/core/udf/test/eval/codegen/EvalCodeGeneratorTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.geedgenetworks.core.udf.test.eval.codegen;
-
-
-import com.geedgenetworks.core.expressions.EvalExpressionResolver;
-import com.geedgenetworks.core.expressions.Expression;
-import com.geedgenetworks.core.expressions.codegen.CodeGeneratorContext;
-import com.geedgenetworks.core.expressions.codegen.EvalCodeGenerator;
-import org.apache.commons.lang3.StringUtils;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class EvalCodeGeneratorTest {
-
- private static EvalExpressionResolver resolver;
-
- @BeforeAll
- public static void setUp() {
- resolver = new EvalExpressionResolver();
- }
-
- @Test
- public void testCodeGen() {
- Expression expression = resolver.resolve("common_client_port > common_server_port " +
- " ? 'C2S:' + common_c2s_pkt_num : 'S2C:' + common_s2c_pkt_num");
- CodeGeneratorContext context = new CodeGeneratorContext();
- expression.accept(new EvalCodeGenerator(context));
- String memberCode = context.reuseMemberCode();
- assertTrue(StringUtils.contains(memberCode, "C2S:"));
- assertTrue(StringUtils.contains(memberCode, "S2C:"));
- }
-
-}