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);
}
}
}
}
}
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);
}
Aggregations