UNPKG

antlr-ng

Version:

Next generation ANTLR Tool

178 lines (177 loc) 4.75 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); import { CommonToken, IntervalSet } from "antlr4ng"; import { ANTLRv4Parser } from "../../generated/ANTLRv4Parser.js"; import { CommonTree } from "../../tree/CommonTree.js"; class GrammarAST extends CommonTree { static { __name(this, "GrammarAST"); } /** A discriminator to distinguish between different grammar AST types without creating a circular dependency. */ astType = "GrammarAST"; /** For process AST nodes from imported grammars. */ g; /** If we build an ATN, we make AST node point at left edge of ATN construct */ atnState; textOverride; constructor(...args) { let nodeOrToken; if (args.length > 0) { if (typeof args[0] === "number") { const [type, t, text] = args; if (t === void 0) { nodeOrToken = CommonToken.fromType(type, ANTLRv4Parser.symbolicNames[type] ?? void 0); } else { nodeOrToken = CommonToken.fromToken(t); nodeOrToken.type = type; if (text !== void 0) { nodeOrToken.text = text; } } } else { nodeOrToken = args[0]; } } super(nodeOrToken); if (nodeOrToken instanceof GrammarAST) { this.g = nodeOrToken.g; this.atnState = nodeOrToken.atnState; this.textOverride = nodeOrToken.textOverride; } } getNodesWithType(typeOrTypes) { if (typeof typeOrTypes === "number") { return this.getNodesWithType(IntervalSet.of(typeOrTypes, typeOrTypes)); } const nodes = []; const work = []; work.push(this); while (work.length > 0) { const t = work.shift(); if (typeOrTypes === null || typeOrTypes.contains(t.getType())) { nodes.push(t); } if (t.children.length > 0) { work.push(...t.children); } } return nodes; } getAllChildrenWithType(type) { return this.children.filter((t) => { return t.getType() === type; }); } getNodesWithTypePreorderDFS(types) { const nodes = new Array(); this.doGetNodesWithTypePreorderDFS(nodes, types); return nodes; } getNodeWithTokenIndex(index) { if (this.token && this.token.tokenIndex === index) { return this; } for (const child of this.children) { const result = child.getNodeWithTokenIndex(index); if (result !== null) { return result; } } return null; } /** * Walk ancestors of this node until we find ALT with * alt!=null or leftRecursiveAltInfo!=null. Then grab label if any. * If not a rule element, just returns null. */ getAltLabel() { const ancestors = this.getAncestors(); if (ancestors === null) { return null; } for (let i = ancestors.length - 1; i >= 0; i--) { const p = ancestors[i]; if (p.getType() === ANTLRv4Parser.ALT) { const a = p; if (a.altLabel) { return a.altLabel.getText(); } if (a.leftRecursiveAltInfo) { return a.leftRecursiveAltInfo.altLabel ?? null; } } } return null; } deleteChild(param) { if (typeof param === "number") { return super.deleteChild(param); } for (const c of this.children) { if (c === param) { super.deleteChild(param.childIndex); return true; } } return false; } getFirstDescendantWithType(typeOrTypes) { if (typeof typeOrTypes === "number") { if (this.token?.type === typeOrTypes) { return this; } for (const c of this.children) { const t = c; if (t.token?.type === typeOrTypes) { return t; } const d = t.getFirstDescendantWithType(typeOrTypes); if (d !== null) { return d; } } return null; } if (this.token && typeOrTypes.get(this.token.type)) { return this; } for (const c of this.children) { const t = c; if (t.token && typeOrTypes.get(t.token.type)) { return t; } const d = t.getFirstDescendantWithType(typeOrTypes); if (d !== null) { return d; } } return null; } setType(type) { if (this.token) { this.token.type = type; } } setText(text) { if (this.token) { this.token.text = text; } } dupNode() { return new GrammarAST(this); } visit(v) { return v.visit(this); } doGetNodesWithTypePreorderDFS(nodes, types) { if (types.contains(this.getType())) { nodes.push(this); } this.children.forEach((child) => { child.doGetNodesWithTypePreorderDFS(nodes, types); }); } } export { GrammarAST };