Search in sources :

Example 1 with NFAEdge

use of priv.bajdcc.util.lexer.automata.nfa.NFAEdge in project jMiniLang by bajdcc.

the class DFA method deleteEpsilonEdges.

/**
 * 去除Epsilon边
 */
private void deleteEpsilonEdges() {
    ArrayList<NFAStatus> NFAStatusList = getNFAStatusClosure(new BreadthFirstSearch<>(), // 获取状态闭包
    nfa.begin);
    // 不可到达状态集合
    ArrayList<NFAStatus> unaccessiableList = new ArrayList<>();
    for (NFAStatus status : NFAStatusList) {
        boolean epsilon = true;
        for (NFAEdge edge : status.inEdges) {
            if (edge.data.kAction != EdgeType.EPSILON) {
                // 不是Epsilon边
                // 当前可到达
                epsilon = false;
                break;
            }
        }
        if (epsilon) {
            // 如果所有入边为Epsilon边,则不可到达
            unaccessiableList.add(status);
        }
    }
    // 初态设为有效
    unaccessiableList.remove(nfa.begin);
    BreadthFirstSearch<NFAEdge, NFAStatus> epsilonBFS = new BreadthFirstSearch<NFAEdge, NFAStatus>() {

        @Override
        public boolean testEdge(NFAEdge edge) {
            return edge.data.kAction == EdgeType.EPSILON;
        }
    };
    /* 遍历所有有效状态 */
    // 若为有效状态
    /* 获取当前状态的Epsilon闭包 */
    /* 去除自身状态 */
    /* 遍历Epsilon闭包的状态 */
    /* 如果闭包中有终态,则当前状态为终态 */
    /* 遍历闭包中所有边 */
    /* 如果当前边不是Epsilon边,就将闭包中的有效边添加到当前状态 */
    /* 如果当前边不是Epsilon边,就将闭包中的有效边添加到当前状态 */
    NFAStatusList.stream().filter(status -> !unaccessiableList.contains(status)).forEach(status -> {
        // 若为有效状态
        /* 获取当前状态的Epsilon闭包 */
        ArrayList<NFAStatus> epsilonClosure = getNFAStatusClosure(epsilonBFS, status);
        /* 去除自身状态 */
        epsilonClosure.remove(status);
        /* 遍历Epsilon闭包的状态 */
        for (NFAStatus epsilonStatus : epsilonClosure) {
            if (epsilonStatus.data.bFinal) {
                /* 如果闭包中有终态,则当前状态为终态 */
                status.data.bFinal = true;
            }
            /* 遍历闭包中所有边 */
            /* 如果当前边不是Epsilon边,就将闭包中的有效边添加到当前状态 */
            epsilonStatus.outEdges.stream().filter(edge -> edge.data.kAction != EdgeType.EPSILON).forEach(edge -> {
                /* 如果当前边不是Epsilon边,就将闭包中的有效边添加到当前状态 */
                connect(status, edge.end).data = edge.data;
            });
        }
    });
    /* 删除Epsilon边 */
    for (NFAStatus status : NFAStatusList) {
        for (Iterator<NFAEdge> it = status.outEdges.iterator(); it.hasNext(); ) {
            NFAEdge edge = it.next();
            if (edge.data.kAction == EdgeType.EPSILON) {
                it.remove();
                // 删除Epsilon边
                disconnect(status, edge);
            }
        }
    }
    /* 删除无效状态 */
    for (NFAStatus status : unaccessiableList) {
        // 删除无效状态
        NFAStatusList.remove(status);
        // 删除与状态有关的所有边
        disconnect(status);
    }
    unaccessiableList.clear();
    /* 删除重复边 */
    for (NFAStatus status : NFAStatusList) {
        for (int i = 0; i < status.outEdges.size() - 1; i++) {
            NFAEdge edge1 = status.outEdges.get(i);
            for (ListIterator<NFAEdge> it2 = status.outEdges.listIterator(i + 1); it2.hasNext(); ) {
                NFAEdge edge2 = it2.next();
                if (edge1.end == edge2.end && edge1.data.kAction == edge2.data.kAction && edge1.data.param == edge2.data.param) {
                    it2.remove();
                    disconnect(status, edge2);
                }
            }
        }
    }
}
Also used : Iterator(java.util.Iterator) ListIterator(java.util.ListIterator) DFAStatus(priv.bajdcc.util.lexer.automata.dfa.DFAStatus) Collection(java.util.Collection) IRegexComponent(priv.bajdcc.util.lexer.regex.IRegexComponent) HashMap(java.util.HashMap) Collectors(java.util.stream.Collectors) BreadthFirstSearch(priv.bajdcc.util.lexer.automata.BreadthFirstSearch) ArrayList(java.util.ArrayList) EdgeType(priv.bajdcc.util.lexer.automata.EdgeType) NFAStatus(priv.bajdcc.util.lexer.automata.nfa.NFAStatus) NFAEdge(priv.bajdcc.util.lexer.automata.nfa.NFAEdge) NFA(priv.bajdcc.util.lexer.automata.nfa.NFA) BreadthFirstSearch(priv.bajdcc.util.lexer.automata.BreadthFirstSearch) NFAStatus(priv.bajdcc.util.lexer.automata.nfa.NFAStatus) ArrayList(java.util.ArrayList) NFAEdge(priv.bajdcc.util.lexer.automata.nfa.NFAEdge)

Example 2 with NFAEdge

use of priv.bajdcc.util.lexer.automata.nfa.NFAEdge in project jMiniLang by bajdcc.

the class DFA method determine.

/**
 * NFA确定化,转为DFA
 */
private void determine() {
    /* 取得NFA所有状态 */
    ArrayList<NFAStatus> NFAStatusList = getNFAStatusClosure(new BreadthFirstSearch<>(), nfa.begin);
    ArrayList<DFAStatus> DFAStatusList = new ArrayList<>();
    /* 哈希表用来进行DFA状态表的查找 */
    HashMap<String, Integer> DFAStatusListMap = new HashMap<>();
    DFAStatus initStatus = new DFAStatus();
    // 是否终态
    initStatus.data.bFinal = nfa.begin.data.bFinal;
    // DFA[0]=NFA初态集合
    initStatus.data.nfaStatus.add(nfa.begin);
    DFAStatusList.add(initStatus);
    DFAStatusListMap.put(initStatus.data.getStatusString(NFAStatusList), 0);
    /* 构造DFA表 */
    for (int i = 0; i < DFAStatusList.size(); i++) {
        DFAStatus dfaStatus = DFAStatusList.get(i);
        ArrayList<DFAEdgeBag> bags = new ArrayList<>();
        /* 遍历当前NFA状态集合的所有边 */
        for (NFAStatus nfaStatus : dfaStatus.data.nfaStatus) {
            for (NFAEdge nfaEdge : nfaStatus.outEdges) {
                DFAEdgeBag dfaBag = null;
                for (DFAEdgeBag bag : bags) {
                    /* 检查是否在表中 */
                    if (nfaEdge.data.kAction == bag.kAction && nfaEdge.data.param == bag.param) {
                        dfaBag = bag;
                        break;
                    }
                }
                /* 若不存在,则新建 */
                if (dfaBag == null) {
                    dfaBag = new DFAEdgeBag();
                    dfaBag.kAction = nfaEdge.data.kAction;
                    dfaBag.param = nfaEdge.data.param;
                    bags.add(dfaBag);
                }
                /* 添加当前边 */
                dfaBag.nfaEdges.add(nfaEdge);
                /* 添加当前状态 */
                dfaBag.nfaStatus.add(nfaEdge.end);
            }
        }
        /* 遍历当前的所有DFA边 */
        for (DFAEdgeBag bag : bags) {
            /* 检测DFA指向的状态是否存在 */
            DFAStatus status;
            /* 哈希字符串 */
            String hash = bag.getStatusString(NFAStatusList);
            if (DFAStatusListMap.containsKey(bag.getStatusString(NFAStatusList))) {
                status = DFAStatusList.get(DFAStatusListMap.get(hash));
            } else {
                // 不存在DFA
                status = new DFAStatus();
                status.data.nfaStatus = new ArrayList<>(bag.nfaStatus);
                /* 检查终态 */
                for (NFAStatus nfaStatus : status.data.nfaStatus) {
                    if (nfaStatus.data.bFinal) {
                        status.data.bFinal = true;
                        break;
                    }
                }
                DFAStatusList.add(status);
                DFAStatusListMap.put(hash, DFAStatusList.size() - 1);
            }
            /* 创建DFA边 */
            DFAEdge edge = connect(dfaStatus, status);
            edge.data.kAction = bag.kAction;
            edge.data.param = bag.param;
            edge.data.nfaEdges = bag.nfaEdges;
        }
    }
    dfa = DFAStatusList.get(0);
}
Also used : HashMap(java.util.HashMap) NFAStatus(priv.bajdcc.util.lexer.automata.nfa.NFAStatus) ArrayList(java.util.ArrayList) NFAEdge(priv.bajdcc.util.lexer.automata.nfa.NFAEdge) DFAStatus(priv.bajdcc.util.lexer.automata.dfa.DFAStatus)

Aggregations

ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 DFAStatus (priv.bajdcc.util.lexer.automata.dfa.DFAStatus)2 NFAEdge (priv.bajdcc.util.lexer.automata.nfa.NFAEdge)2 NFAStatus (priv.bajdcc.util.lexer.automata.nfa.NFAStatus)2 Collection (java.util.Collection)1 Iterator (java.util.Iterator)1 ListIterator (java.util.ListIterator)1 Collectors (java.util.stream.Collectors)1 BreadthFirstSearch (priv.bajdcc.util.lexer.automata.BreadthFirstSearch)1 EdgeType (priv.bajdcc.util.lexer.automata.EdgeType)1 NFA (priv.bajdcc.util.lexer.automata.nfa.NFA)1 IRegexComponent (priv.bajdcc.util.lexer.regex.IRegexComponent)1