UNPKG

antlr-ng

Version:

Next generation ANTLR Tool

82 lines (81 loc) 2.83 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); import { Token } from "antlr4ng"; import { TreePatternLexer } from "./TreePatternLexer.js"; import { TreePatternParser } from "./TreePatternParser.js"; import { WildcardTreePattern } from "./WildcardTreePattern.js"; class TreeWizard { static { __name(this, "TreeWizard"); } tokenNameToTypeMap; constructor(tokenNames) { this.tokenNameToTypeMap = this.computeTokenTypes(tokenNames); } /** * Given a pattern like (ASSIGN %lhs:ID %rhs:.) with optional labels on the various nodes and '.' (dot) as * the node/subtree wildcard, returns true if the pattern matches and fill the labels Map with the labels pointing * at the appropriate nodes. Returns false if the pattern is malformed or the tree does not match. * * If a node specifies a text arg in pattern, then that must match for that node in t. */ parse(t, pattern, labels) { const tokenizer = new TreePatternLexer(pattern); const parser = new TreePatternParser(tokenizer, this); const tpattern = parser.pattern(); const matched = this.doParse(t, tpattern, labels ?? null); return matched; } /** Using the map of token names to token types, returns the type. */ getTokenType(tokenName) { if (!this.tokenNameToTypeMap) { return Token.INVALID_TYPE; } return this.tokenNameToTypeMap.get(tokenName) ?? Token.INVALID_TYPE; } /** * Computes a map that is an inverted index of tokenNames (which maps int token types to names). */ computeTokenTypes(tokenNames) { const m = /* @__PURE__ */ new Map(); for (let ttype = 0; ttype < tokenNames.length; ttype++) { const name = tokenNames[ttype]; m.set(name, ttype); } return m; } /** * Does the work for parse. Check to see if the t2 pattern fits the structure and token types in t1. Check text * if the pattern has text arguments on nodes. Fill labels map with pointers to nodes in tree matched against * nodes in pattern with labels. */ doParse(t1, tpattern, labels) { if (!(tpattern instanceof WildcardTreePattern)) { if (t1.getType() !== tpattern.getType()) { return false; } if (tpattern.hasTextArg && t1.getText() !== tpattern.getText()) { return false; } } if (tpattern.label && labels !== null) { labels.set(tpattern.label, t1); } const n1 = t1.children.length; const n2 = tpattern.children.length; if (n1 !== n2) { return false; } for (let i = 0; i < n1; i++) { const child1 = t1.children[i]; const child2 = tpattern.children[i]; if (!this.doParse(child1, child2, labels)) { return false; } } return true; } } export { TreeWizard };