UNPKG

antlr-ng

Version:

Next generation ANTLR Tool

112 lines (111 loc) 3.93 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); import { GrammarTreeVisitor } from "../tree/walkers/GrammarTreeVisitor.js"; import { MultiMap } from "stringtemplate4ts"; import { LeftRecursiveRuleAnalyzer } from "../analysis/LeftRecursiveRuleAnalyzer.js"; import { DictType } from "../misc/types.js"; import { Utils } from "../misc/Utils.js"; import { ScopeParser } from "../parse/ScopeParser.js"; import { Grammar } from "../tool/Grammar.js"; import { LeftRecursiveRule } from "../tool/LeftRecursiveRule.js"; import { Rule } from "../tool/Rule.js"; class RuleCollector extends GrammarTreeVisitor { static { __name(this, "RuleCollector"); } /** Which grammar are we checking? */ g; nameToRuleMap = /* @__PURE__ */ new Map(); ruleToAltLabels = new MultiMap(); altLabelToRuleName = /* @__PURE__ */ new Map(); grammarCaseInsensitive = false; constructor(g) { super(g.tool.errorManager); this.g = g; } process(ast) { this.visitGrammar(ast); } discoverRule(rule, id, modifiers, arg, returns, thrws, options, locals, actions, block) { const numAlts = block.children.length; let r; if (LeftRecursiveRuleAnalyzer.hasImmediateRecursiveRuleRefs(rule, id.getText())) { r = new LeftRecursiveRule(this.g, id.getText(), rule); } else { r = new Rule(this.g, id.getText(), rule, numAlts); } this.nameToRuleMap.set(r.name, r); if (arg !== void 0) { r.args = ScopeParser.parseTypedArgList(arg, arg.getText(), this.g); r.args.type = DictType.Argument; r.args.ast = arg; arg.resolver = r.alt[this.currentOuterAltNumber]; } if (returns !== void 0) { r.retvals = ScopeParser.parseTypedArgList(returns, returns.getText(), this.g); r.retvals.type = DictType.Return; r.retvals.ast = returns; } if (locals !== void 0) { r.locals = ScopeParser.parseTypedArgList(locals, locals.getText(), this.g); r.locals.type = DictType.Local; r.locals.ast = locals; } for (const a of actions) { const action = a.children[1]; r.namedActions.set(a.children[0].getText(), action); action.resolver = r; } } discoverOuterAlt(alt) { if (alt.altLabel && this.currentRuleName) { this.ruleToAltLabels.map(this.currentRuleName, alt.altLabel); const altLabel = alt.altLabel.getText(); this.altLabelToRuleName.set(Utils.capitalize(altLabel), this.currentRuleName); this.altLabelToRuleName.set(Utils.decapitalize(altLabel), this.currentRuleName); } } grammarOption(id, valueAST) { const caseInsensitive = this.getCaseInsensitiveValue(id, valueAST); if (caseInsensitive !== null) { this.grammarCaseInsensitive = caseInsensitive; } } discoverLexerRule(rule, id, modifiers, options, block) { let currentCaseInsensitive = this.grammarCaseInsensitive; if (options !== null) { for (const child of options.children) { const childAST = child; const caseInsensitive = this.getCaseInsensitiveValue( childAST.children[0], childAST.children[1] ); if (caseInsensitive !== null) { currentCaseInsensitive = caseInsensitive; } } } const numAlts = block.children.length; const r = new Rule(this.g, id.getText(), rule, numAlts, this.currentModeName, currentCaseInsensitive); if (modifiers.length != 0) { r.modifiers = modifiers; } this.nameToRuleMap.set(r.name, r); } getCaseInsensitiveValue(optionID, valueAST) { const optionName = optionID.getText(); if (optionName === Grammar.caseInsensitiveOptionName) { const valueText = valueAST.getText(); if (valueText === "true") { return true; } if (valueText === "false") { return false; } } return null; } } export { RuleCollector };