UNPKG

@stackpress/idea-parser

Version:

Parses ideas to AST and readable JSON.

114 lines (113 loc) 3.57 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Exception_js_1 = __importDefault(require("./Exception.js")); class Lexer { constructor() { this._code = ''; this._index = 0; this._dictionary = {}; } get dictionary() { return Object.assign({}, this._dictionary); } get index() { return this._index; } clone() { const lexer = new Lexer(); lexer.load(this._code, this._index); for (const key in this._dictionary) { lexer.define(key, this._dictionary[key].reader); } return lexer; } define(key, reader) { this._dictionary[key] = { key, reader }; } expect(keys) { if (!Array.isArray(keys)) { keys = [keys]; } const definitions = keys.map(key => { const reader = this.get(key); if (!reader) { throw Exception_js_1.default.for('Unknown definition %s', key); } return reader; }).filter(Boolean); if (!definitions.length) { throw Exception_js_1.default.for('Unknown definitions %s', keys.join(', ')); } const match = this.match(this._code, this._index, keys); if (!match) { if (this._code[this._index + 10]) { throw Exception_js_1.default.for('Unexpected %s ... expecting %s', this._code .substring(this._index, this._index + 10) .replace(/[\n\r]/g, ' ') .trim(), keys.join(' or ')).withPosition(this._index, this.nextSpace()); } else { throw Exception_js_1.default.for('Unexpected %s expecting %s', this._code.substring(this._index, this._index + 10), keys.join(' or ')).withPosition(this._index, this.nextSpace()); } } this._index = match.end; return match; } get(key) { return this._dictionary[key]; } load(code, index = 0) { this._code = code; this._index = index; return this; } match(code, start, keys) { keys = keys || Object.keys(this._dictionary); for (let i = 0; i < keys.length; i++) { if (!this._dictionary[keys[i]]) { throw Exception_js_1.default.for('Unknown definition %s', keys[i]); } const results = this._dictionary[keys[i]].reader(code, start, this); if (results && results.end > start) { return results; } } return null; } next(names) { const start = this._index; try { this.expect(names); this._index = start; return true; } catch (error) { this._index = start; return false; } } optional(names) { const start = this._index; try { return this.expect(names); } catch (error) { this._index = start; return undefined; } } read() { return this.optional(Object.keys(this.dictionary)); } substring(start, end) { return this._code.substring(start, end); } nextSpace() { const index = this._code.indexOf(' ', this._index); return index === -1 ? this._code.length : index; } } exports.default = Lexer;