antlr-ng
Version:
Next generation ANTLR Tool
84 lines (83 loc) • 2.05 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
class Graph {
static {
__name(this, "Graph");
}
static Node = class Node {
static {
__name(this, "Node");
}
payload;
edges = [];
// points at which nodes?
constructor(payload) {
this.payload = payload;
}
addEdge(n) {
if (!this.edges.includes(n)) {
this.edges.push(n);
}
}
toString() {
return String(this.payload);
}
};
/** Map from node payload to node containing it */
nodes = /* @__PURE__ */ new Map();
addEdge(a, b) {
const aNode = this.getNode(a);
const bNode = this.getNode(b);
aNode.addEdge(bNode);
}
getNode(a) {
const existing = this.nodes.get(a);
if (existing) {
return existing;
}
const n = new Graph.Node(a);
this.nodes.set(a, n);
return n;
}
/**
* DFS-based topological sort. A valid sort is the reverse of the post-order DFA traversal. Amazingly simple
* but true. For sorting, I'm not following convention here since ANTLR needs the opposite. Here's what I
* assume for sorting:
*
* If there exists an edge u -> v then u depends on v and v must happen before u.
*
* So if this gives non-reversed post order traversal, I get the order I want.
*
* @returns A list of node payloads in topological order.
*/
sort() {
const visited = /* @__PURE__ */ new Set();
const sorted = new Array();
while (visited.size < this.nodes.size) {
let n = null;
for (const tNode of this.nodes.values()) {
n = tNode;
if (!visited.has(n)) {
break;
}
}
if (n !== null) {
this.dfs(n, visited, sorted);
}
}
return sorted;
}
dfs(n, visited, sorted) {
if (visited.has(n)) {
return;
}
visited.add(n);
for (const target of n.edges) {
this.dfs(target, visited, sorted);
}
sorted.push(n.payload);
}
}
export {
Graph
};