UNPKG

antlr-ng

Version:

Next generation ANTLR Tool

124 lines (123 loc) 3.34 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); import { Rule } from "./Rule.js"; class LeftRecursiveRule extends Rule { static { __name(this, "LeftRecursiveRule"); } /** Did we delete any labels on direct left-recur refs? Points at ID of ^(= ID el) */ leftRecursiveRuleRefLabels = new Array(); recPrimaryAlts; recOpAlts; originalAST; constructor(g, name, ast) { super(g, name, ast, 1); this.originalAST = ast; } hasAltSpecificContexts() { return super.hasAltSpecificContexts() || this.getAltLabels() !== null; } getOriginalNumberOfAlts() { return this.recPrimaryAlts.length + this.recOpAlts.size; } getOriginalAST() { return this.originalAST; } getUnlabeledAltASTs() { const alts = new Array(); for (const altInfo of this.recPrimaryAlts) { if (altInfo.altLabel === void 0) { alts.push(altInfo.originalAltAST); } } for (let i = 0; i < this.recOpAlts.size; i++) { const altInfo = this.recOpAlts.getElement(i); if (altInfo.altLabel === void 0) { alts.push(altInfo.originalAltAST); } } if (alts.length === 0) { return null; } return alts; } /** * @returns an array that maps predicted alt from primary decision to original alt of rule. For following rule, * returns [0, 2, 4] * * ```antlr * e : e '*' e * | INT * | e '+' e * | ID * ; * ``` * * That maps predicted alt 1 to original alt 2 and predicted 2 to alt 4. */ getPrimaryAlts() { const alts = [0]; for (const altInfo of this.recPrimaryAlts) { alts.push(altInfo.altNum); } return alts; } /** * @returns an array that maps predicted alt from recursive op decision to original alt of rule. For following rule, * returns [0, 1, 3] * * ```antlr * e : e '*' e * | INT * | e '+' e * | ID * ; * ``` * That maps predicted alt 1 to original alt 1 and predicted 2 to alt 3. */ getRecursiveOpAlts() { const alts = [0]; for (const [_, altInfo] of this.recOpAlts) { alts.push(altInfo.altNum); } return alts; } /** @returns labels from those alts we deleted for left-recursive rules. */ getAltLabels() { const labels = /* @__PURE__ */ new Map(); const normalAltLabels = super.getAltLabels(); if (normalAltLabels !== null) { normalAltLabels.forEach((value, key) => { labels.set(key, value); }); } for (const altInfo of this.recPrimaryAlts) { if (altInfo.altLabel !== void 0) { let pairs = labels.get(altInfo.altLabel); if (!pairs) { pairs = []; labels.set(altInfo.altLabel, pairs); } pairs.push([altInfo.altNum, altInfo.originalAltAST]); } } for (let i = 0; i < this.recOpAlts.size; i++) { const altInfo = this.recOpAlts.getElement(i); if (altInfo.altLabel !== void 0) { let pairs = labels.get(altInfo.altLabel); if (!pairs) { pairs = []; labels.set(altInfo.altLabel, pairs); } pairs.push([altInfo.altNum, altInfo.originalAltAST]); } } if (labels.size === 0) { return null; } return labels; } } export { LeftRecursiveRule };