
com.alibaba.qlexpress4.runtime.operator.OperatorManager Maven / Gradle / Ivy
package com.alibaba.qlexpress4.runtime.operator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.qlexpress4.QLOptions;
import com.alibaba.qlexpress4.QLPrecedences;
import com.alibaba.qlexpress4.aparser.OperatorFactory;
import com.alibaba.qlexpress4.aparser.ParserOperatorManager;
import com.alibaba.qlexpress4.exception.ErrorReporter;
import com.alibaba.qlexpress4.exception.UserDefineException;
import com.alibaba.qlexpress4.runtime.QRuntime;
import com.alibaba.qlexpress4.runtime.Value;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.DivideAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.DivideOperator;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.MinusAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.MinusOperator;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.MultiplyAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.MultiplyOperator;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.PlusAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.PlusOperator;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.RemainderAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.arithmetic.RemainderOperator;
import com.alibaba.qlexpress4.runtime.operator.assign.AssignOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseAndAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseAndOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseInvertOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseLeftShiftAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseLeftShiftOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseOrAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseOrOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseRightShiftAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseRightShiftOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseRightShiftUnsignedAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseRightShiftUnsignedOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseXorAssignOperator;
import com.alibaba.qlexpress4.runtime.operator.bit.BitwiseXorOperator;
import com.alibaba.qlexpress4.runtime.operator.collection.InOperator;
import com.alibaba.qlexpress4.runtime.operator.compare.EqualOperator;
import com.alibaba.qlexpress4.runtime.operator.compare.GreaterEqualOperator;
import com.alibaba.qlexpress4.runtime.operator.compare.GreaterOperator;
import com.alibaba.qlexpress4.runtime.operator.compare.LessEqualOperator;
import com.alibaba.qlexpress4.runtime.operator.compare.LessOperator;
import com.alibaba.qlexpress4.runtime.operator.compare.UnequalOperator;
import com.alibaba.qlexpress4.runtime.operator.logic.LogicAndOperator;
import com.alibaba.qlexpress4.runtime.operator.logic.LogicNotOperator;
import com.alibaba.qlexpress4.runtime.operator.logic.LogicOrOperator;
import com.alibaba.qlexpress4.runtime.operator.string.LikeOperator;
import com.alibaba.qlexpress4.runtime.operator.unary.MinusMinusPrefixUnaryOperator;
import com.alibaba.qlexpress4.runtime.operator.unary.MinusMinusSuffixUnaryOperator;
import com.alibaba.qlexpress4.runtime.operator.unary.MinusUnaryOperator;
import com.alibaba.qlexpress4.runtime.operator.unary.PlusPlusPrefixUnaryOperator;
import com.alibaba.qlexpress4.runtime.operator.unary.PlusPlusSuffixUnaryOperator;
import com.alibaba.qlexpress4.runtime.operator.unary.PlusUnaryOperator;
import com.alibaba.qlexpress4.runtime.operator.unary.UnaryOperator;
import com.alibaba.qlexpress4.runtime.util.ThrowUtils;
/**
* @author bingo
*/
public class OperatorManager implements OperatorFactory, ParserOperatorManager {
private static final Map DEFAULT_BINARY_OPERATOR_MAP = new ConcurrentHashMap<>(64);
private static final Map DEFAULT_PREFIX_UNARY_OPERATOR_MAP = new ConcurrentHashMap<>(8);
private static final Map DEFAULT_SUFFIX_UNARY_OPERATOR_MAP = new ConcurrentHashMap<>(8);
static {
List binaryOperatorList = new ArrayList<>(64);
binaryOperatorList.add(AssignOperator.getInstance());
binaryOperatorList.add(PlusOperator.getInstance());
binaryOperatorList.add(PlusAssignOperator.getInstance());
binaryOperatorList.add(MinusOperator.getInstance());
binaryOperatorList.add(MinusAssignOperator.getInstance());
binaryOperatorList.add(MultiplyOperator.getInstance());
binaryOperatorList.add(MultiplyAssignOperator.getInstance());
binaryOperatorList.add(DivideOperator.getInstance());
binaryOperatorList.add(DivideAssignOperator.getInstance());
binaryOperatorList.add(RemainderOperator.getInstance("%"));
binaryOperatorList.add(RemainderAssignOperator.getInstance());
//binaryOperatorList.add(RemainderOperator.getInstance("mod"));
binaryOperatorList.add(BitwiseAndOperator.getInstance());
binaryOperatorList.add(BitwiseAndAssignOperator.getInstance());
binaryOperatorList.add(BitwiseOrOperator.getInstance());
binaryOperatorList.add(BitwiseOrAssignOperator.getInstance());
binaryOperatorList.add(BitwiseXorOperator.getInstance());
binaryOperatorList.add(BitwiseXorAssignOperator.getInstance());
binaryOperatorList.add(BitwiseLeftShiftOperator.getInstance());
binaryOperatorList.add(BitwiseLeftShiftAssignOperator.getInstance());
binaryOperatorList.add(BitwiseRightShiftOperator.getInstance());
binaryOperatorList.add(BitwiseRightShiftAssignOperator.getInstance());
binaryOperatorList.add(BitwiseRightShiftUnsignedOperator.getInstance());
binaryOperatorList.add(BitwiseRightShiftUnsignedAssignOperator.getInstance());
binaryOperatorList.add(LogicAndOperator.getInstance("&&"));
binaryOperatorList.add(LogicAndOperator.getInstance("and"));
binaryOperatorList.add(LogicOrOperator.getInstance("||"));
binaryOperatorList.add(LogicOrOperator.getInstance("or"));
binaryOperatorList.add(EqualOperator.getInstance());
binaryOperatorList.add(UnequalOperator.getInstance("!="));
binaryOperatorList.add(UnequalOperator.getInstance("<>"));
//binaryOperatorList.add(PrismaticUnequalOperator.getInstance());
binaryOperatorList.add(GreaterOperator.getInstance());
binaryOperatorList.add(GreaterEqualOperator.getInstance());
binaryOperatorList.add(LessOperator.getInstance());
binaryOperatorList.add(LessEqualOperator.getInstance());
binaryOperatorList.add(InOperator.getInstance());
binaryOperatorList.add(LikeOperator.getInstance());
binaryOperatorList.add(InstanceOfOperator.getInstance());
for (BinaryOperator binaryOperator : binaryOperatorList) {
DEFAULT_BINARY_OPERATOR_MAP.put(binaryOperator.getOperator(), binaryOperator);
}
List prefixUnaryOperatorList = new ArrayList<>(8);
prefixUnaryOperatorList.add(PlusUnaryOperator.getInstance());
prefixUnaryOperatorList.add(MinusUnaryOperator.getInstance());
prefixUnaryOperatorList.add(PlusPlusPrefixUnaryOperator.getInstance());
prefixUnaryOperatorList.add(MinusMinusPrefixUnaryOperator.getInstance());
prefixUnaryOperatorList.add(BitwiseInvertOperator.getInstance());
prefixUnaryOperatorList.add(LogicNotOperator.getInstance());
for (UnaryOperator unaryOperator : prefixUnaryOperatorList) {
DEFAULT_PREFIX_UNARY_OPERATOR_MAP.put(unaryOperator.getOperator(), unaryOperator);
}
List suffixUnaryOperatorList = new ArrayList<>(8);
suffixUnaryOperatorList.add(PlusPlusSuffixUnaryOperator.getInstance());
suffixUnaryOperatorList.add(MinusMinusSuffixUnaryOperator.getInstance());
for (UnaryOperator unaryOperator : suffixUnaryOperatorList) {
DEFAULT_SUFFIX_UNARY_OPERATOR_MAP.put(unaryOperator.getOperator(), unaryOperator);
}
}
private final Map customBinaryOperatorMap = new ConcurrentHashMap<>();
/**
* @param operatorName
* @param customBinaryOperator
* @param priority {@link QLPrecedences}
* @return
*/
public boolean addBinaryOperator(String operatorName, CustomBinaryOperator customBinaryOperator, int priority) {
if (DEFAULT_BINARY_OPERATOR_MAP.containsKey(operatorName)) {
return false;
}
BinaryOperator preBinaryOperator = customBinaryOperatorMap.putIfAbsent(operatorName,
adapt2BinOp(operatorName, customBinaryOperator, priority)
);
return preBinaryOperator == null;
}
public boolean replaceDefaultOperator(String operatorName, CustomBinaryOperator customBinaryOperator) {
BinaryOperator defaultOperator = DEFAULT_BINARY_OPERATOR_MAP.get(operatorName);
if (defaultOperator == null) {
return false;
}
BinaryOperator preBinaryOperator = customBinaryOperatorMap.putIfAbsent(operatorName,
adapt2BinOp(operatorName, customBinaryOperator, defaultOperator.getPriority())
);
return preBinaryOperator == null;
}
private BinaryOperator adapt2BinOp(String operatorName, CustomBinaryOperator customBinaryOperator, int priority) {
return new BinaryOperator() {
@Override
public Object execute(Value left, Value right, QRuntime qRuntime,
QLOptions qlOptions, ErrorReporter errorReporter) {
try {
return customBinaryOperator.execute(left, right);
} catch (UserDefineException e) {
throw ThrowUtils.reportUserDefinedException(errorReporter, e);
} catch (Throwable t) {
throw ThrowUtils.wrapThrowable(t, errorReporter, "OPERATOR_INNER_EXCEPTION",
"custom operator '" + operatorName + "' inner exception");
}
}
@Override
public String getOperator() {
return operatorName;
}
@Override
public int getPriority() {
return priority;
}
};
}
/**
* @param operatorLexeme like +, =, *, /
* @return binary operator
*/
public BinaryOperator getBinaryOperator(String operatorLexeme) {
BinaryOperator customBinaryOperator = customBinaryOperatorMap.get(operatorLexeme);
if (customBinaryOperator != null) {
return customBinaryOperator;
}
return DEFAULT_BINARY_OPERATOR_MAP.get(operatorLexeme);
}
/**
* like --1 ++1 !true ~1 ^1
*
* @param operatorLexeme ++, --
* @return prefix unary operator
*/
public UnaryOperator getPrefixUnaryOperator(String operatorLexeme) {
return DEFAULT_PREFIX_UNARY_OPERATOR_MAP.get(operatorLexeme);
}
/**
* like 1-- 1++
*
* @param operatorLexeme ++, --
* @return suffix unary operator
*/
public UnaryOperator getSuffixUnaryOperator(String operatorLexeme) {
return DEFAULT_SUFFIX_UNARY_OPERATOR_MAP.get(operatorLexeme);
}
@Override
public boolean isOpType(String lexeme, OpType opType) {
switch (opType) {
case MIDDLE:
return getBinaryOperator(lexeme) != null;
case PREFIX:
return DEFAULT_PREFIX_UNARY_OPERATOR_MAP.containsKey(lexeme);
case SUFFIX:
return DEFAULT_SUFFIX_UNARY_OPERATOR_MAP.containsKey(lexeme);
}
return false;
}
@Override
public Integer precedence(String lexeme) {
return getBinaryOperator(lexeme).getPriority();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy