com.espertech.esper.epl.parse.ASTExprHelper Maven / Gradle / Ivy
/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.epl.parse;
import com.espertech.esper.client.ConfigurationInformation;
import com.espertech.esper.epl.expression.core.*;
import com.espertech.esper.epl.expression.ops.ExprEqualsNode;
import com.espertech.esper.epl.expression.ops.ExprEqualsNodeImpl;
import com.espertech.esper.epl.expression.ops.ExprMathNode;
import com.espertech.esper.epl.expression.time.ExprTimePeriod;
import com.espertech.esper.epl.expression.time.ExprTimePeriodImpl;
import com.espertech.esper.epl.expression.time.TimeAbacus;
import com.espertech.esper.epl.generated.EsperEPL2GrammarLexer;
import com.espertech.esper.epl.generated.EsperEPL2GrammarParser;
import com.espertech.esper.epl.spec.OnTriggerSetAssignment;
import com.espertech.esper.epl.spec.StatementSpecRaw;
import com.espertech.esper.epl.variable.VariableMetaData;
import com.espertech.esper.epl.variable.VariableService;
import com.espertech.esper.epl.variable.VariableServiceUtil;
import com.espertech.esper.pattern.EvalFactoryNode;
import com.espertech.esper.rowregex.RowRegexExprNode;
import com.espertech.esper.type.MathArithTypeEnum;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.Tree;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
public class ASTExprHelper {
public static ExprNode resolvePropertyOrVariableIdentifier(String identifier, VariableService variableService, StatementSpecRaw spec) {
VariableMetaData metaData = variableService.getVariableMetaData(identifier);
if (metaData != null) {
ExprVariableNodeImpl exprNode = new ExprVariableNodeImpl(metaData, null);
spec.setHasVariables(true);
addVariableReference(spec, metaData.getVariableName());
String message = VariableServiceUtil.checkVariableContextName(spec.getOptionalContextName(), metaData);
if (message != null) {
throw ASTWalkException.from(message);
}
return exprNode;
} else {
return new ExprIdentNodeImpl(identifier);
}
}
public static void addVariableReference(StatementSpecRaw statementSpec, String variableName) {
if (statementSpec.getReferencedVariables() == null) {
statementSpec.setReferencedVariables(new HashSet());
}
statementSpec.getReferencedVariables().add(variableName);
}
public static ExprTimePeriod timePeriodGetExprAllParams(EsperEPL2GrammarParser.TimePeriodContext ctx, Map astExprNodeMap, VariableService variableService, StatementSpecRaw spec, ConfigurationInformation config, TimeAbacus timeAbacus) {
ExprNode[] nodes = new ExprNode[9];
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree unitRoot = ctx.getChild(i);
ExprNode valueExpr;
if (ASTUtil.isTerminatedOfType(unitRoot.getChild(0), EsperEPL2GrammarLexer.IDENT)) {
String ident = unitRoot.getChild(0).getText();
valueExpr = ASTExprHelper.resolvePropertyOrVariableIdentifier(ident, variableService, spec);
} else {
final AtomicReference ref = new AtomicReference();
ExprAction action = new ExprAction() {
public void found(ExprNode exprNode, Map astExprNodeMap, Tree node) {
astExprNodeMap.remove(node);
ref.set(exprNode);
}
};
ASTExprHelper.recursiveFindRemoveChildExprNode(unitRoot.getChild(0), astExprNodeMap, action);
valueExpr = ref.get();
}
if (ASTUtil.getRuleIndexIfProvided(unitRoot) == EsperEPL2GrammarParser.RULE_microsecondPart) {
nodes[8] = valueExpr;
}
if (ASTUtil.getRuleIndexIfProvided(unitRoot) == EsperEPL2GrammarParser.RULE_millisecondPart) {
nodes[7] = valueExpr;
}
if (ASTUtil.getRuleIndexIfProvided(unitRoot) == EsperEPL2GrammarParser.RULE_secondPart) {
nodes[6] = valueExpr;
}
if (ASTUtil.getRuleIndexIfProvided(unitRoot) == EsperEPL2GrammarParser.RULE_minutePart) {
nodes[5] = valueExpr;
}
if (ASTUtil.getRuleIndexIfProvided(unitRoot) == EsperEPL2GrammarParser.RULE_hourPart) {
nodes[4] = valueExpr;
}
if (ASTUtil.getRuleIndexIfProvided(unitRoot) == EsperEPL2GrammarParser.RULE_dayPart) {
nodes[3] = valueExpr;
}
if (ASTUtil.getRuleIndexIfProvided(unitRoot) == EsperEPL2GrammarParser.RULE_weekPart) {
nodes[2] = valueExpr;
}
if (ASTUtil.getRuleIndexIfProvided(unitRoot) == EsperEPL2GrammarParser.RULE_monthPart) {
nodes[1] = valueExpr;
}
if (ASTUtil.getRuleIndexIfProvided(unitRoot) == EsperEPL2GrammarParser.RULE_yearPart) {
nodes[0] = valueExpr;
}
}
ExprTimePeriod timeNode = new ExprTimePeriodImpl(config.getEngineDefaults().getExpression().getTimeZone(),
nodes[0] != null, nodes[1] != null, nodes[2] != null, nodes[3] != null, nodes[4] != null, nodes[5] != null, nodes[6] != null, nodes[7] != null, nodes[8] != null, timeAbacus);
for (ExprNode node : nodes) {
if (node != null) timeNode.addChildNode(node);
}
return timeNode;
}
public static ExprTimePeriod timePeriodGetExprJustSeconds(EsperEPL2GrammarParser.ExpressionContext expression, Map astExprNodeMap, ConfigurationInformation config, TimeAbacus timeAbacus) {
ExprNode node = exprCollectSubNodes(expression, 0, astExprNodeMap).get(0);
ExprTimePeriod timeNode = new ExprTimePeriodImpl(config.getEngineDefaults().getExpression().getTimeZone(),
false, false, false, false, false, false, true, false, false, timeAbacus);
timeNode.addChildNode(node);
return timeNode;
}
protected static List getOnTriggerSetAssignments(EsperEPL2GrammarParser.OnSetAssignmentListContext ctx, Map astExprNodeMap) {
if (ctx == null || ctx.onSetAssignment().isEmpty()) {
return Collections.emptyList();
}
List ctxs = ctx.onSetAssignment();
List assignments = new ArrayList(ctx.onSetAssignment().size());
for (EsperEPL2GrammarParser.OnSetAssignmentContext assign : ctxs) {
ExprNode childEvalNode;
if (assign.eventProperty() != null) {
ExprNode prop = ASTExprHelper.exprCollectSubNodes(assign.eventProperty(), 0, astExprNodeMap).get(0);
ExprNode value = ASTExprHelper.exprCollectSubNodes(assign.expression(), 0, astExprNodeMap).get(0);
ExprEqualsNode equals = new ExprEqualsNodeImpl(false, false);
equals.addChildNode(prop);
equals.addChildNode(value);
childEvalNode = equals;
} else {
childEvalNode = ASTExprHelper.exprCollectSubNodes(assign, 0, astExprNodeMap).get(0);
}
assignments.add(new OnTriggerSetAssignment(childEvalNode));
}
return assignments;
}
public static void patternCollectAddSubnodesAddParentNode(EvalFactoryNode evalNode, Tree node, Map astPatternNodeMap) {
if (evalNode == null) {
throw ASTWalkException.from("Invalid null expression node for '" + ASTUtil.printNode(node) + "'");
}
for (int i = 0; i < node.getChildCount(); i++) {
Tree childNode = node.getChild(i);
EvalFactoryNode childEvalNode = patternGetRemoveTopNode(childNode, astPatternNodeMap);
if (childEvalNode != null) {
evalNode.addChildNode(childEvalNode);
}
}
astPatternNodeMap.put(node, evalNode);
}
public static EvalFactoryNode patternGetRemoveTopNode(Tree node, Map astPatternNodeMap) {
EvalFactoryNode pattern = astPatternNodeMap.get(node);
if (pattern != null) {
astPatternNodeMap.remove(node);
return pattern;
}
for (int i = 0; i < node.getChildCount(); i++) {
pattern = patternGetRemoveTopNode(node.getChild(i), astPatternNodeMap);
if (pattern != null) {
return pattern;
}
}
return null;
}
public static void regExCollectAddSubNodesAddParentNode(RowRegexExprNode exprNode, Tree node, Map astRegExNodeMap) {
regExCollectAddSubNodes(exprNode, node, astRegExNodeMap);
astRegExNodeMap.put(node, exprNode);
}
public static void regExCollectAddSubNodes(final RowRegexExprNode regexNode, Tree node, Map astRegExNodeMap) {
if (regexNode == null) {
throw ASTWalkException.from("Invalid null expression node for '" + ASTUtil.printNode(node) + "'");
}
RegExAction action = new RegExAction() {
public void found(RowRegexExprNode exprNode, Map astRegExNodeMap, Tree node) {
astRegExNodeMap.remove(node);
regexNode.addChildNode(exprNode);
}
};
for (int i = 0; i < node.getChildCount(); i++) {
Tree childNode = node.getChild(i);
regExApplyActionRecursive(childNode, astRegExNodeMap, action);
}
}
public static void regExApplyActionRecursive(Tree node, Map astRegExNodeMap, RegExAction action) {
RowRegexExprNode expr = astRegExNodeMap.get(node);
if (expr != null) {
action.found(expr, astRegExNodeMap, node);
return;
}
for (int i = 0; i < node.getChildCount(); i++) {
regExApplyActionRecursive(node.getChild(i), astRegExNodeMap, action);
}
}
public static void exprCollectAddSubNodesAddParentNode(ExprNode exprNode, Tree node, Map astExprNodeMap) {
exprCollectAddSubNodes(exprNode, node, astExprNodeMap);
astExprNodeMap.put(node, exprNode);
}
public static void exprCollectAddSubNodes(final ExprNode parentNode, Tree node, Map astExprNodeMap) {
if (parentNode == null) {
throw ASTWalkException.from("Invalid null expression node for '" + ASTUtil.printNode(node) + "'");
}
if (node == null) {
return;
}
ExprAction action = new ExprAction() {
public void found(ExprNode exprNode, Map astExprNodeMap, Tree node) {
astExprNodeMap.remove(node);
parentNode.addChildNode(exprNode);
}
};
for (int i = 0; i < node.getChildCount(); i++) {
Tree childNode = node.getChild(i);
recursiveFindRemoveChildExprNode(childNode, astExprNodeMap, action);
}
}
public static void exprCollectAddSingle(final ExprNode parentNode, Tree node, Map astExprNodeMap) {
if (parentNode == null) {
throw ASTWalkException.from("Invalid null expression node for '" + ASTUtil.printNode(node) + "'");
}
if (node == null) {
return;
}
ExprAction action = new ExprAction() {
public void found(ExprNode exprNode, Map astExprNodeMap, Tree node) {
astExprNodeMap.remove(node);
parentNode.addChildNode(exprNode);
}
};
recursiveFindRemoveChildExprNode(node, astExprNodeMap, action);
}
public static void exprCollectAddSubNodesExpressionCtx(final ExprNode parentNode, List expressionContexts, Map astExprNodeMap) {
ExprAction action = new ExprAction() {
public void found(ExprNode exprNode, Map astExprNodeMap, Tree node) {
astExprNodeMap.remove(node);
parentNode.addChildNode(exprNode);
}
};
for (EsperEPL2GrammarParser.ExpressionContext ctx : expressionContexts) {
recursiveFindRemoveChildExprNode(ctx, astExprNodeMap, action);
}
}
public static List exprCollectSubNodes(Tree parentNode, int startIndex, Map astExprNodeMap) {
ExprNode selfNode = astExprNodeMap.remove(parentNode);
if (selfNode != null) {
return Collections.singletonList(selfNode);
}
final List exprNodes = new ArrayList();
ExprAction action = new ExprAction() {
public void found(ExprNode exprNode, Map astExprNodeMap, Tree node) {
astExprNodeMap.remove(node);
exprNodes.add(exprNode);
}
};
for (int i = startIndex; i < parentNode.getChildCount(); i++) {
Tree currentNode = parentNode.getChild(i);
recursiveFindRemoveChildExprNode(currentNode, astExprNodeMap, action);
}
return exprNodes;
}
private static void recursiveFindRemoveChildExprNode(Tree node, Map astExprNodeMap, ExprAction action) {
ExprNode expr = astExprNodeMap.get(node);
if (expr != null) {
action.found(expr, astExprNodeMap, node);
return;
}
for (int i = 0; i < node.getChildCount(); i++) {
recursiveFindRemoveChildExprNode(node.getChild(i), astExprNodeMap, action);
}
}
public static RowRegexExprNode regExGetRemoveTopNode(Tree node, Map astRowRegexNodeMap) {
RowRegexExprNode regex = astRowRegexNodeMap.get(node);
if (regex != null) {
astRowRegexNodeMap.remove(node);
return regex;
}
for (int i = 0; i < node.getChildCount(); i++) {
regex = regExGetRemoveTopNode(node.getChild(i), astRowRegexNodeMap);
if (regex != null) {
return regex;
}
}
return null;
}
public static ExprNode mathGetExpr(ParseTree ctx, Map astExprNodeMap, ConfigurationInformation configurationInformation) {
int count = 1;
ExprNode base = ASTExprHelper.exprCollectSubNodes(ctx.getChild(0), 0, astExprNodeMap).get(0);
while (true) {
int token = ASTUtil.getAssertTerminatedTokenType(ctx.getChild(count));
MathArithTypeEnum mathArithTypeEnum = tokenToMathEnum(token);
ExprNode right = ASTExprHelper.exprCollectSubNodes(ctx.getChild(count + 1), 0, astExprNodeMap).get(0);
ExprMathNode math = new ExprMathNode(mathArithTypeEnum,
configurationInformation.getEngineDefaults().getExpression().isIntegerDivision(),
configurationInformation.getEngineDefaults().getExpression().isDivisionByZeroReturnsNull());
math.addChildNode(base);
math.addChildNode(right);
base = math;
count += 2;
if (count >= ctx.getChildCount()) {
break;
}
}
return base;
}
private static MathArithTypeEnum tokenToMathEnum(int token) {
switch (token) {
case EsperEPL2GrammarLexer.DIV:
return MathArithTypeEnum.DIVIDE;
case EsperEPL2GrammarLexer.STAR:
return MathArithTypeEnum.MULTIPLY;
case EsperEPL2GrammarLexer.PLUS:
return MathArithTypeEnum.ADD;
case EsperEPL2GrammarLexer.MINUS:
return MathArithTypeEnum.SUBTRACT;
case EsperEPL2GrammarLexer.MOD:
return MathArithTypeEnum.MODULO;
default:
throw ASTWalkException.from("Encountered unrecognized math token type " + token);
}
}
public static void addOptionalNumber(ExprNode exprNode, EsperEPL2GrammarParser.NumberContext number) {
if (number == null) {
return;
}
ExprConstantNode constantNode = new ExprConstantNodeImpl(ASTConstantHelper.parse(number));
exprNode.addChildNode(constantNode);
}
public static void addOptionalSimpleProperty(ExprNode exprNode, Token token, VariableService variableService, StatementSpecRaw spec) {
if (token == null) {
return;
}
ExprNode node = ASTExprHelper.resolvePropertyOrVariableIdentifier(token.getText(), variableService, spec);
exprNode.addChildNode(node);
}
public static ExprNode[] exprCollectSubNodesPerNode(List expression, Map astExprNodeMap) {
ExprNode[] nodes = new ExprNode[expression.size()];
for (int i = 0; i < expression.size(); i++) {
nodes[i] = exprCollectSubNodes(expression.get(i), 0, astExprNodeMap).get(0);
}
return nodes;
}
private static interface ExprAction {
public void found(ExprNode exprNode, Map astExprNodeMap, Tree node);
}
private static interface RegExAction {
public void found(RowRegexExprNode exprNode, Map astRegExNodeMap, Tree node);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy