UNPKG

antlr-ng

Version:

Next generation ANTLR Tool

84 lines (83 loc) 2.05 kB
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 };