UNPKG

@masala/parser

Version:
256 lines (213 loc) 7.51 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.string = string; var _parser = require('./parser'); var _parser2 = _interopRequireDefault(_parser); var _response = require('./response'); var _response2 = _interopRequireDefault(_response); var _tuple = require('../data/tuple'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // (Stream 'c -> number -> Response 'a 'c) -> Parser 'a 'c function parse(p) { return new _parser2.default(p); } // (('b -> Parser 'a 'c) * 'b)-> Parser 'a 'c /* * Parsec * https://github.com/d-plaindoux/parsec * * Copyright (c) 2016 Didier Plaindoux * Licensed under the LGPL2 license. */ function lazy(p, parameters) { var self = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (parameters && !Array.isArray(parameters)) { throw 'Lazy(parser, [params]) function expect parser parameters to be packed into an array'; } // equivalent of p(...parameters), but would fail if parameters are undefined // In some case, p is a function that require a 'this' bound to the function // https://github.com/d-plaindoux/masala-parser/issues/9 return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return p.apply(self, parameters).parse(input, index); }); } // 'a -> Parser 'a 'c function returns(v) { return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return _response2.default.accept(v, input, index, false); }); } // unit -> Parser 'a 'c function error() { return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; // TODO: add an optional logger parameter, and log return _response2.default.reject(input, index, false); }); } // ('a -> boolean) -> Parser a 'c // index is forwarded at index +1 function satisfy(predicate) { return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return input.get(index).filter(predicate).map(function (value) { return _response2.default.accept(value, input, index + 1, true); }).lazyRecoverWith(function () { return _response2.default.reject(input, index, false); }); }); } // Parser 'a 'c -> Parser 'a 'c function doTry(p) { return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return p.parse(input, index).fold(function (accept) { return accept; }, // Compared to satisfy, we come back to initial offset function (reject) { return _response2.default.reject(input, reject.offset, false); }); }); } function layer(p) { return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return p.parse(input, index).fold(function (accept) { // TODO logger return _response2.default.accept(new _tuple.Tuple().append(accept.value), input, index, false); }, // Compared to satisfy, we come back to initial offset function (reject) { return reject; }); }); } // unit -> Parser 'a 'c function any() { return satisfy(function () { return true; }); } // unit -> Parser 'a 'c function nop() { return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return _response2.default.accept(_tuple.NEUTRAL, input, index, true); }); } // Parser 'a ? -> Parser 'a 'a function not(p) { return doTry(p).then(error()).or(any()); } // int -> Parser (List 'a') a' function subStream(length) { return any().occurrence(length); } function startWith(value) { return nop().returns(value); } function moveUntil(stop) { if (typeof stop === 'string') { return searchStringStart(stop); } if (Array.isArray(stop)) { return searchArrayStringStart(stop); } // TODO: change undefined by a Symbol // TODO: for better performance, maybe check in the map if the symbol is included, and remove the or var foundEos = Symbol('found-eos'); return doTry(not(stop).rep().then((0, _parser.eos)()).returns(foundEos)).or(not(stop).rep().map(function (chars) { return chars.join(''); })).filter(function (v) { return v !== foundEos; }); } function dropTo(stop) { if (typeof stop === 'string') { return moveUntil(stop).then(string(stop)).drop(); } else { return moveUntil(stop).then(stop).drop(); } } exports.default = { parse: parse, nop: nop, try: doTry, any: any, subStream: subStream, not: not, layer: layer, lazy: lazy, returns: returns, error: error, eos: _parser.eos, satisfy: satisfy, startWith: startWith, moveUntil: moveUntil, dropTo: dropTo }; /**Optimization functions */ /** * Will work only if input.source is a String * @param string * @returns {Parser} */ function searchStringStart(string) { return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; if (typeof input.source !== 'string') { throw 'Input source must be a String'; } var sourceIndex = input.source.indexOf(string, index); if (sourceIndex > 0) { return _response2.default.accept(input.source.substring(index, sourceIndex), input, sourceIndex, true); } else { return _response2.default.reject(input, index, false); } }); } /** * Will work only if input.source is a String */ function searchArrayStringStart(array) { return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; if (typeof input.source !== 'string') { throw 'Input source must be a String'; } var sourceIndex = -1; var i = 0; while (sourceIndex < 0 && i < array.length) { var needle = array[i]; sourceIndex = input.source.indexOf(needle, index); i++; if (sourceIndex > 0) { break; } } //const sourceIndex = input.source.indexOf(string, index) if (sourceIndex > 0) { return _response2.default.accept(input.source.substring(index, sourceIndex), input, sourceIndex, true); } else { return _response2.default.reject(input, index, false); } }); } // string -> Parser string char // index is forwarded at the length of the string function string(s) { return new _parser2.default(function (input) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; if (input.subStreamAt(s.split(''), index)) { return _response2.default.accept(s, input, index + s.length, true); } else { return _response2.default.reject(input, index, false); } }); } //# sourceMappingURL=flow-bundle.js.map