UNPKG

pegisland

Version:

General PEG-based parser supporting island grammars with lake symbols

98 lines 3.34 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PackratParsingEnv = exports.PackratParser = exports.ParsingError = void 0; // Copyright (C) 2021- Katsumi Okuda. All rights reserved. const line_column_1 = __importDefault(require("line-column")); const IParsingEnv_1 = require("./IParsingEnv"); const Position_1 = require("./Position"); const Printer_1 = require("./Printer"); const Stats_1 = require("./Stats"); function makeErrorMessage(env) { const finder = (0, line_column_1.default)(env.s); const info = finder.fromIndex(env.maxIndex); if (info) { return [ `Parsing error at offset line ${info.line} column ${info.col}.`, 'when parsing with the following parsing expressions:', ...[...env.deepestStack.map(Printer_1.peToString)].reverse(), ].join('\n'); } return `Parsing error at offset ${env.maxIndex}`; } class ParsingError extends Error { constructor(env) { super(makeErrorMessage(env)); this.env = env; } } exports.ParsingError = ParsingError; class PackratParser { constructor(rules) { this.rules = rules; } parse(s, startSymbol, stats) { const rule = this.getStartRule(startSymbol); if (rule instanceof Error) { return rule; } const env = new PackratParsingEnv(s, stats); const result = rule.parse(env, new Position_1.Position(0, 1, 1)); if (result === null) { return new ParsingError(env); } const [tree, nextPos] = result; if (nextPos.offset < s.length) { return new ParsingError(env); } return tree; } getStartRule(startSymbol) { let rule = this.rules.values().next().value; if (startSymbol) { if (this.rules.has(startSymbol)) { rule = this.rules.get(startSymbol); } else { return Error(`Nonterminal symbol ${startSymbol} does not exist in the grammar.`); } } return rule; } } exports.PackratParser = PackratParser; class PackratParsingEnv extends IParsingEnv_1.BaseParsingEnv { constructor(s, stats = new Stats_1.Stats()) { super(s); this.stats = stats; this.deepestStack = []; this.maxIndex = 0; this.currentStack = []; } parseRule(rule, pos) { if (!this.memo[pos.offset].has(rule)) { this.stats.memoMissCount++; this.memo[pos.offset].set(rule, rule.parse(this, pos)); } this.stats.memoAccessCount++; const result = this.memo[pos.offset].get(rule); if (result === null) { this.stats.failureCount++; } return result; } parse(pe, pos) { this.currentStack.push(pe); if (pos.offset >= this.maxIndex) { this.maxIndex = pos.offset; this.deepestStack = [...this.currentStack]; } const result = pe.accept(this.recognizer, pos); this.currentStack.pop(); return result; } } exports.PackratParsingEnv = PackratParsingEnv; //# sourceMappingURL=PackratParser.js.map