All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.libra.expr.compiler.syntax.OperatorParser Maven / Gradle / Ivy

/*
 * MIT License
 *
 * Copyright (c) 2018 Alibaba Group
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.libra.expr.compiler.syntax;

import com.libra.Log;

import com.libra.expr.common.StringSupport;
import com.libra.expr.compiler.lex.SymbolToken;
import com.libra.expr.compiler.lex.Token;
import com.libra.expr.compiler.syntax.operator.BinOperator;
import com.libra.expr.compiler.syntax.operator.Operator;
import com.libra.expr.compiler.syntax.operator.TerOperator;
import com.libra.expr.compiler.syntax.operator.UniOperator;

import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.List;
import java.util.Stack;

/**
 * Created by gujicheng on 16/9/9.
 */
public class OperatorParser extends Parser {
    private final static String TAG = "OperatorParser_TMTEST";

    // ` means minus,$ means end
//    private static final String sOperatorString = "+-*/%()`=?:$";
    private static final char sOperatorString[] =
            {
            SymbolToken.ADD, SymbolToken.SUB, SymbolToken.MUL, SymbolToken.DIV, SymbolToken.MOD,
            SymbolToken.LEFT_BRACKET, SymbolToken.RIGHT_BRACKET, SymbolToken.MINUS, SymbolToken.EQ, SymbolToken.QUESTION, SymbolToken.COLON,
            SymbolToken.NOT, SymbolToken.GT, SymbolToken.LT, SymbolToken.GE, SymbolToken.LE, SymbolToken.EQ_EQ, SymbolToken.NOT_EQ,
            SymbolToken.ADD_EQ, SymbolToken.SUB_EQ, SymbolToken.MUL_EQ, SymbolToken.DIV_EQ, SymbolToken.MOD_EQ, SymbolToken.AND, SymbolToken.OR, SymbolToken.END};
    private static final int sOperatorCount = sOperatorString.length;

    // 0 means eq, 1 means greater(left greater than right), 2 means less, 3 means illegal
    private static final byte PRI_EQ = 0;
    private static final byte PRI_GR = 1;
    private static final byte PRI_LE = 2;
    private static final byte PRI_IL = 3;
    private static final byte[] sOpPriors = {
//             +       -       *       /       %      (       )       `       =       ?        :      not     >       <       >=      <=      ==      !=       +=     -=      *=       /=      %=     &&      ||      $
/* + */     PRI_GR, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* - */     PRI_GR, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* * */     PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* / */     PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* % */     PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* ( */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_EQ, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_IL,
/* ) */     PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_IL, PRI_GR, PRI_GR, PRI_IL, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* ` */     PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* = */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_LE, PRI_GR,
/* ? */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_IL, PRI_LE, PRI_IL, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_LE, PRI_IL,
/* : */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_LE, PRI_GR,
/*not*/     PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* > */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* < */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/*>= */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/*<= */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/*== */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/*!= */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/*+= */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR,
/*-= */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR,
/**= */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR,
/*/= */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR,
/*%= */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR,
/* && */    PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR,
/* || */    PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_GR, PRI_LE, PRI_GR, PRI_GR,
/* $ */     PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_IL, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_LE, PRI_EQ
    };

    private Stack mOperators;
    private List mOperatorProcessors = new ArrayList();
    private char mPreOperator;

    private TerOperator mTerOperator;

    private Stack mOperands = new Stack();

    public OperatorParser() {
        mOperatorProcessors.add(new UniOperator());
        mOperatorProcessors.add(new BinOperator());
        mTerOperator = new TerOperator();
        mOperatorProcessors.add(mTerOperator);
    }

    public void setOperatorStack(Stack operators) {
        mOperators = operators;
        mTerOperator.setOperatorStack(operators);
    }

    public void setOperandStack(Stack operands) {
        mOperands = operands;
        for (Operator operator : mOperatorProcessors) {
            operator.setOperandStack(mOperands);
        }
    }

    @Override
    public void reset() {
        super.reset();
    }

    public void init() {
        mPreOperator = SymbolToken.END;
    }

    @Override
    public void setCodeGenerator(CodeGenerator codeGenerator) {
        super.setCodeGenerator(codeGenerator);

        for (Operator operator : mOperatorProcessors) {
            operator.setCodeGenerator(mCodeGenerator);
        }
    }

    @Override
    public void setRegisterManager(RegisterManager registerManager) {
        super.setRegisterManager(registerManager);

        for (Operator operator : mOperatorProcessors) {
            operator.setRegisterManager(mRegisterManager);
        }
    }

    @Override
    public void setStringManager(StringSupport sm) {
        super.setStringManager(sm);

        for (Operator operator : mOperatorProcessors) {
            operator.setStringManager(sm);
        }
    }

    private void OperatorDeal(char op) {
        for (Operator operator : mOperatorProcessors) {
            if (operator.deal(op)) {
                break;
            }
        }
    }

    @Override
    public int parse(Token token) {
        int ret = RESULT_FAILED;

        if (Token.TYPE_SYMBOL == token.mType) {
            SymbolToken st = (SymbolToken) token;
            char op = st.mValue;
//            Log.d(TAG, "parse token*********************** operator:" + SymbolToken.show(op));
            if (isOperator(op)) {
                do {
                    int pri = prior(mPreOperator, op);

//                    Log.d(TAG, "prior left:" + SymbolToken.show(mPreOperator) + "  right:" + SymbolToken.show(op) + "  pri:" + pri + "  opesize:" + mOperators.size());
                    if (PRI_EQ == pri) {
                        try {
                            mOperators.pop();
                        } catch (EmptyStackException e) {
                            Log.e(TAG, "mOperators is empty");
                        }

                        if (SymbolToken.RIGHT_BRACKET == op) {
                            mPreOperator = mOperators.peek();
                        }
                        ret = RESULT_FINISH;
                        break;
                    } else if (PRI_GR == pri) {
                        try {
                            mOperators.pop();
                        } catch (EmptyStackException e) {
                            Log.e(TAG, "mOperators is empty");
                        }

//                        Log.d(TAG, "deal");
                        OperatorDeal(mPreOperator);
                        mPreOperator = mOperators.peek();
//                        Log.d(TAG, "deal end");
                    } else if (PRI_LE == pri) {
                        mOperators.push(op);
                        mPreOperator = op;
                        ret = RESULT_FINISH;
//                        Log.d(TAG, "break with le");
                        break;
                    } else {
                        // error
//                        Log.e(TAG, "operator deal error:" + SymbolToken.show(op));
                        ret = RESULT_FAILED;
                        break;
                    }
                } while (true);
            }
        }

        return ret;
    }

    @Override
    protected Expr buildExpr() {
        return null;
    }

    private static int prior(char ch1, char ch2) {
//        Log.d(TAG, "ch1:" + SymbolToken.show(ch1) + "  ch2:" + SymbolToken.show(ch2));
        int index1 = getIndex(ch1);
        int index2 = getIndex(ch2);

        if (index1 > -1 && index2 > -1) {
//            Log.d(TAG, "index1:" + index1 + "  index2:" + index2);
            return sOpPriors[index1 * sOperatorCount + index2];
        }

        return PRI_IL;
    }

    private static int getIndex(char ch) {
        int ret = -1;

        for (int i = 0; i < sOperatorString.length; ++i) {
            if (ch == sOperatorString[i]) {
                ret = i;
                break;
            }
        }

        return ret;
    }

    private static boolean isOperator(char ch) {
        return (getIndex(ch) > -1) ? true : false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy