parser-combinator
Version:
Parser combinators
252 lines (212 loc) • 8.69 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _index = require('../../index');
var _response = require('./../../parsec/response');
var _response2 = _interopRequireDefault(_response);
var _parser = require('./../../parsec/parser');
var _parser2 = _interopRequireDefault(_parser);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Created by nicorama on 10/01/2017.
*/
var ExtractorBundle = function () {
function ExtractorBundle(options) {
_classCallCheck(this, ExtractorBundle);
this.options = {
spacesCharacters: ' \t\n',
wordSeparators: _index.C.charIn(' \n:-,;'),
letter: _index.C.letter,
moreSeparators: null
};
Object.assign(this.options, this._handleOptions(options));
this.last = _last;
this.first = _first;
}
_createClass(ExtractorBundle, [{
key: '_handleOptions',
value: function _handleOptions(options) {
if (options && (typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {
if (options.moreSeparators) {
if (options.wordSeparators) {
console.warn('Parsec WARNING: You cannot set both options ' + 'wordSeparators & options.moreSeparator ; moreSeparator is ignored');
delete options.moreSeparator;
} else {
options.wordSeparators = _index.C.charIn(' \n:-,;' + options.moreSeparators);
}
}
return options;
} else {
return {};
}
}
}, {
key: 'spaces',
value: function spaces() {
return _index.C.charIn(this.options.spacesCharacters).rep().map(function (spaces) {
return spaces.join('');
});
}
// returns a types number
}, {
key: 'number',
value: function number() {
return _index.N.digit.rep().map(function (v) {
return parseInt(v.join(''));
});
}
// returns a string representing numbers
}, {
key: 'digits',
value: function digits() {
return _index.N.digit.rep().map(function (v) {
return v.join('');
});
}
}, {
key: 'word',
value: function word() {
return this.options.letter.rep().map(function (v) {
return v.join('');
});
}
}, {
key: '_wordSeparators',
value: function _wordSeparators() {
//TODO : replace second element by moreSeparators
return this.spaces().or(this.options.wordSeparators);
}
}, {
key: 'words',
value: function words() {
var keepSpaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
if (keepSpaces) {
return _index.F.try(this.word().or(this._wordSeparators())).rep().map(function (item) {
return item.array();
});
} else {
var parser = _index.F.try(this._wordSeparators().optrep().thenRight(this.word()));
return parser.rep().thenLeft(this._wordSeparators().optrep()).map(function (item) {
return item.array();
});
}
}
}, {
key: 'wordsIn',
value: function wordsIn(array) {
var keepSpaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (keepSpaces) {
return _index.F.try(this.stringIn(array).or(this._wordSeparators())).rep().map(function (item) {
return item.array();
});
} else {
var parser = _index.F.try(this._wordSeparators().optrep().thenRight(this.stringIn(array)));
return parser.rep().thenLeft(this._wordSeparators().optrep()).map(function (item) {
return item.array();
});
}
}
}, {
key: 'stringIn',
value: function stringIn(array) {
var tryString = function tryString(s) {
return _index.F.try(_index.C.string(s));
};
if (array.length === 0) {
return tryString('').thenReturns(undefined);
}
if (array.length === 1) {
// TODO : use tryString
return _index.F.try(_index.C.string(array[0]));
}
// TODO: Comment reduce use
var initial = tryString(array[0]);
var workArray = array.slice(1);
return workArray.reduce(function (accu, next) {
return accu.or(tryString(next));
}, initial);
}
}, {
key: '_wordSequence',
value: function _wordSequence(stop) {
return _index.F.not(stop);
}
}, {
key: 'wordsUntil',
value: function wordsUntil(stop) {
if (typeof stop === 'string') {
return satisfyStringFast(stop);
}
if (Array.isArray(stop)) {
return satisfyArrayStringFast(stop);
}
return _index.F.try(this._wordSequence(stop).rep().then(_index.F.eos).thenReturns(undefined)).or(this._wordSequence(stop).rep().map(function (chars) {
return chars.join('');
})).filter(function (v) {
return v !== undefined;
});
}
}]);
return ExtractorBundle;
}();
exports.default = ExtractorBundle;
function _last(values) {
return values[values.length - 1];
}
function _first(values) {
return values[0];
}
/**
* Will work only if input.source is a String
* @param string
* @returns {Parser}
*/
function satisfyStringFast(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.location(index), false);
}
});
}
/**
* Will work only if input.source is a String
* Needs to be tested with ReactJS
* @param string
* @returns {Parser}
*/
function satisfyArrayStringFast(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.location(index), false);
}
});
}
//# sourceMappingURL=extractor-bundle.js.map