UNPKG

molstar

Version:

A comprehensive macromolecular library.

522 lines (521 loc) 19 kB
/** * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> * @author Koya Sakuma <koya.sakuma.work@gmail.com> ** * Adapted from Parsimmon (https://github.com/jneen/parsimmon) * Copyright (c) 2011-present J. Adkisson (http://jneen.net). **/ import { __spreadArray } from "tslib"; var MonadicParser = /** @class */ (function () { function MonadicParser(_) { this._ = _; } MonadicParser.prototype.parse = function (input) { var result = this.skip(MonadicParser.eof)._(input, 0); if (result.status) { return { success: true, value: result.value }; } return { success: false, index: makeLineColumnIndex(input, result.furthest), expected: result.expected }; }; ; MonadicParser.prototype.tryParse = function (str) { var result = this.parse(str); if (result.success) { return result.value; } else { var msg = formatError(str, result); var err = new Error(msg); throw err; } }; MonadicParser.prototype.or = function (alternative) { return MonadicParser.alt(this, alternative); }; MonadicParser.prototype.trim = function (parser) { return this.wrap(parser, parser); }; MonadicParser.prototype.wrap = function (leftParser, rightParser) { return seqPick(1, typeof leftParser === 'string' ? MonadicParser.string(leftParser) : leftParser, this, typeof rightParser === 'string' ? MonadicParser.string(rightParser) : rightParser); }; MonadicParser.prototype.thru = function (wrapper) { return wrapper(this); }; MonadicParser.prototype.then = function (next) { return seqPick(1, this, next); }; MonadicParser.prototype.many = function () { var _this = this; return new MonadicParser(function (input, i) { var accum = []; var result = void 0; while (true) { result = mergeReplies(_this._(input, i), result); if (result.status) { if (i === result.index) { throw new Error('infinite loop detected in .many() parser --- calling .many() on a parser which can accept zero characters is usually the cause'); } i = result.index; accum.push(result.value); } else { return mergeReplies(makeSuccess(i, accum), result); } } }); }; ; MonadicParser.prototype.times = function (min, _max) { var _this = this; var max = typeof _max === 'undefined' ? min : _max; return new MonadicParser(function (input, i) { var accum = []; var result = void 0; var prevResult = void 0; var times; for (times = 0; times < min; times++) { result = _this._(input, i); prevResult = mergeReplies(result, prevResult); if (result.status) { i = result.index; accum.push(result.value); } else { return prevResult; } } for (; times < max; times += 1) { result = _this._(input, i); prevResult = mergeReplies(result, prevResult); if (result.status) { i = result.index; accum.push(result.value); } else { break; } } return mergeReplies(makeSuccess(i, accum), prevResult); }); }; ; MonadicParser.prototype.result = function (res) { return this.map(function () { return res; }); }; ; MonadicParser.prototype.atMost = function (n) { return this.times(0, n); }; ; MonadicParser.prototype.atLeast = function (n) { return MonadicParser.seq(this.times(n), this.many()).map(function (r) { return __spreadArray(__spreadArray([], r[0], true), r[1], true); }); }; ; MonadicParser.prototype.map = function (f) { var _this = this; return new MonadicParser(function (input, i) { var result = _this._(input, i); if (!result.status) { return result; } return mergeReplies(makeSuccess(result.index, f(result.value)), result); }); }; MonadicParser.prototype.skip = function (next) { return seqPick(0, this, next); }; MonadicParser.prototype.mark = function () { return MonadicParser.seq(MonadicParser.index, this, MonadicParser.index).map(function (r) { return ({ start: r[0], value: r[1], end: r[2] }); }); }; MonadicParser.prototype.node = function (name) { return MonadicParser.seq(MonadicParser.index, this, MonadicParser.index).map(function (r) { return ({ name: name, start: r[0], value: r[1], end: r[2] }); }); }; ; MonadicParser.prototype.sepBy = function (separator) { return MonadicParser.sepBy(this, separator); }; MonadicParser.prototype.sepBy1 = function (separator) { return MonadicParser.sepBy1(this, separator); }; MonadicParser.prototype.lookahead = function (x) { return this.skip(MonadicParser.lookahead(x)); }; ; MonadicParser.prototype.notFollowedBy = function (x) { return this.skip(MonadicParser.notFollowedBy(x)); }; ; MonadicParser.prototype.desc = function (expected) { var _this = this; return new MonadicParser(function (input, i) { var reply = _this._(input, i); if (!reply.status) { reply.expected = [expected]; } return reply; }); }; ; MonadicParser.prototype.fallback = function (result) { return this.or(MonadicParser.succeed(result)); }; ; MonadicParser.prototype.ap = function (other) { return MonadicParser.seq(other, this).map(function (_a) { var f = _a[0], x = _a[1]; return f(x); }); }; ; MonadicParser.prototype.chain = function (f) { var _this = this; return new MonadicParser(function (input, i) { var result = _this._(input, i); if (!result.status) { return result; } var nextParser = f(result.value); return mergeReplies(nextParser._(input, result.index), result); }); }; ; return MonadicParser; }()); export { MonadicParser }; (function (MonadicParser) { function seqMap(a, b, c) { var args = [].slice.call(arguments); if (args.length === 0) { throw new Error('seqMap needs at least one argument'); } var mapper = args.pop(); assertFunction(mapper); return seq.apply(null, args).map(function (results) { return mapper.apply(null, results); }); } MonadicParser.seqMap = seqMap; function createLanguage(parsers) { var language = {}; for (var _i = 0, _a = Object.keys(parsers); _i < _a.length; _i++) { var key = _a[_i]; (function (key) { language[key] = lazy(function () { return parsers[key](language); }); })(key); } return language; } MonadicParser.createLanguage = createLanguage; function seq() { var parsers = []; for (var _i = 0; _i < arguments.length; _i++) { parsers[_i] = arguments[_i]; } var numParsers = parsers.length; return new MonadicParser(function (input, index) { var result; var accum = new Array(numParsers); var i = index; for (var j = 0; j < numParsers; j++) { result = mergeReplies(parsers[j]._(input, i), result); if (!result.status) { return result; } accum[j] = result.value; i = result.index; } return mergeReplies(makeSuccess(i, accum), result); }); } MonadicParser.seq = seq; function alt() { var parsers = []; for (var _i = 0; _i < arguments.length; _i++) { parsers[_i] = arguments[_i]; } var numParsers = parsers.length; if (numParsers === 0) { return fail('zero alternates'); } return new MonadicParser(function (input, i) { var result; for (var j = 0; j < parsers.length; j++) { result = mergeReplies(parsers[j]._(input, i), result); if (result.status) { return result; } } return result; }); } MonadicParser.alt = alt; function sepBy(parser, separator) { return sepBy1(parser, separator).or(succeed([])); } MonadicParser.sepBy = sepBy; function sepBy1(parser, separator) { var pairs = separator.then(parser).many(); return seq(parser, pairs).map(function (r) { return __spreadArray([r[0]], r[1], true); }); } MonadicParser.sepBy1 = sepBy1; function string(str) { var expected = "'".concat(str, "'"); if (str.length === 1) { var code_1 = str.charCodeAt(0); return new MonadicParser(function (input, i) { return input.charCodeAt(i) === code_1 ? makeSuccess(i + 1, str) : makeFailure(i, expected); }); } return new MonadicParser(function (input, i) { var j = i + str.length; if (input.slice(i, j) === str) return makeSuccess(j, str); else return makeFailure(i, expected); }); } MonadicParser.string = string; function flags(re) { var s = '' + re; return s.slice(s.lastIndexOf('/') + 1); } function anchoredRegexp(re) { return RegExp('^(?:' + re.source + ')', flags(re)); } function regexp(re, group) { if (group === void 0) { group = 0; } var anchored = anchoredRegexp(re); var expected = '' + re; return new MonadicParser(function (input, i) { var match = anchored.exec(input.slice(i)); if (match) { if (0 <= group && group <= match.length) { var fullMatch = match[0]; var groupMatch = match[group]; return makeSuccess(i + fullMatch.length, groupMatch); } var message = "invalid match group (0 to ".concat(match.length, ") in ").concat(expected); return makeFailure(i, message); } return makeFailure(i, expected); }); } MonadicParser.regexp = regexp; function succeed(value) { return new MonadicParser(function (input, i) { return makeSuccess(i, value); }); } MonadicParser.succeed = succeed; function fail(expected) { return new MonadicParser(function (input, i) { return makeFailure(i, expected); }); } MonadicParser.fail = fail; function lookahead(x) { if (isParser(x)) { return new MonadicParser(function (input, i) { var result = x._(input, i); if (result.status) { result.index = i; result.value = null; } return result; }); } else if (typeof x === 'string') { return lookahead(string(x)); } else if (x instanceof RegExp) { return lookahead(regexp(x)); } throw new Error('not a string, regexp, or parser: ' + x); } MonadicParser.lookahead = lookahead; function notFollowedBy(parser) { return new MonadicParser(function (input, i) { var result = parser._(input, i); return result.status ? makeFailure(i, 'not "' + input.slice(i, result.index) + '"') : makeSuccess(i, null); }); } MonadicParser.notFollowedBy = notFollowedBy; function test(predicate) { return new MonadicParser(function (input, i) { var char = input.charAt(i); if (i < input.length && predicate(char)) { return makeSuccess(i + 1, char); } else { return makeFailure(i, 'a character ' + predicate); } }); } MonadicParser.test = test; function oneOf(str) { return test(function (ch) { return str.indexOf(ch) >= 0; }); } MonadicParser.oneOf = oneOf; function noneOf(str) { return test(function (ch) { return str.indexOf(ch) < 0; }); } MonadicParser.noneOf = noneOf; function range(begin, end) { return test(function (ch) { return begin <= ch && ch <= end; }).desc(begin + '-' + end); } MonadicParser.range = range; function takeWhile(predicate) { return new MonadicParser(function (input, i) { var j = i; while (j < input.length && predicate(input.charAt(j))) { j++; } return makeSuccess(j, input.slice(i, j)); }); } MonadicParser.takeWhile = takeWhile; function lazy(f) { var parser = new MonadicParser(function (input, i) { var a = f()._; parser._ = a; return a(input, i); }); return parser; } MonadicParser.lazy = lazy; function empty() { return fail('empty'); } MonadicParser.empty = empty; MonadicParser.index = new MonadicParser(function (input, i) { return makeSuccess(i, makeLineColumnIndex(input, i)); }); MonadicParser.anyChar = new MonadicParser(function (input, i) { if (i >= input.length) { return makeFailure(i, 'any character'); } return makeSuccess(i + 1, input.charAt(i)); }); MonadicParser.all = new MonadicParser(function (input, i) { return makeSuccess(input.length, input.slice(i)); }); MonadicParser.eof = new MonadicParser(function (input, i) { if (i < input.length) { return makeFailure(i, 'EOF'); } return makeSuccess(i, null); }); MonadicParser.digit = regexp(/[0-9]/).desc('a digit'); MonadicParser.digits = regexp(/[0-9]*/).desc('optional digits'); MonadicParser.letter = regexp(/[a-z]/i).desc('a letter'); MonadicParser.letters = regexp(/[a-z]*/i).desc('optional letters'); MonadicParser.optWhitespace = regexp(/\s*/).desc('optional whitespace'); MonadicParser.whitespace = regexp(/\s+/).desc('whitespace'); MonadicParser.cr = string('\r'); MonadicParser.lf = string('\n'); MonadicParser.crlf = string('\r\n'); MonadicParser.newline = alt(MonadicParser.crlf, MonadicParser.lf, MonadicParser.cr).desc('newline'); MonadicParser.end = alt(MonadicParser.newline, MonadicParser.eof); function of(value) { return succeed(value); } MonadicParser.of = of; function regex(re) { return regexp(re); } MonadicParser.regex = regex; })(MonadicParser || (MonadicParser = {})); function seqPick(idx) { var parsers = []; for (var _i = 1; _i < arguments.length; _i++) { parsers[_i - 1] = arguments[_i]; } var numParsers = parsers.length; return new MonadicParser(function (input, index) { var result; var picked; var i = index; for (var j = 0; j < numParsers; j++) { result = mergeReplies(parsers[j]._(input, i), result); if (!result.status) { return result; } if (idx === j) picked = result.value; i = result.index; } return mergeReplies(makeSuccess(i, picked), result); }); } function makeSuccess(index, value) { return { status: true, index: index, value: value }; } function makeFailure(index, expected) { return { status: false, furthest: index, expected: [expected] }; } function mergeReplies(result, last) { if (!last || result.status || last.status || result.furthest > last.furthest) { return result; } var expected = result.furthest === last.furthest ? unsafeUnion(result.expected, last.expected) : last.expected; return { status: result.status, furthest: last.furthest, expected: expected }; } function makeLineColumnIndex(input, i) { var lines = input.slice(0, i).split('\n'); // Note that unlike the character offset, the line and column offsets are // 1-based. var lineWeAreUpTo = lines.length; var columnWeAreUpTo = lines[lines.length - 1].length + 1; return { offset: i, line: lineWeAreUpTo, column: columnWeAreUpTo }; } function formatExpected(expected) { if (expected.length === 1) { return expected[0]; } return 'one of ' + expected.join(', '); } function formatGot(input, error) { var index = error.index; var i = index.offset; if (i === input.length) { return ', got the end of the input'; } var prefix = i > 0 ? '\'...' : '\''; var suffix = input.length - i > 12 ? '...\'' : '\''; return " at line ".concat(index.line, " column ").concat(index.column, ", got ").concat(prefix).concat(input.slice(i, i + 12)).concat(suffix); } function formatError(input, error) { return "expected ".concat(formatExpected(error.expected)).concat(formatGot(input, error)); } function unsafeUnion(xs, ys) { var xn = xs.length; var yn = ys.length; if (xn === 0) return ys; else if (yn === 0) return xs; var set = new Set(); var ret = []; for (var i = 0; i < xn; i++) { if (!set.has(xs[i])) { ret[ret.length] = xs[i]; set.add(xs[i]); } } for (var i = 0; i < yn; i++) { if (!set.has(ys[i])) { ret[ret.length] = ys[i]; set.add(ys[i]); } } ret.sort(); return ret; } function isParser(obj) { return obj instanceof MonadicParser; } function assertFunction(x) { if (typeof x !== 'function') { throw new Error('not a function: ' + x); } }