ima-parse
Version:
Easy Simple Parser, that only requires a Grammar JSON to output an AST.
73 lines (72 loc) • 3.23 kB
JavaScript
"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;