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