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