Search in sources :

Example 1 with DFAStatus

use of priv.bajdcc.util.lexer.automata.dfa.DFAStatus in project jMiniLang by bajdcc.

the class DFA method getDFAString.

/**
 * 提供DFA描述
 * @return DFA描述
 */
public String getDFAString() {
    /* 取得NFA所有状态 */
    ArrayList<NFAStatus> NFAStatusList = getNFAStatusClosure(new BreadthFirstSearch<>(), nfa.begin);
    /* 取得DFA所有状态 */
    ArrayList<DFAStatus> DFAStatusList = getDFAStatusClosure(new BreadthFirstSearch<>(), dfa);
    StringBuilder sb = new StringBuilder();
    /* 生成DFA描述 */
    for (int i = 0; i < DFAStatusList.size(); i++) {
        DFAStatus status = DFAStatusList.get(i);
        /* 状态 */
        sb.append("状态[").append(i).append("]").append(status.data.bFinal ? "[结束]" : "").append(" => ").append(status.data.getStatusString(NFAStatusList)).append(System.lineSeparator());
        /* 边 */
        for (DFAEdge edge : status.outEdges) {
            // 指向边
            sb.append("\t边 => [").append(DFAStatusList.indexOf(edge.end)).append("]").append(System.lineSeparator());
            sb.append("\t\t类型 => ").append(edge.data.kAction.getName());
            switch(// 类型
            edge.data.kAction) {
                case CHARSET:
                    // 区间
                    sb.append("\t").append(chMap.getRanges().get(edge.data.param));
                    break;
                case EPSILON:
                    break;
                default:
                    break;
            }
            sb.append(System.lineSeparator());
        }
    }
    return sb.toString();
}
Also used : DFAStatus(priv.bajdcc.util.lexer.automata.dfa.DFAStatus) NFAStatus(priv.bajdcc.util.lexer.automata.nfa.NFAStatus)

Example 2 with DFAStatus

use of priv.bajdcc.util.lexer.automata.dfa.DFAStatus in project jMiniLang by bajdcc.

the class DFA method mergeStatus.

/**
 * 合并相同状态
 *
 * @param pat
 *            状态划分
 * @param statusList
 *            状态转移表
 */
private boolean mergeStatus(ArrayList<ArrayList<Integer>> pat, ArrayList<DFAStatus> statusList) {
    /* 保存要处理的多状态合并的划分 */
    ArrayList<ArrayList<Integer>> dealWith = pat.stream().filter(collection -> collection.size() > 1).collect(Collectors.toCollection(ArrayList::new));
    /* 是否已经没有等价类,若没有,就返回false,这样算法就结束(收敛 ) */
    if (dealWith.isEmpty()) {
        return false;
    }
    /* 合并每一分组 */
    for (ArrayList<Integer> collection : dealWith) {
        /* 目标状态为集合中第一个状态,其余状态被合并 */
        int dstStatus = collection.get(0);
        /* 目标状态 */
        DFAStatus status = statusList.get(dstStatus);
        for (int i = 1; i < collection.size(); i++) {
            /* 重复的状态 */
            int srcStatus = collection.get(i);
            DFAStatus dupStatus = statusList.get(srcStatus);
            /* 备份重复状态的入边 */
            ArrayList<DFAEdge> edges = new ArrayList<>(dupStatus.inEdges);
            /* 将指向重复状态的边改为指向目标状态的边 */
            for (DFAEdge edge : edges) {
                /* 复制边 */
                connect(edge.begin, status).data = edge.data;
            }
            /* 去除重复状态 */
            disconnect(dupStatus);
        }
    }
    return true;
}
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) DFAStatus(priv.bajdcc.util.lexer.automata.dfa.DFAStatus) ArrayList(java.util.ArrayList)

Example 3 with DFAStatus

use of priv.bajdcc.util.lexer.automata.dfa.DFAStatus 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)

Example 4 with DFAStatus

use of priv.bajdcc.util.lexer.automata.dfa.DFAStatus in project jMiniLang by bajdcc.

the class DFA method buildTransition.

/**
 * 建立状态
 *
 * @param finalStatus 终态
 * @return 状态转换矩阵
 */
public int[][] buildTransition(Collection<Integer> finalStatus) {
    finalStatus.clear();
    /* DFA状态表 */
    ArrayList<DFAStatus> statusList = getDFATable();
    /* 建立状态转移矩阵 */
    int[][] transition = new int[statusList.size()][chMap.getRanges().size()];
    /* 填充状态转移表 */
    for (int i = 0; i < statusList.size(); i++) {
        DFAStatus status = statusList.get(i);
        if (status.data.bFinal) {
            // 标记终态
            finalStatus.add(i);
        }
        for (int j = 0; j < transition[i].length; j++) {
            // 置无效标记-1
            transition[i][j] = -1;
        }
        for (DFAEdge edge : status.outEdges) {
            if (edge.data.kAction == EdgeType.CHARSET) {
                transition[i][edge.data.param] = statusList.indexOf(edge.end);
            }
        }
    }
    return transition;
}
Also used : DFAStatus(priv.bajdcc.util.lexer.automata.dfa.DFAStatus)

Aggregations

DFAStatus (priv.bajdcc.util.lexer.automata.dfa.DFAStatus)4 NFAStatus (priv.bajdcc.util.lexer.automata.nfa.NFAStatus)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 NFAEdge (priv.bajdcc.util.lexer.automata.nfa.NFAEdge)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