antlr-ng
Version:
Next generation ANTLR Tool
178 lines (177 loc) • 4.75 kB
JavaScript
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
};