编译器

作者: sspa | 来源:发表于2019-11-15 15:33 被阅读0次

    1. 构建 VariateType

    public enum VariateType {
        /**
         * <p>Variate type, include <type>STRING</type>, <type>NUMERIC</type>,
         * <type>ARRAY</type>, <type>BOOLEAN</type>, <type>FUNCTION</type>,
         * <type>SYMBOL</type>, <type>SYMBOL</type> and <type>ORIGINAL</type>.</p>
         */
        STRING, NUMERIC, FUNCTION, SYMBOL, BOOLEAN, ORIGINAL, ARRAY, ERROR, STREAM,
    }
    

    2. 构建 Variate

    import com.google.gson.JsonArray;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonParser;
    import com.google.gson.JsonPrimitive;
    import com.neusoft.rsapm.brain.common.exception.CompilerException;
    import com.neusoft.rsapm.brain.common.util.Util;
    import lombok.Getter;
    import lombok.ToString;
    import org.apache.commons.lang.StringUtils;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Objects;
    import java.util.stream.Collectors;
    
    import static com.neusoft.rsapm.compile.VariateType.*;
    
    /**
     * @author Muxin Sun
     * @date 2019/05/20
     */
    @Getter
    @ToString
    public class Variate {
    
        /**
         * @date 2019/05/20
         * <p>Supported operators, sort operational character by priority level. <char>'</char> is max level,
         *   Note: <char>=</char> is not mutator method.</p>
         */
    
        public static final String LEFT_PARENTHESIS = "(";
        public static final String RIGHT_PARENTHESIS = ")";
        public static final String GREATER_THAN = ">";
        public static final String LESS_THAN = "<";
        public static final String EQUAL = "=";
        public static final String PLUS = "+";
        public static final String MINUS = "-";
        public static final String COMMA = ",";
        public static final String TIMES = "*";
        public static final String DIVISION = "/";
        public static final String DOT = ".";
    
        public static final String QUERY = "#";
        public static final String GREATER_EQUAL = ">=";
        public static final String LESS_EQUAL = "<=";
    
        public static final String OR = " or ";
        public static final String AND = " and ";
    
        public static final Variate LEFT_PARENTHESIS_VARIATE = build(SYMBOL, LEFT_PARENTHESIS);
        public static final Variate RIGHT_PARENTHESIS_VARIATE = build(SYMBOL, RIGHT_PARENTHESIS);
        public static final Variate GREATER_THAN_VARIATE = build(SYMBOL, GREATER_THAN);
        public static final Variate LESS_THAN_VARIATE = build(SYMBOL, LESS_THAN);
        public static final Variate EQUAL_VARIATE = build(SYMBOL, EQUAL);
        public static final Variate PLUS_VARIATE = build(SYMBOL, PLUS);
        public static final Variate MINUS_VARIATE = build(SYMBOL, MINUS);
        public static final Variate COMMA_VARIATE = build(SYMBOL, COMMA);
        public static final Variate TIMES_VARIATE = build(SYMBOL, TIMES);
        public static final Variate DIVISION_VARIATE = build(SYMBOL, DIVISION);
        public static final Variate QUERY_VARIATE = build(SYMBOL, QUERY);
        public static final Variate GREATER_EQUAL_VARIATE = build(SYMBOL, GREATER_EQUAL);
        public static final Variate LESS_EQUAL_VARIATE = build(SYMBOL, LESS_EQUAL);
        public static final Variate OR_VARIATE = build(SYMBOL, OR);
        public static final Variate AND_VARIATE = build(SYMBOL, AND);
    
    
        public static final String[] OPERATORS = {LEFT_PARENTHESIS, RIGHT_PARENTHESIS, QUERY,
                GREATER_THAN, GREATER_EQUAL, LESS_THAN, LESS_EQUAL, EQUAL, PLUS, MINUS, COMMA, TIMES,
                DIVISION, OR, AND};
    
        /**
         * <p>check {@code op} is OPERATOR?</p>
         *
         * @return ture if {@code op} is in {@code OPERATORS}, else false
         * @see #OPERATORS
         */
        public static boolean isOperator(String op) {
            return Arrays.asList(OPERATORS).contains(op);
        }
    
        public static List<String> spliteExpr(String expr) throws CompilerException {
            return spliteExpr(expr, new BaseQuery());
        }
    
        public static List<String> spliteExpr(final String expr, final BaseQuery baseQuery) throws CompilerException {
            List<String> words = new ArrayList<>();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < expr.length();) {
                if (expr.substring(i).startsWith(OR)) {
                    words.add(sb.toString().trim());
                    words.add(OR);
                    sb = new StringBuffer();
                    i += OR.length();
                } else if (expr.substring(i).startsWith(AND)) {
                    words.add(sb.toString().trim());
                    words.add(AND);
                    sb = new StringBuffer();
                    i += AND.length();
                } else if (expr.substring(i).startsWith(LESS_EQUAL)) {
                    words.add(sb.toString().trim());
                    words.add(LESS_EQUAL);
                    sb = new StringBuffer();
                    i += LESS_EQUAL.length();
                } else if (expr.substring(i).startsWith(GREATER_EQUAL)) {
                    words.add(sb.toString().trim());
                    words.add(GREATER_EQUAL);
                    sb = new StringBuffer();
                    i += GREATER_EQUAL.length();
                } else if (expr.substring(i).startsWith(QUERY)) {
                    words.add(sb.toString().trim());
                    words.add(QUERY);
                    sb = new StringBuffer();
                    i += QUERY.length();
                    if (expr.substring(i).contains(QUERY)) {
                        final String query = expr.substring(i).substring(0, expr.substring(i).indexOf(QUERY));
                        baseQuery.addQuery(query);
                        words.add(query);
                        i += query.length();
                        words.add(QUERY);
                        i += QUERY.length();
                    } else {
                        throw new CompilerException("expr query no match.");
                    }
                } else if (expr.substring(i).startsWith(DIVISION)) {
                    words.add(sb.toString().trim());
                    words.add(DIVISION);
                    sb = new StringBuffer();
                    i += DIVISION.length();
                } else if (expr.substring(i).startsWith(TIMES)) {
                    words.add(sb.toString().trim());
                    words.add(TIMES);
                    sb = new StringBuffer();
                    i += TIMES.length();
                } else if (expr.substring(i).startsWith(COMMA)) {
                    words.add(sb.toString().trim());
                    words.add(COMMA);
                    sb = new StringBuffer();
                    i += COMMA.length();
                } else if (expr.substring(i).startsWith(MINUS)) {
                    words.add(sb.toString().trim());
                    words.add(MINUS);
                    sb = new StringBuffer();
                    i += MINUS.length();
                } else if (expr.substring(i).startsWith(PLUS)) {
                    words.add(sb.toString().trim());
                    words.add(PLUS);
                    sb = new StringBuffer();
                    i += PLUS.length();
                } else if (expr.substring(i).startsWith(EQUAL)) {
                    words.add(sb.toString().trim());
                    words.add(EQUAL);
                    sb = new StringBuffer();
                    i += EQUAL.length();
                } else if (expr.substring(i).startsWith(LESS_THAN)) {
                    words.add(sb.toString().trim());
                    words.add(LESS_THAN);
                    sb = new StringBuffer();
                    i += LESS_THAN.length();
                } else if (expr.substring(i).startsWith(GREATER_THAN)) {
                    words.add(sb.toString().trim());
                    words.add(GREATER_THAN);
                    sb = new StringBuffer();
                    i += GREATER_THAN.length();
                } else if (expr.substring(i).startsWith(RIGHT_PARENTHESIS)) {
                    words.add(sb.toString().trim());
                    words.add(RIGHT_PARENTHESIS);
                    sb = new StringBuffer();
                    i += RIGHT_PARENTHESIS.length();
                } else if (expr.substring(i).startsWith(LEFT_PARENTHESIS)) {
                    words.add(sb.toString().trim());
                    words.add(LEFT_PARENTHESIS);
                    sb = new StringBuffer();
                    i += LEFT_PARENTHESIS.length();
                } else if (expr.substring(i).startsWith(DOT) && StringUtils.isAlpha(expr.substring(i+1,i+2))) {
                    words.add(sb.toString().trim());
                    words.add(DOT);
                    sb = new StringBuffer();
                    i += DOT.length();
    
                    StringBuffer func_name = new StringBuffer();
                    while((!LEFT_PARENTHESIS.equals(String.valueOf(expr.charAt(i)))) && i<expr.length()) {
                        func_name.append(expr.charAt(i));
                        i++;
                    }
                    words.add(func_name.toString().trim());
                    words.add(LEFT_PARENTHESIS);
                    int stack = 1;
                    StringBuffer func_body = new StringBuffer();
                    while(stack > 0 && i<expr.length()) {
                        i++;
                        if (LEFT_PARENTHESIS.equals(String.valueOf(expr.charAt(i)))) {
                            stack += 1;
                        } else if (RIGHT_PARENTHESIS.equals(String.valueOf(expr.charAt(i)))) {
                            stack -= 1;
                        }
                        if (stack > 0) {
                            func_body.append(expr.charAt(i));
                        }
    
                    }
                    words.add(func_body.toString().trim());
                    words.add(RIGHT_PARENTHESIS);
    
                    i++;
                } else {
                    sb.append(expr.charAt(i));
                    i += 1;
                }
            }
            if (sb.length() > 0) {
                words.add(sb.toString().trim());
            }
            return words.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
        }
    
        /**
         * <p>Lexical compiler triple: <code>type</code> is variate type,
         *    <code>name</code> is variate name, <code>value</code> is variate value. </p>
         *
         * @date 2019/05/21
         */
        private VariateType type;
        private JsonElement value;
        private StringBuffer sb;
    
        /**
         * <p> Variate Constructor. </p>
         *
         * @param type variate type.
         * @param value variate value.
         */
        private Variate(VariateType type, JsonPrimitive value, StringBuffer sb) {
            this.type = type;
            this.value = value;
            this.sb = sb;
        }
    
        /**
         * <p> Variate Constructor. </p>
         *
         * @param type variate type.
         * @param value variate value.
         */
        private Variate(VariateType type, JsonArray value, StringBuffer sb) {
            this.type = type;
            this.value = value;
            this.sb = sb;
        }
    
        /**
         * <p>build <code>type</code> variate</p>
         *
         * @param obj variate value.
         * @return <code>Variate</code> Variate type is <code>type</code>, name is null, value is empty
         */
        public static Variate build(Object obj) {
            if (obj instanceof JsonArray) {
                return new Variate(ARRAY, (JsonArray) obj, new StringBuffer());
            }
            return build(ORIGINAL, obj);
        }
    
        /**
         * <p>build <code>type</code> variate</p>
         *
         * @param type datum type.
         * @param obj variate value.
         * @return <code>Variate</code> Variate type is <code>type</code>, name is null, value is empty
         */
        public static Variate build(VariateType type, Object obj) {
            if (type.equals(ARRAY) || type.equals(STREAM)) {
                if (obj instanceof JsonArray) {
                    return new Variate(type, (JsonArray) obj, new StringBuffer());
                }
            }
            if (type == ORIGINAL) {
                return new Variate(ORIGINAL, new JsonPrimitive(""), new StringBuffer(obj.toString()));
            }
            if (obj instanceof Integer) {
                return new Variate(type, new JsonPrimitive((int) obj), new StringBuffer());
            } else if (obj instanceof Long) {
                return new Variate(type, new JsonPrimitive((long) obj), new StringBuffer());
            } else if (obj instanceof Short) {
                return new Variate(type, new JsonPrimitive((short) obj), new StringBuffer());
            } else if (obj instanceof Float) {
                return new Variate(type, new JsonPrimitive((float) obj), new StringBuffer());
            } else if (obj instanceof Double) {
                return new Variate(type, new JsonPrimitive((double) obj), new StringBuffer());
            } else if (obj instanceof Byte) {
                return new Variate(type, new JsonPrimitive((byte) obj), new StringBuffer());
            } else if (obj instanceof Boolean) {
                return new Variate(type, new JsonPrimitive((boolean) obj), new StringBuffer());
            } else if (obj instanceof Character) {
                return new Variate(type, new JsonPrimitive((char) obj), new StringBuffer());
            } else if (obj instanceof Number) {
                return new Variate(type, new JsonPrimitive((Number) obj), new StringBuffer());
            }
            return new Variate(type, new JsonPrimitive(obj.toString()), new StringBuffer());
        }
    
        /**
         * <p>check {@code value} is empty?</p>
         *
         * @return ture if {@code value} is null or the size of {@code value} is 0, else false
         * @see #value
         */
        boolean isEmpty() {
            return (Objects.isNull(this.value) || StringUtils.isEmpty(this.value.getAsString()))
                    && Objects.deepEquals(this.sb.length(), 0);
        }
    
        /**
         * <p>expand <code>value</code></p>
         *
         * @param ch the next of variate <char>ch</char>
         */
        void expand(String ch) throws CompilerException {
            if (this.type.equals(ORIGINAL)) {
                this.sb.append(ch);
                return;
            }
            throw new CompilerException("expand error: type is not ORIGINAL. ");
        }
    
        /**
         * <p>check {@code value} is empty?</p>
         *
         * @return true ior false
         * @see #isEmpty()
         */
        private boolean isValid() {
            if (this.type.equals(ORIGINAL)) {
                return true;
            } else if (this.type.equals(FUNCTION)) {
                return StringUtils.isAlpha(getValue().getAsString()) && Objects.deepEquals(isEmpty(), false);
            } else if (this.type.equals(NUMERIC)) {
                return Util.isNumeric(value.getAsNumber());
            } else if (this.type.equals(STRING)) {
                return true;
            } else if (this.type.equals(SYMBOL)) {
                return isOperator(getValue().getAsString());
            } else if (this.type.equals(BOOLEAN)) {
                getValue().getAsBoolean();
                return true;
            } else if (this.type.equals(ARRAY)) {
                return getValue().isJsonArray();
            } else if (this.type.equals(STREAM)) {
                return getValue().isJsonArray();
            }
            return false;
        }
    
        /**
         * <p>transform {@code type}</p>
         *
         * @return void
         * @throws CompilerException type and value do not match
         * @throws CompilerException type is not {@code original} and @{code this.type.equals(type)}
         */
        private void transformType(VariateType type) throws CompilerException {
            if (this.type.equals(type)) {
                return ;
            }
            if (isORIGINAL()) {
                this.type = type;
                switch (type) {
                    case BOOLEAN:
                        value = new JsonPrimitive(Boolean.valueOf(sb.toString()));
                        break;
                    case NUMERIC:
                        value = new JsonPrimitive(Double.valueOf(sb.toString()));
                        break;
                    case ORIGINAL:
                    case ERROR:
                        break;
                    case ARRAY:
                        value = new JsonParser().parse(sb.toString());
                        break;
                    case STRING:
                    case SYMBOL:
                    case FUNCTION:
                        value = new JsonPrimitive(sb.toString());
                        break;
                }
                if (!isValid()) {
                    this.type = ORIGINAL;
                    throw new CompilerException("transform error: type and value do not match. ");
                }
                sb = new StringBuffer();
            } else {
                throw new CompilerException("transform error: original type is not {@code original}. ");
            }
        }
    
        /**
         * <p>transform {@code FUNCTION} type</p>
         *
         * @return void
         * @throws CompilerException type and value do not match
         * @throws CompilerException original type is not {@code original}
         *
         * @see #transformType(VariateType)
         */
        void toFUNCTION()  throws CompilerException {
            transformType(FUNCTION);
        }
    
        /**
         * <p>transform {@code STRING} type</p>
         *
         * @return void
         * @throws CompilerException type and value do not match
         * @throws CompilerException original type is not {@code original}
         *
         * @see #transformType(VariateType)
         */
        void toSTRING()  throws CompilerException {
            transformType(STRING);
        }
    
        /**
         * <p>transform {@code FUNCTION} type</p>
         *
         * @return void
         * @throws CompilerException type and value do not match
         * @throws CompilerException original type is not {@code original}
         *
         * @see #transformType(VariateType)
         */
        void toSYMBOL()  throws CompilerException {
            transformType(SYMBOL);
        }
    
        /**
         * <p>transform {@code NUMERIC} type</p>
         *
         * @return void
         * @throws CompilerException type and value do not match
         * @throws CompilerException original type is not {@code original}
         *
         * @see #transformType(VariateType)
         */
        void toNUMERIC()  throws CompilerException {
            transformType(NUMERIC);
        }
    
        /**
         * <p>transform {@code BOOLEAN} type</p>
         *
         * @return void
         *
         * @see #transformType(VariateType)
         */
        void toBOOLEAN() {
            type = BOOLEAN;
        }
    
        /**
         * <p>transform {@code STREAM} type</p>
         *
         * @return void
         *
         * @see #transformType(VariateType)
         */
        void toSTREAM() {
            type = STREAM;
        }
    
        /**
         * <p>transform {@code ARRAY} type</p>
         *
         * @return void
         *
         * @see #transformType(VariateType)
         */
        void toARRAY() {
            type = ARRAY;
        }
    
        /**
         * <p>transform {@code NUMERIC} type</p>
         *
         * @return void
         *
         * @see #transformType(VariateType)
         */
        void toERROR() {
            type = ERROR;
        }
    
        /**
         * <p>check variate {@code type}</p>
         *
         * @return true if {@code type} is {@code STRING}, else false
         */
        public boolean isSTRING() {
            return this.type.equals(STRING) && this.isValid();
        }
    
        /**
         * <p>check variate {@code type}</p>
         *
         * @return true if {@code type} is {@code NUMERIC}, else false
         */
        public boolean isNUMERIC() {
            return this.type.equals(NUMERIC) && this.isValid();
        }
    
        /**
         * <p>check variate {@code type}</p>
         *
         * @return true if {@code type} is {@code FUNCTION}, else false
         */
        public boolean isFUNCTION() {
            return this.type.equals(FUNCTION) && this.isValid();
        }
    
        /**
         * <p>check variate {@code type}</p>
         *
         * @return true if {@code type} is {@code SYMBOL}, else false
         */
        public boolean isSYMBOL() {
            return this.type.equals(SYMBOL) && this.isValid();
        }
    
        /**
         * <p>check variate {@code type}</p>
         *
         * @return true if {@code type} is {@code STREAM}, else false
         */
        public boolean isSTREAM() {
            return this.type.equals(STREAM) && this.isValid();
        }
    
        /**
         * <p>check variate {@code type}</p>
         *
         * @return true if {@code type} is {@code ARRAY}, else false
         */
        public boolean isARRAY() {
            return this.type.equals(ARRAY) && this.isValid();
        }
    
        /**
         * <p>check variate {@code type}</p>
         *
         * @return true if {@code type} is {@code BOOLEAN}, else false
         */
        public boolean isBOOLEAN() {
            return this.type.equals(BOOLEAN) && this.isValid();
        }
    
        /**
         * <p>check variate {@code type}</p>
         *
         * @return true if {@code type} is {@code ORIGINAL}, else false
         */
        public boolean isORIGINAL() {
            return this.type.equals(ORIGINAL) && this.isValid();
        }
    
        /**
         * <p>check variate {@code type}</p>
         *
         * @return true if {@code type} is {@code ERROR}, else false
         */
        public boolean isERROR() {
            return this.type.equals(ERROR) && this.isValid();
        }
    
        /**
         * <p>check variate {@code value}</p>
         *
         * @param value string value
         * @return true if {@code value} is value, else false
         */
        public boolean equals(String value) {
            return getValue().getAsString().equals(value);
        }
    
        /**
         * <p>check variate {@code value}</p>
         *
         * @param v Variate
         * @return true if {@code value} is value, else false
         */
        public boolean equals(Variate v) {
            return v.type.equals(this.type) && v.value.getAsString().equals(this.value.getAsString());
        }
    }
    

    3. 构建 Lexical

    
    import com.neusoft.rsapm.brain.common.exception.CompilerException;
    import com.neusoft.rsapm.brain.common.exception.MessageException;
    import com.neusoft.rsapm.brain.common.util.Util;
    import org.apache.commons.lang.StringUtils;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    import static com.neusoft.rsapm.compile.VariateType.*;
    
    /**
     * Lexocal for metric cal
     *
     * @author Muxin Sun
     * @date 2018/12/20
     */
    public interface Lexical {
    
        /**
         * <p>function name</p>
         */
        String MIN_FUNCTION = "min";
        String MAX_FUNCTION = "max";
        String SUM_FUNCTION = "sum";
        String AVG_FUNCTION = "avg";
        String COUNT_FUNCTION = "count";
    
        String NAME_PREFIX = "v";
        AtomicInteger SEQUENCE = new AtomicInteger(0);
    
        /**
         * <p>variate to values</p>
         */
        Map<String, Variate> NAME_VARIATE = new HashMap<>();
    
        /**
         * <p>gt sign</p>
         *
         * @param valueA valueA is numeric
         * @param valueB valueB is numeric
         * @return 1 if valueA grant than valueB, else 0
         * @throws CompilerException Non-numeric type cannot be multiplied.
         */
        default Variate gt(Variate valueA, Variate valueB) throws CompilerException {
            if (valueA.isNUMERIC() && valueB.isNUMERIC()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsDouble()>valueB.getValue().getAsDouble()?1:0);
            } else if (valueA.isSTRING() && valueB.isSTRING()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsString().compareTo(valueB.getValue().getAsString())>0?1:0);
            }
            throw new CompilerException("Operator type cannot be compared.");
        }
    
        /**
         * <p>lt sign</p>
         *
         * @param valueA valueA is numeric
         * @param valueB valueB is numeric
         * @return 1 if valueA less than valueB, else 0
         * @throws CompilerException Non-numeric type cannot be multiplied.
         */
        default Variate lt(Variate valueA, Variate valueB) throws CompilerException {
            if (valueA.isNUMERIC() && valueB.isNUMERIC()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsDouble()<valueB.getValue().getAsDouble()?1:0);
            } else if (valueA.isSTRING() && valueB.isSTRING()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsString().compareTo(valueB.getValue().getAsString())<0?1:0);
            }
            throw new CompilerException("Operator type cannot be compared.");
        }
    
        /**
         * <p>eq sign</p>
         *
         * @param valueA valueA is numeric
         * @param valueB valueB is numeric
         * @return 1 if valueA less than valueB, else 0
         * @throws CompilerException Non-numeric type cannot be multiplied.
         */
        default Variate eq(Variate valueA, Variate valueB) throws CompilerException {
            if (valueA.isNUMERIC() && valueB.isNUMERIC()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsDouble()==valueB.getValue().getAsDouble()?1:0);
            } else if (valueA.isSTRING() && valueB.isSTRING()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsString().compareTo(valueB.getValue().getAsString())==0?1:0);
            }
            throw new CompilerException("Operator type cannot be compared.");
        }
    
        /**
         * <p>eq sign</p>
         *
         * @param valueA valueA is numeric
         * @param valueB valueB is numeric
         * @return 1 if valueA less than valueB, else 0
         * @throws CompilerException Non-numeric type cannot be multiplied.
         */
        default Variate ge(Variate valueA, Variate valueB) throws CompilerException {
            if (valueA.isNUMERIC() && valueB.isNUMERIC()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsDouble()>=valueB.getValue().getAsDouble()?1:0);
            } else if (valueA.isSTRING() && valueB.isSTRING()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsString().compareTo(valueB.getValue().getAsString())>=0?1:0);
            }
            throw new CompilerException("Operator type cannot be compared.");
        }
    
        /**
         * <p>eq sign</p>
         *
         * @param valueA valueA is numeric
         * @param valueB valueB is numeric
         * @return 1 if valueA less than or equal valueB, else 0
         * @throws CompilerException Non-numeric type cannot be multiplied.
         */
        default Variate le(Variate valueA, Variate valueB) throws CompilerException {
            if (valueA.isNUMERIC() && valueB.isNUMERIC()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsDouble()<=valueB.getValue().getAsDouble()?1:0);
            } else if (valueA.isSTRING() && valueB.isSTRING()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsString().compareTo(valueB.getValue().getAsString())<=0?1:0);
            }
            throw new CompilerException("Operator type cannot be compared.");
        }
    
        /**
         * <p>plus sign</p>
         *
         * @param valueA valueA is numeric
         * @param valueB valueB is numeric
         * @return <code>valueA+valueB</code>
         * @throws CompilerException Non-numeric types cannot be added.
         */
        default Variate plus(Variate valueA, Variate valueB) throws CompilerException {
            if (valueA.isNUMERIC() && valueB.isNUMERIC()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsDouble() + valueB.getValue().getAsDouble());
            }
            throw new CompilerException("Non-numeric types cannot be added.");
        }
    
        /**
         * <p>minus sign</p>
         *
         * @param valueA valueA is numeric
         * @param valueB valueB is numeric
         * @return <code>valueA-valueB</code>
         * @throws CompilerException Non-numeric type cannot be subtracted.
         */
        default Variate minus(Variate valueA, Variate valueB) throws CompilerException {
            if (valueA.isNUMERIC() && valueB.isNUMERIC()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsDouble() - valueB.getValue().getAsDouble());
            }
            throw new CompilerException("Non-numeric type cannot be subtracted.");
        }
    
        /**
         * <p>times sign</p>
         *
         * @param valueA valueA is numeric
         * @param valueB valueB is numeric
         * @return <code>valueA*valueB</code>
         * @throws CompilerException Non-numeric type cannot be multiplied.
         */
        default Variate times(Variate valueA, Variate valueB) throws CompilerException {
            if (valueA.isNUMERIC() && valueB.isNUMERIC()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsDouble() * valueB.getValue().getAsDouble());
            }
            throw new CompilerException("Non-numeric type cannot be multiplied.");
        }
    
        /**
         * <p>divide sign</p>
         *
         * @param valueA valueA is numeric
         * @param valueB valueB is numeric
         * @return <code>valueA/valueB</code> valueB is no-null
         * @throws CompilerException Non-numeric type cannot be divided.
         */
        default Variate division(Variate valueA, Variate valueB) throws CompilerException {
            if (valueA.isNUMERIC() && valueB.isNUMERIC()) {
                return Variate.build(NUMERIC, valueA.getValue().getAsDouble() / valueB.getValue().getAsDouble());
            }
            throw new CompilerException("Non-numeric type cannot be divided.");
        }
    
        /**
         * <p>execute function and </p>
         *
         * @param function function name
         * @param parameters parameters is variate_stream
         * @return <code>execute result</code>
         * @throws CompilerException if function is not def.
         */
        default Variate execute(String function, List<Variate> parameters) throws CompilerException {
            if (MIN_FUNCTION.equals(function)) {
                if (parameters.stream().allMatch(Variate::isNUMERIC)) {
                    return Variate.build(NUMERIC, parameters.stream().map(Variate::getValue).mapToDouble(Util::getNumeric).min().orElse(Double.NaN));
                }
                throw new CompilerException("min function do not accept non-numeric parameters.");
            }
            if (MAX_FUNCTION.equals(function)) {
                if (parameters.stream().allMatch(Variate::isNUMERIC)) {
                    return Variate.build(NUMERIC, parameters.stream().map(Variate::getValue).mapToDouble(Util::getNumeric).max().orElse(Double.NaN));
                }
                throw new CompilerException("max function do not accept non-numeric parameters.");
            }
            if (SUM_FUNCTION.equals(function)) {
                if (parameters.stream().allMatch(Variate::isNUMERIC)) {
                    return Variate.build(NUMERIC, parameters.stream().map(Variate::getValue).mapToDouble(Util::getNumeric).sum());
                }
                throw new CompilerException("sum function do not accept non-numeric parameters.");
            }
            if (AVG_FUNCTION.equals(function)) {
                if (parameters.stream().allMatch(Variate::isNUMERIC)) {
                    return Variate.build(NUMERIC, parameters.stream().map(Variate::getValue).mapToDouble(Util::getNumeric).average().orElse(Double.NaN));
                }
                throw new CompilerException("avg function do not accept non-numeric parameters.");
            }
            if (COUNT_FUNCTION.equals(function)) {
                return Variate.build(NUMERIC, parameters.stream().count());
            }
            throw new CompilerException("function is not def.");
        }
    
        /**
         * <p>execute function, and args is array</p>
         *
         * @param function function name
         * @param parameters function parameters
         * @return <code>execute result</code>
         */
        default Variate execute(String function, Variate... parameters) throws CompilerException, MessageException {
            return execute(function, Stream.of(parameters).collect(Collectors.toList()));
        }
    
        /**
         * <p>check operator is a function? </p>
         * <pre>
         * isFunction(null)   = false
         * isFunction("")     = true
         * isFunction("  ")   = false
         * isFunction("abc")  = true
         * isFunction("ab2c") = false
         * isFunction("ab-c") = false
         * </pre>
         * @param operator operator name
         * @return <code>true</code> if only contains letters, and is non-null
         */
        default boolean isFunction(String operator) {
            return StringUtils.isAlpha(operator);
        }
    
        /**
         * <p>store variate value function, return random variate</p>
         *
         * @param variate {@link #NAME_VARIATE}
         * @return <code>variate name</code>, name is auto-created
         */
        default String putVariate(final Variate variate) {
            NAME_VARIATE.put(String.format("%s-%d", NAME_PREFIX, SEQUENCE.incrementAndGet()), variate);
            return String.valueOf(String.format("%s-%d", NAME_PREFIX, SEQUENCE.get()));
        }
    
        /**
         * <p>get variate value, by name</p>
         *
         * @param name variate name
         * @return <code>variate</code>
         * @throws CompilerException if <code>variate</code> is not exist
         */
        default boolean isVariate(String name) throws CompilerException {
            return NAME_VARIATE.containsKey(name);
        }
    
        /**
         * <p>get variate value, by name</p>
         *
         * @param name variate name
         * @return <code>variate</code>
         * @throws CompilerException if <code>variate</code> is not exist
         */
        default Variate getVariate(String name) throws CompilerException {
            if (NAME_VARIATE.containsKey(name)) {
                return NAME_VARIATE.get(name);
            }
            throw new CompilerException("variate {"+name+"} is not exist");
        }
    }
    
    

    4. 构建 Syntactic

    import com.neusoft.rsapm.brain.common.exception.CompilerException;
    import com.neusoft.rsapm.brain.common.util.Util;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Objects;
    import java.util.Stack;
    
    import static com.neusoft.rsapm.compile.Variate.*;
    import static com.neusoft.rsapm.compile.Variate.COMMA_VARIATE;
    import static com.neusoft.rsapm.compile.VariateType.*;
    
    /**
     * @author Muxin Sun
     * @date 2018/12/20
     */
    public class Syntactic {
    
        private static Variate transform(final Lexical lexical, final Variate variate) throws CompilerException {
            if (variate.isORIGINAL() && Util.isNumeric(variate.getSb().toString())) {
                variate.toNUMERIC();
                return variate;
            } else if (variate.isORIGINAL() && lexical.isVariate(variate.getSb().toString())) {
                return lexical.getVariate(variate.getSb().toString());
            } else if (variate.isORIGINAL()) {
                throw new CompilerException("no variate.");
            }
            return variate;
        }
    
        /**
         * <p>calculate expr value</p>
         *
         * @param lexical lexical
         * @param expr expr
         * @return Variate
         */
        public static Variate getExprValue(final Lexical lexical, final String expr) throws CompilerException {
            final BaseQuery baseQuery = new BaseQuery();
            List<String> words = Variate.spliteExpr(expr, baseQuery);
            baseQuery.exeQuery();
            return getExprValue(lexical, baseQuery, words);
        }
    
        /**
         * <p>calculate expr value</p>
         *
         * @param lexical lexical
         * @param baseQuery baseQuery
         * @param words words
         * @return Variate
         */
        public static Variate getExprValue(final Lexical lexical, final BaseQuery baseQuery,
                                           final List<String> words) throws CompilerException {
    
            boolean isQuery = false;
    
            Stack<Variate> operators = new Stack<>();
            Stack<Variate> numbers = new Stack<>();
    
            Variate variate = Variate.build("");
    
            for (String word : words) {
                switch (word) {
                    case LEFT_PARENTHESIS:
                        if (Objects.deepEquals(variate.isEmpty(), false)) {
                            variate.toFUNCTION();
                            operators.push(variate);
                        }
                        operators.push(LEFT_PARENTHESIS_VARIATE);
                        variate = Variate.build("");
                        break;
                    case RIGHT_PARENTHESIS:
                        List<Variate> variates = new ArrayList<>();
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE)) {
                                operators.pop();
                                variates.add(variate);
                                if (!operators.isEmpty() && operators.peek().isFUNCTION()) {
                                    variate = lexical.execute(operators.pop().getValue().getAsString(), variates);
                                }
                                break;
                            } else if (operators.peek().equals(COMMA_VARIATE)) {
                                operators.pop();
                                variates.add(numbers.pop());
                            } else if (operators.peek().equals(GREATER_THAN_VARIATE)) {
                                operators.pop();
                                variate = lexical.gt(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_THAN_VARIATE)) {
                                operators.pop();
                                variate = lexical.lt(numbers.pop(), variate);
                            } else if (operators.peek().equals(EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.eq(numbers.pop(), variate);
                            } else if (operators.peek().equals(GREATER_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.ge(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.le(numbers.pop(), variate);
                            } else if (operators.peek().equals(PLUS_VARIATE)) {
                                operators.pop();
                                variate = lexical.plus(numbers.pop(), variate);
                            } else if (operators.peek().equals(MINUS_VARIATE)) {
                                operators.pop();
                                variate = lexical.minus(numbers.pop(), variate);
                            } else if (operators.peek().equals(TIMES_VARIATE)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION_VARIATE)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek());
                            }
                        }
                        break;
                    case COMMA:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(GREATER_THAN_VARIATE)) {
                                operators.pop();
                                variate = lexical.gt(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_THAN_VARIATE)) {
                                operators.pop();
                                variate = lexical.lt(numbers.pop(), variate);
                            } else if (operators.peek().equals(EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.eq(numbers.pop(), variate);
                            } else if (operators.peek().equals(GREATER_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.ge(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.le(numbers.pop(), variate);
                            } else if (operators.peek().equals(PLUS_VARIATE)) {
                                operators.pop();
                                variate = lexical.plus(numbers.pop(), variate);
                            } else if (operators.peek().equals(MINUS_VARIATE)) {
                                operators.pop();
                                variate = lexical.minus(numbers.pop(), variate);
                            } else if (operators.peek().equals(TIMES_VARIATE)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION_VARIATE)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek());
                            }
                        }
                        numbers.push(variate);
                        operators.push(COMMA_VARIATE);
                        variate = Variate.build("");
                        break;
                    case GREATER_THAN:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(GREATER_THAN_VARIATE)) {
                                operators.pop();
                                variate = lexical.gt(numbers.pop(), variate);
                            } else if (operators.peek().equals(GREATER_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.ge(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_THAN)) {
                                operators.pop();
                                variate = lexical.lt(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.le(numbers.pop(), variate);
                            } else if (operators.peek().equals(EQUAL)) {
                                operators.pop();
                                variate = lexical.eq(numbers.pop(), variate);
                            } else if (operators.peek().equals(PLUS)) {
                                operators.pop();
                                variate = lexical.plus(numbers.pop(), variate);
                            } else if (operators.peek().equals(MINUS)) {
                                operators.pop();
                                variate = lexical.minus(numbers.pop(), variate);
                            } else if (operators.peek().equals(TIMES)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek());
                            }
                        }
                        numbers.push(variate);
                        operators.push(GREATER_THAN_VARIATE);
                        variate = Variate.build("");
                        break;
                    case GREATER_EQUAL:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(GREATER_THAN_VARIATE)) {
                                operators.pop();
                                variate = lexical.gt(numbers.pop(), variate);
                            } else if (operators.peek().equals(GREATER_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.ge(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_THAN)) {
                                operators.pop();
                                variate = lexical.lt(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.le(numbers.pop(), variate);
                            } else if (operators.peek().equals(EQUAL)) {
                                operators.pop();
                                variate = lexical.eq(numbers.pop(), variate);
                            } else if (operators.peek().equals(PLUS)) {
                                operators.pop();
                                variate = lexical.plus(numbers.pop(), variate);
                            } else if (operators.peek().equals(MINUS)) {
                                operators.pop();
                                variate = lexical.minus(numbers.pop(), variate);
                            } else if (operators.peek().equals(TIMES)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek());
                            }
                        }
                        numbers.push(variate);
                        operators.push(GREATER_EQUAL_VARIATE);
                        variate = Variate.build("");
                        break;
                    case LESS_THAN:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(GREATER_THAN_VARIATE)) {
                                operators.pop();
                                variate = lexical.gt(numbers.pop(), variate);
                            } else if (operators.peek().equals(GREATER_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.ge(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_THAN)) {
                                operators.pop();
                                variate = lexical.lt(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.le(numbers.pop(), variate);
                            } else if (operators.peek().equals(EQUAL)) {
                                operators.pop();
                                variate = lexical.eq(numbers.pop(), variate);
                            } else if (operators.peek().equals(PLUS)) {
                                operators.pop();
                                variate = lexical.plus(numbers.pop(), variate);
                            } else if (operators.peek().equals(MINUS)) {
                                operators.pop();
                                variate = lexical.minus(numbers.pop(), variate);
                            } else if (operators.peek().equals(TIMES)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek());
                            }
                        }
                        numbers.push(variate);
                        operators.push(LESS_THAN_VARIATE);
                        variate = Variate.build("");
                        break;
                    case LESS_EQUAL:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(GREATER_THAN_VARIATE)) {
                                operators.pop();
                                variate = lexical.gt(numbers.pop(), variate);
                            } else if (operators.peek().equals(GREATER_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.ge(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_THAN)) {
                                operators.pop();
                                variate = lexical.lt(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.le(numbers.pop(), variate);
                            } else if (operators.peek().equals(EQUAL)) {
                                operators.pop();
                                variate = lexical.eq(numbers.pop(), variate);
                            } else if (operators.peek().equals(PLUS)) {
                                operators.pop();
                                variate = lexical.plus(numbers.pop(), variate);
                            } else if (operators.peek().equals(MINUS)) {
                                operators.pop();
                                variate = lexical.minus(numbers.pop(), variate);
                            } else if (operators.peek().equals(TIMES)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek());
                            }
                        }
                        numbers.push(variate);
                        operators.push(LESS_EQUAL_VARIATE);
                        variate = Variate.build("");
                        break;
                    case EQUAL:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(GREATER_THAN_VARIATE)) {
                                operators.pop();
                                variate = lexical.gt(numbers.pop(), variate);
                            } else if (operators.peek().equals(GREATER_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.ge(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_THAN)) {
                                operators.pop();
                                variate = lexical.lt(numbers.pop(), variate);
                            } else if (operators.peek().equals(LESS_EQUAL_VARIATE)) {
                                operators.pop();
                                variate = lexical.le(numbers.pop(), variate);
                            } else if (operators.peek().equals(EQUAL)) {
                                operators.pop();
                                variate = lexical.eq(numbers.pop(), variate);
                            } else if (operators.peek().equals(PLUS)) {
                                operators.pop();
                                variate = lexical.plus(numbers.pop(), variate);
                            } else if (operators.peek().equals(MINUS)) {
                                operators.pop();
                                variate = lexical.minus(numbers.pop(), variate);
                            } else if (operators.peek().equals(TIMES)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek());
                            }
                        }
                        numbers.push(variate);
                        operators.push(EQUAL_VARIATE);
                        variate = Variate.build("");
                        break;
                    case PLUS:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE) ||
                                    operators.peek().equals(GREATER_THAN_VARIATE) || operators.peek().equals(GREATER_EQUAL_VARIATE) ||
                                    operators.peek().equals(LESS_THAN_VARIATE) || operators.peek().equals(LESS_EQUAL_VARIATE) ||
                                    operators.peek().equals(EQUAL_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(PLUS_VARIATE)) {
                                operators.pop();
                                variate = lexical.plus(numbers.pop(), variate);
                            } else if (operators.peek().equals(MINUS_VARIATE)) {
                                operators.pop();
                                variate = lexical.minus(numbers.pop(), variate);
                            } else if (operators.peek().equals(TIMES_VARIATE)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION_VARIATE)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek().getValue());
                            }
                        }
                        numbers.push(variate);
                        operators.push(PLUS_VARIATE);
                        variate = Variate.build("");
                        break;
                    case MINUS:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE) ||
                                    operators.peek().equals(GREATER_THAN_VARIATE) || operators.peek().equals(GREATER_EQUAL_VARIATE) ||
                                    operators.peek().equals(LESS_THAN_VARIATE) || operators.peek().equals(LESS_EQUAL_VARIATE) ||
                                    operators.peek().equals(EQUAL_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(PLUS_VARIATE)) {
                                operators.pop();
                                variate = lexical.plus(numbers.pop(), variate);
                            } else if (operators.peek().equals(MINUS_VARIATE)) {
                                operators.pop();
                                variate = lexical.minus(numbers.pop(), variate);
                            } else if (operators.peek().equals(TIMES_VARIATE)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION_VARIATE)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek().getValue());
                            }
                        }
                        numbers.push(variate);
                        operators.push(MINUS_VARIATE);
                        variate = Variate.build("");
                        break;
                    case TIMES:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE) ||
                                    operators.peek().equals(GREATER_THAN_VARIATE) || operators.peek().equals(GREATER_EQUAL_VARIATE) ||
                                    operators.peek().equals(LESS_THAN_VARIATE) || operators.peek().equals(LESS_EQUAL_VARIATE) ||
                                    operators.peek().equals(EQUAL_VARIATE) || operators.peek().equals(PLUS_VARIATE) ||
                                    operators.peek().equals(MINUS_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(TIMES_VARIATE)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION_VARIATE)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek().getValue());
                            }
                        }
                        numbers.push(variate);
                        operators.push(TIMES_VARIATE);
                        variate = Variate.build("");
                        break;
                    case DIVISION:
                        variate = transform(lexical, variate);
                        while (!operators.isEmpty()) {
                            if (operators.peek().equals(LEFT_PARENTHESIS_VARIATE) || operators.peek().equals(COMMA_VARIATE) ||
                                    operators.peek().equals(GREATER_THAN_VARIATE) || operators.peek().equals(GREATER_EQUAL_VARIATE) ||
                                    operators.peek().equals(LESS_THAN_VARIATE) || operators.peek().equals(LESS_EQUAL_VARIATE) ||
                                    operators.peek().equals(EQUAL_VARIATE) || operators.peek().equals(PLUS_VARIATE) ||
                                    operators.peek().equals(MINUS_VARIATE)) {
                                break;
                            } else if (operators.peek().equals(TIMES_VARIATE)) {
                                operators.pop();
                                variate = lexical.times(numbers.pop(), variate);
                            } else if (operators.peek().equals(DIVISION_VARIATE)) {
                                operators.pop();
                                variate = lexical.division(numbers.pop(), variate);
                            } else {
                                throw new CompilerException(
                                        "operators error : " + operators.peek().getValue());
                            }
                        }
                        numbers.push(variate);
                        operators.push(DIVISION_VARIATE);
                        variate = Variate.build("");
                        break;
                    case QUERY:
                        isQuery = !isQuery;
                        break;
                    default:
                        if (isQuery) {
                            if (variate.isEmpty()) {
                                variate = Variate.build(ARRAY, baseQuery.getResponse(word));
                            } else {
                                throw new CompilerException("operators error.");
                            }
                        } else {
                            variate.expand(word);
                        }
                }
            }
    
            variate = transform(lexical, variate);
    
            while ( !operators.isEmpty() ) {
                if (operators.peek().equals(COMMA_VARIATE)) {
                    operators.pop();
                } else if (operators.peek().equals(GREATER_THAN_VARIATE)) {
                    operators.pop();
                    variate = lexical.gt(numbers.pop(), variate);
                } else if (operators.peek().equals(GREATER_EQUAL_VARIATE)) {
                    operators.pop();
                    variate = lexical.ge(numbers.pop(), variate);
                } else if (operators.peek().equals(LESS_THAN_VARIATE)) {
                    operators.pop();
                    variate = lexical.lt(numbers.pop(), variate);
                } else if (operators.peek().equals(LESS_EQUAL_VARIATE)) {
                    operators.pop();
                    variate = lexical.lt(numbers.pop(), variate);
                } else if (operators.peek().equals(EQUAL_VARIATE)) {
                    operators.pop();
                    variate = lexical.eq(numbers.pop(), variate);
                } else if (operators.peek().equals(PLUS_VARIATE)) {
                    operators.pop();
                    variate = lexical.plus(numbers.pop(), variate);
                } else if (operators.peek().equals(MINUS_VARIATE)) {
                    operators.pop();
                    variate = lexical.minus(numbers.pop(), variate);
                } else if (operators.peek().equals(TIMES_VARIATE)) {
                    operators.pop();
                    variate = lexical.times(numbers.pop(), variate);
                } else if (operators.peek().equals(DIVISION_VARIATE)) {
                    operators.pop();
                    variate = lexical.division(numbers.pop(), variate);
                } else {
                    throw new CompilerException(
                            "operators error : " + operators.peek().getValue());
                }
            }
            if (numbers.empty()) {
                return variate;
            }
            throw new CompilerException(
                    "expr error : " + words);
        }
    }
    

    相关文章

      网友评论

        本文标题:编译器

        本文链接:https://www.haomeiwen.com/subject/pmcoectx.html