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

com.github.liuyehcf.framework.language.hua.compile.HuaCompiler Maven / Gradle / Ivy

package com.github.liuyehcf.framework.language.hua.compile;

import com.github.liuyehcf.framework.compile.engine.cfg.lr.Context;
import com.github.liuyehcf.framework.compile.engine.cfg.lr.LALR;
import com.github.liuyehcf.framework.compile.engine.grammar.definition.SemanticAction;
import com.github.liuyehcf.framework.compile.engine.utils.Pair;
import com.github.liuyehcf.framework.language.hua.compile.definition.semantic.AbstractSemanticAction;
import com.github.liuyehcf.framework.language.hua.core.*;
import com.github.liuyehcf.framework.language.hua.core.bytecode.ByteCode;
import com.github.liuyehcf.framework.language.hua.core.bytecode.cf.ControlTransfer;
import com.github.liuyehcf.framework.language.hua.core.bytecode.cf._goto;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.*;

import static com.github.liuyehcf.framework.language.hua.compile.definition.GrammarDefinition.GRAMMAR;
import static com.github.liuyehcf.framework.language.hua.compile.definition.GrammarDefinition.LEXICAL_ANALYZER;

/**
 * Hua编译器
 *
 * @author hechenfeng
 * @date 2018/6/2
 */
public class HuaCompiler extends LALR implements Serializable {

    /**
     * 环境变量名
     */
    public static final String HUA_SERIALIZATION_FILE = "HUA_COMPILER";

    private HuaCompiler() {
        super(GRAMMAR, LEXICAL_ANALYZER);
    }

    public static HuaCompiler getHuaCompiler() {
        HuaCompiler huaCompiler;

        /*
         * 首先从序列化文件中加载编译器
         */
        try {
            InputStream resourceStream = ClassLoader.getSystemClassLoader().getResourceAsStream(HUA_SERIALIZATION_FILE);
            if (resourceStream == null) {
                throw new NullPointerException();
            }
            ObjectInputStream inputStream = new ObjectInputStream(resourceStream);
            huaCompiler = (HuaCompiler) inputStream.readObject();
            return huaCompiler;
        } catch (Throwable e) {
            // ignore
        }

        /*
         * 重新构建编译器
         */
        huaCompiler = new HuaCompiler();

        return huaCompiler;
    }

    @Override
    protected Engine createCompiler(String input) {
        return new HuaEngine(input);
    }

    public class HuaEngine extends Engine {

        /**
         * 常量池
         */
        private ConstantPool constantPool = new ConstantPool();

        /**
         * 方法定义表
         */
        private MethodInfoTable methodInfoTable = new MethodInfoTable();

        HuaEngine(String input) {
            super(input);
        }

        @Override
        protected void before() {

        }

        @Override
        protected void after() {
            /*
             * 代码优化
             */
            optimize();

            /*
             * 设置编译结果
             */
            setResult(new IntermediateInfo(constantPool, methodInfoTable));
        }

        private void optimize() {
            Map table = methodInfoTable.getTable();

            for (MethodInfo methodInfo : table.values()) {
                optimize(methodInfo);
            }
        }

        private void optimize(MethodInfo methodInfo) {
            List byteCodes = methodInfo.getByteCodes();

            /*
             * 将多级跳转指令改成一个跳转指令
             */
            simplifyControlTransferCode(byteCodes);

            /*
             * 删除多余的跳转指令(不可达)
             */
            removeRedundantControlTransferCode(byteCodes);
        }

        private void simplifyControlTransferCode(List byteCodes) {
            for (ByteCode code : byteCodes) {
                if (!(code instanceof ControlTransfer)) {
                    continue;
                }

                ControlTransfer controlTransferCode = (ControlTransfer) code;

                int codeOffset = controlTransferCode.getCodeOffset();

                codeOffset = getFinalCodeOffset(byteCodes, codeOffset);

                controlTransferCode.setCodeOffset(codeOffset);
            }
        }

        private int getFinalCodeOffset(List byteCodes, final int codeOffset) {
            int optimizedCodeOffset = codeOffset;

            Set visitedCodes = new HashSet<>();

            ByteCode code;
            while ((code = byteCodes.get(optimizedCodeOffset)) instanceof _goto) {
                /*
                 * 对于for(;;){}这样的循环,只有一个goto语句,且回到原点
                 * 跳转链路的终点是一个goto self
                 */
                if (!visitedCodes.add(code)) {
                    return optimizedCodeOffset;
                }
                optimizedCodeOffset = ((ControlTransfer) code).getCodeOffset();
            }

            return optimizedCodeOffset;
        }

        private void removeRedundantControlTransferCode(List byteCodes) {
            Set visitedCodes = new HashSet<>();

            visitCode(0, visitedCodes, byteCodes);

            List unvisitedCodeOffsets = new ArrayList<>();
            for (int i = 0; i < byteCodes.size(); i++) {
                unvisitedCodeOffsets.add(i);
            }
            unvisitedCodeOffsets.removeAll(visitedCodes);

            Collections.sort(unvisitedCodeOffsets);

            List controlTransferCodes = new ArrayList<>();
            Map> controlTransferCodeOffsetMap = new HashMap<>();
            for (int offset = 0; offset < byteCodes.size(); offset++) {
                ByteCode code = byteCodes.get(offset);
                if (code instanceof ControlTransfer) {
                    controlTransferCodes.add((ControlTransfer) code);
                    controlTransferCodeOffsetMap.put((ControlTransfer) code, new Pair<>(offset, ((ControlTransfer) code).getCodeOffset()));
                }
            }

            for (int unvisitedCodeOffset : unvisitedCodeOffsets) {
                /*
                 * 如果转移指令跳转目标代码的序号大于codeOffset,由于codeOffset处的指令会被删除
                 * 因此该跳转指令的目标代码序号需要-1
                 */
                for (ControlTransfer controlTransferCode : controlTransferCodes) {
                    Pair pair = controlTransferCodeOffsetMap.get(controlTransferCode);
                    int offset = pair.getFirst();
                    int toOffset = pair.getSecond();

                    /*
                     * 这个跳转指令也不可达,跳过不处理
                     */
                    if (unvisitedCodeOffsets.contains(offset)) {
                        continue;
                    }

                    /*
                     * 若跳转偏移量比当前不可达指令的偏移量要大,那么跳转偏移量-1
                     */
                    if (toOffset > unvisitedCodeOffset) {
                        controlTransferCode.setCodeOffset(controlTransferCode.getCodeOffset() - 1);
                    }
                }
            }

            /*
             * 清理不可达指令
             */
            List copyByteCodes = new ArrayList<>(byteCodes);
            byteCodes.clear();

            for (int i = 0; i < copyByteCodes.size(); i++) {
                if (!unvisitedCodeOffsets.contains(i)) {
                    byteCodes.add(copyByteCodes.get(i));
                }
            }
        }

        private void visitCode(int codeOffset, Set visitedCodes, List byteCodes) {
            if (codeOffset >= byteCodes.size() || visitedCodes.contains(codeOffset)) {
                return;
            }

            visitedCodes.add(codeOffset);
            ByteCode code = byteCodes.get(codeOffset);

            if (code instanceof ControlTransfer) {
                visitCode(((ControlTransfer) code).getCodeOffset(), visitedCodes, byteCodes);
                if (!(code instanceof _goto)) {
                    visitCode(codeOffset + 1, visitedCodes, byteCodes);
                }
            } else {
                visitCode(codeOffset + 1, visitedCodes, byteCodes);
            }
        }

        @Override
        protected void onReduction(Context context) {
            List> semanticActions = context.getRawPrimaryProduction().getSemanticActions();
            if (semanticActions == null) {
                return;
            }

            for (SemanticAction semanticAction : semanticActions) {
                ((AbstractSemanticAction) semanticAction).onAction(new CompilerContext(context, constantPool, methodInfoTable));
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy