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

com.libra.expr.compiler.ExprCompiler Maven / Gradle / Ivy

The newest version!
/*
 * 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;

import com.libra.Log;
import com.libra.TextUtils;
import com.libra.Utils;
import com.libra.expr.common.ExprCode;
import com.libra.expr.common.StringSupport;
import com.libra.expr.compiler.lex.LexParser;
import com.libra.expr.compiler.lex.Token;
import com.libra.expr.compiler.syntax.CodeGenerator;
import com.libra.expr.compiler.syntax.Expr;
import com.libra.expr.compiler.syntax.RegisterManager;
import com.libra.expr.compiler.syntax.SyntaxParser;

/**
 * Created by gujicheng on 16/9/8.
 */

public class ExprCompiler implements LexParser.Listener {
    private final static String TAG = "ExprCompiler_TMTEST";

    private StringSupport mStringStore;
    private LexParser mLexParser = new LexParser();
    private SyntaxParser mSyntaxParser = new SyntaxParser();
    private CodeGenerator mCodeGenerator = new CodeGenerator();
    private RegisterManager mRegisterManager = new RegisterManager();

    public ExprCompiler() {
        mLexParser.setListener(this);
    }

    private Listener mListener;

    public interface Listener {
        void onCodeBlock(String name, ExprCode codes);
    }

    public void setListener(Listener lis) {
        mListener = lis;
    }

    public void setStringSupport(StringSupport sm) {
        mStringStore = sm;
        mLexParser.setStringStore(mStringStore);
        mSyntaxParser.setStringStore(mStringStore);

        mSyntaxParser.setCodeGenerator(mCodeGenerator);
        mSyntaxParser.setRegisterManager(mRegisterManager);
    }

    private void reset() {
        mLexParser.reset();
        mSyntaxParser.reset();

        mCodeGenerator.reset();
        mRegisterManager.reset();
    }

    private boolean isSpace(String str) {
        boolean ret = true;

        if (!TextUtils.isEmpty(str)) {
            int len = str.length();
            for (int i = 0; i < len; ++i) {
                char c = str.charAt(i);
                if (!Utils.isSpace(c)) {
                    ret = false;
                    break;
                }
            }
        }

        return ret;
    }

    private String preProcess(String expr) {
        if (!TextUtils.isEmpty(expr)) {
            String[] exprSentences = expr.split(";");
//            Log.d(TAG, "preProcess sentence count:" + exprSentences.length);
            StringBuilder sb = new StringBuilder();
            boolean first = true;
            for (int i = 0; i < exprSentences.length; ++i) {
                if (!isSpace(exprSentences[i])) {
                    if (first) {
                        first = false;
                    } else {
                        sb.append(";");
                    }

                    sb.append(exprSentences[i]);
                }
            }

            expr = sb.toString();
        }

        return expr;
    }

    public boolean compileBlock(String blocks) {
        boolean ret = true;
        if (!TextUtils.isEmpty(blocks) && (null != mListener)) {
            String[] blockArr = blocks.split("block");
            for (int i = 0; i < blockArr.length; ++i) {
                String block = blockArr[i].trim();
                if (!TextUtils.isEmpty(block)) {
//                    Log.d(TAG, "block:" + block);
                    int start = block.indexOf('{');
                    int end = block.lastIndexOf('}');
                    if (start < end && start > -1) {
                        String name = block.substring(0, start).trim();
                        String content = block.substring(start + 1, end);
//                        Log.d(TAG, "name:" + name + "  content:" + content);

                        if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(content)) {
                            if (ret = doCompile(content)) {
                                mListener.onCodeBlock(name, getCode());
                            } else {
                                Log.e(TAG, "compile failed");
                                mListener.onCodeBlock(name, null);
                                break;
                            }
//                            Log.d(TAG, "ret:" + ret);
                        } else {
                            ret = false;
                            Log.e(TAG, "name or content is empty block:" + block);
                            break;
                        }
                    } else {
                        ret = false;
                        Log.e(TAG, "format error:" + block);
                        break;
                    }
                } else {
                    Log.w(TAG, "block is empty");
                }
            }
        } else {
            Log.e(TAG, "blocks is empty or mListener is null");
            ret = false;
        }

        return ret;
    }

    public boolean doCompile(String expr) {
        boolean ret = false;
        reset();

        expr = preProcess(expr);

        Log.d(TAG, "compile expr start:" + expr);

        if (!TextUtils.isEmpty(expr)) {
            // must add " "
            ret = mLexParser.parse(expr + " ");
        } else {
            Log.e(TAG, "empty expr:" + expr);
        }

        Log.d(TAG, "compile expr end:" + ret);
        return ret;
    }

    public boolean compile(String expr) {
        boolean ret = false;

        if (!TextUtils.isEmpty(expr)) {
            if (expr.startsWith("${") && expr.endsWith("}")) {
                expr = expr.substring(2, expr.length() - 1);

                ret = doCompile(expr);
            } else {
                Log.e(TAG, "error format:" + expr);
            }
        } else {
            Log.e(TAG, "empty expr");
        }

        return ret;
    }

    @Override
    public void onLexParseStart() {
//        Log.d(TAG, "onLexParseStart");
        mSyntaxParser.reset();
    }

    @Override
    public boolean onLexParseToken(Token token) {
//        Log.d(TAG, "onLexParseToken:" + token);
        boolean ret = mSyntaxParser.parse(token);
//        Log.d(TAG, "onLexParseToken ret:" + ret);

        return ret;
    }

    @Override
    public boolean onLexParseEnd(boolean result) {
//        Log.d(TAG, "onLexParseEnd:" + result);

        if (result) {
            mSyntaxParser.forceFinish();
//            mSyntaxParser.parse(new SymbolToken(SymbolToken.END));

            Expr expr = mSyntaxParser.getExpr();
            if (null == expr) {
//                result = false;
                Log.e(TAG, "onLexParseEnd get expr is null");
            }
//            Log.d(TAG, "result expr:" + expr + "  code:" + mSyntaxParser.getExprCode());
        } else {
            Log.e(TAG, "onLexParseEnd parse failed");
        }

        return result;
    }

    public ExprCode getCode() {
        ExprCode ret = mSyntaxParser.getExprCode();
        if (null != ret) {
            ret = ret.clone();
        }

        return ret;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy