Class Evaluator
- All Implemented Interfaces:
GJVisitor<Object,
EvalContext>
- Direct Known Subclasses:
SqlGenerator
Each visit() method in this class takes two parameters, the first being the node being visited, and the second contains an EvalContext object containing the variables and functions which can be referenced within the expression. The visitor (i.e. this class) is then passed to it's children nodes using the nodes' accept() method (generated by jtb).
Variables can be any wrappered primitive type (e.g. Long, Integer, ...), although mathematical evaluation (+, -, /, etc) are currently only implemented for Doubles and Longs.
This class can be considered thread-safe, since it holds no instance-wide state. (All methods that require access to a EvalContext have it passed in through a method parameter). i.e. many threads may use the same Evaluator instance to evaluate different expressions.
NB: In the javadocs below, "lhs" refers to the left-hand-side value of any binary operation, and "rhs" refers to the right-hand-side value; e.g. in "3 + 4", the lhs is "3", the rhs is "4" and the op is "+".
- Author:
- knoxg
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptioncoerceType
(Object a, Object b) Coerce parameter 'b' into a compatible type of parameter 'a', to be used in a binary math op.mathOp
(Object a, Object b, String op, com.randomnoun.common.jexl.eval.Evaluator.BinaryOp longOp, com.randomnoun.common.jexl.eval.Evaluator.BinaryOp doubleOp) Binary math operation.visit
(AdditiveExpression n, EvalContext context) Evaluate a AdditiveExpression node.visit
(ArgumentList n, EvalContext context) Evaluate a ArgumentList node.visit
(Arguments n, EvalContext context) Evaluates an Arguments nodevisit
(BooleanLiteral n, EvalContext context) Evaluate a BooleanLiteral node.visit
(ConditionalAndExpression n, EvalContext context) Evaluate a ConditionalAndExpression node.visit
(EqualityExpression n, EvalContext context) Evaluate a EqualityExpression node.visit
(Expression n, EvalContext context) Evaluate an Expression node.visit
(FunctionCall n, EvalContext context) Evaluate a FunctionCall node.visit
(Literal n, EvalContext context) Evaluate a Literal node.visit
(MultiplicativeExpression n, EvalContext context) Evaluate a MultiplicativeExpression node.visit
(Name n, EvalContext context) Evaluate a Name node.visit
(NodeToken n, EvalContext context) This is never executed (we do not evaluate tokens)visit
(NullLiteral n, EvalContext context) Evaluate a NullLiteral node.visit
(PrimaryExpression n, EvalContext context) Evaluate a PrimaryExpression node.visit
(RelationalExpression n, EvalContext context) Evaluate a RelationalExpression node.visit
(TopLevelExpression n, EvalContext context) Evaluate a TopLevelExpression node.visit
(UnaryExpression n, EvalContext context) Evaluate a UnaryExpression node.Methods inherited from class com.randomnoun.common.jexl.visitor.GJDepthFirst
visit, visit, visit, visit
-
Constructor Details
-
Evaluator
public Evaluator()
-
-
Method Details
-
coerceType
Coerce parameter 'b' into a compatible type of parameter 'a', to be used in a binary math op. If 'b' can't be coerced into 'a', then throw an EvalException.- Parameters:
a
- First binary op parameter (the type of which we are casting to)b
- Second binary op parameter (the value we are casting)- Returns:
- The value of 'b', coerced to be the same type of value 'a'
-
mathOp
public Object mathOp(Object a, Object b, String op, com.randomnoun.common.jexl.eval.Evaluator.BinaryOp longOp, com.randomnoun.common.jexl.eval.Evaluator.BinaryOp doubleOp) Binary math operation. Takes two parameters, the name of the op (only used in exception text), and BinaryOp classes for all supported types. (We only support math operations on Longs and Doubles at the moment, should be easy to add new types if required). If we were aiming for completeness, I'd implement Short, Int, Byte, Char, BigInteger and BigDecimal.The rhs of the expression is coerced into the type of the lhs.
- Parameters:
a
- lhs parameterb
- rhs parameterop
- name of oplongOp
- operation to perform if lhs is LongdoubleOp
- operation to perform if lhs in Double- Returns:
- the evaluated result of the op
-
visit
Evaluate a TopLevelExpression node. The PRE text in this javadoc corresponds to the javacc expansion of this node; e.g. in expression.jj, the rule for TopLevelExpression isvoid TopLevelExpression(): {} { Expression()
} jtb then creates two fields in the TopLevelExpression object, "expression" (containing the Expression() node) and "nodeToken" (containing the EOF token). This is documented in the form below (this is included for all jtb-generated visit methods):
expression -> Expression() nodeToken -> <EOF>
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate an Expression node.conditionalAndExpression -> ConditionalAndExpression() nodeListOptional -> ( "||" ConditionalAndExpression() )*
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a ConditionalAndExpression node.equalityExpression -> EqualityExpression() nodeListOptional -> ( "invalid input: '&'invalid input: '&'" EqualityExpression() )*
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a EqualityExpression node.relationalExpression -> RelationalExpression() nodeListOptional -> ( ( "==" | "!=" ) RelationalExpression() )*
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a RelationalExpression node.additiveExpression -> AdditiveExpression() nodeListOptional -> ( ( "<" | ">" | "<=" | ">=" ) AdditiveExpression() )*
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a AdditiveExpression node.multiplicativeExpression -> MultiplicativeExpression() nodeListOptional -> ( ( "+" | "-" ) MultiplicativeExpression() )*
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a MultiplicativeExpression node.unaryExpression -> UnaryExpression() nodeListOptional -> ( ( "*" | "/" | "%" ) UnaryExpression() )*
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a UnaryExpression node.nodeChoice -> ( "~" | "!" | "-" ) UnaryExpression() | PrimaryExpression()
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a PrimaryExpression node.nodeChoice -> FunctionCall() | Name() | Literal() | "(" Expression() ")"
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a Name node.nodeToken -> <IDENTIFIER> nodeListOptional -> ( "." <IDENTIFIER> )*
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a FunctionCall node.nodeToken -> <IDENTIFIER> arguments -> Arguments()
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluates an Arguments nodenodeToken -> "(" nodeOptional -> [ ArgumentList() ] nodeToken1 -> ")"
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a ArgumentList node.expression -> Expression() nodeListOptional -> ( "," Expression() )*
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a Literal node.nodeChoice -> <INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> | <CHARACTER_LITERAL> | <STRING_LITERAL> | BooleanLiteral() | NullLiteral()
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a BooleanLiteral node.nodeChoice -> "true" | "false"
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
Evaluate a NullLiteral node.nodeToken -> "null"
- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-
visit
This is never executed (we do not evaluate tokens)- Specified by:
visit
in interfaceGJVisitor<Object,
EvalContext> - Overrides:
visit
in classGJDepthFirst<Object,
EvalContext>
-