UNPKG

ima-parse

Version:

Easy Simple Parser, that only requires a Grammar JSON to output an AST.

73 lines (72 loc) 3.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RuleParser = void 0; const definitionParsers_1 = require("./definitionParsers"); const helpers_1 = require("../helpers/helpers"); class RuleParser { rule; grammar; parent; parsedParts = []; /** Rules that are not part of the definition of this rule but are children of this one (comments/macros and such) */ globalParsedParts = []; constructor(rule, grammar, parent) { this.rule = rule; this.grammar = grammar; this.parent = parent; } /** * Try to parse whatever phrase is given with the current or next part. It's not up to us to decide if it must succeed, we just try * to do it and if it succeeds, we add another ParsedPart to the progress list (`this.parsedParts`) */ parsePhrase(input) { const previousPart = this.parsedParts.at(-1); const parsedPart = (0, definitionParsers_1.parseInput)(input, { grammar: this.grammar, parts: this.rule.definition, parser: this }, previousPart); if (parsedPart) { // We override the same part, if for instance the parsed part adds more information, for example when building a string. if (parsedPart.overrideSamePart && this.parsedParts.at(-1)?.index === parsedPart.index) { this.parsedParts.splice(this.parsedParts.length - 1, 1, parsedPart); } else { this.parsedParts.push(parsedPart); } return { success: true, ruleParser: parsedPart.type === "rule" ? parsedPart.successfulParser : this }; } return { success: false, error: "" }; } hasRequiredPartsLeft() { return !(0, definitionParsers_1.isDefinitionSatisfied)(this.rule.definition, this.parsedParts); } getPosition() { return { start: { ...this.getStartCursor() }, end: { ...this.getEndCursor() } }; } getStartCursor() { const parsedPart = this.parsedParts.at(0); switch (parsedPart?.type) { case "simple": return { ...parsedPart.startPos }; case "paths": // We know that if there is a paths part, we never delete the progress which allowed it to exist. That's why we can assume '!' return { ...parsedPart.pathsProgress.at(0).parsedParts.at(0).startPos }; case "rule": return parsedPart.childParser.getStartCursor(); default: (0, helpers_1.assertNever)(parsedPart); } } getEndCursor() { const parsedPart = this.parsedParts.at(-1); switch (parsedPart?.type) { case "simple": return { ...parsedPart.endPos }; case "paths": // We know that if there is a paths part, we never delete the progress which allowed it to exist. That's why we can assume '!' return { ...parsedPart.pathsProgress.at(0).parsedParts.at(-1).endPos }; case "rule": return parsedPart.childParser.getEndCursor(); default: (0, helpers_1.assertNever)(parsedPart); } } } exports.RuleParser = RuleParser;