Introduce the FSM editor
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
be1cd8b39f
commit
877b162eaa
@ -0,0 +1,50 @@
|
|||||||
|
import { Graph } from './d3/graph.ts';
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
transitions: Record<string, number>;
|
||||||
|
start?: boolean;
|
||||||
|
accepting?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createGraph(states: State[]): Graph {
|
||||||
|
const graph = new Graph();
|
||||||
|
for (let i = 0; i < states.length; i++) {
|
||||||
|
const node = graph.createNode(i);
|
||||||
|
if (states[i].accepting) {
|
||||||
|
node.accepting = true;
|
||||||
|
}
|
||||||
|
if (i === 0) {
|
||||||
|
node.start = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < states.length; i++) {
|
||||||
|
const state = states[i];
|
||||||
|
for (const [letter, target] of Object.entries(state.transitions)) {
|
||||||
|
graph.createLink(i, target, letter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createStateList(graph: Graph): State[] {
|
||||||
|
const states: State[] = [];
|
||||||
|
// Map node ids to state ids, as graph nodes may contain gaps.
|
||||||
|
const reduced: { [id: number]: number } = {};
|
||||||
|
for (const node of graph.nodes) {
|
||||||
|
const state: State = {
|
||||||
|
transitions: {},
|
||||||
|
start: node.start,
|
||||||
|
accepting: node.accepting,
|
||||||
|
};
|
||||||
|
reduced[node.id] = states.length;
|
||||||
|
states.push(state);
|
||||||
|
}
|
||||||
|
for (const link of graph.links) {
|
||||||
|
const source = reduced[link.source.id];
|
||||||
|
const target = reduced[link.target.id];
|
||||||
|
for (const label of link.transition.split('')) {
|
||||||
|
states[source].transitions[label] = target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return states;
|
||||||
|
}
|
Loading…
Reference in new issue