diff options
| author | chaochaoc <[email protected]> | 2024-07-23 11:26:47 +0800 |
|---|---|---|
| committer | chaochaoc <[email protected]> | 2024-07-23 11:26:47 +0800 |
| commit | c2d05f2f9ed79533e26afadfb6152cd3a79192b4 (patch) | |
| tree | 52b34bc7959f1d0a9e45a59e31f2a17543912996 | |
| parent | 0e8005ae3b8b45480e4d511c600700ac8de897ae (diff) | |
[GAL-625] feat: remove the impl of antlr4 Token method.
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:")); - } - -} |
