UNPKG

parjs

Version:

A parser-combinator library for JavaScript.

116 lines (115 loc) 3.84 kB
"use strict"; /** * @module parjs/internal */ /** */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const result_1 = require("./result"); const state_1 = require("./state"); const defaults_1 = __importDefault(require("lodash/defaults")); const errors_1 = require("../errors"); const combinator_1 = require("./combinators/combinator"); function getErrorLocation(ps) { let endln = /\r\n|\n|\r/g; let { input, position } = ps; let lastPos = 0; let result; let line = 0; while ((result = endln.exec(ps.input))) { if (result.index > position) break; lastPos = result.index + result[0].length; line++; } return { line, column: line === 0 ? position : position - lastPos }; } /** * A marker class used for storing the parser's user state. */ class ParserUserState { } exports.ParserUserState = ParserUserState; /** * The base Parjs parser class, which supports only basic parsing operations. Should not be used in user code. */ class ParjserBase { /** * Apply the parser to the given state. * @param ps The parsing state. */ apply(ps) { let { position, userState } = ps; // we do this to verify that the ParsingState's fields have been correctly set by the parser. ps.kind = result_1.ResultKind.Unknown; ps.reason = undefined; ps.value = state_1.UNINITIALIZED_RESULT; this._apply(ps); if (ps.kind === result_1.ResultKind.Unknown) { throw new errors_1.ParserDefinitionError(this.type, "the parser's result kind field has not been set."); } if (!ps.isOk) { ps.value = state_1.FAIL_RESULT; ps.reason = ps.reason || this.expecting; } else if (ps.value === state_1.UNINITIALIZED_RESULT) { throw new errors_1.ParserDefinitionError(this.type, "a parser must set the result's value field if it succeeds."); } if (!ps.isOk) { if (ps.reason == null) { throw new errors_1.ParserDefinitionError(this.type, "a failure must have a reason"); } ps.stack.push(this); } else { ps.stack = []; } } parse(input, initialState) { if (typeof input !== "string") { // catches input === undefined, null throw new Error("input must be a valid string"); } let userState = defaults_1.default(new ParserUserState(), initialState); let ps = new state_1.BasicParsingState(input, userState); ps.initialUserState = initialState; this.apply(ps); if (ps.isOk) { if (ps.position !== input.length) { ps.kind = result_1.ResultKind.SoftFail; ps.reason = "parsers did not consume all input"; } } if (ps.kind === result_1.ResultKind.Unknown) { throw new Error("should not happen."); } let ret; if (ps.kind === result_1.ResultKind.Ok) { return new result_1.ParjsSuccess(ps.value); } else { let trace = { userState: ps.userState, position: ps.position, reason: ps.reason, input, get location() { return getErrorLocation(ps); }, stackTrace: ps.stack, kind: ps.kind }; return new result_1.ParjsFailure(trace); } } pipe(...funcs) { return combinator_1.pipe(this, ...funcs); } } exports.ParjserBase = ParjserBase; //# sourceMappingURL=parser.js.map