UNPKG

fruitsconfits

Version:

FruitsConfits - A well typed and sugared parser combinator framework for TypeScript/JavaScript.

385 lines 15.1 kB
"use strict"; // Copyright (c) 2019 Shellyl_N and Authors // license: ISC // https://github.com/shellyln Object.defineProperty(exports, "__esModule", { value: true }); exports.getStringParsers = exports.templateStringsParam = exports.charClassByNeedleFn = exports.charClassNot = exports.charClass = exports.charSequence = void 0; const parser_1 = require("./parser"); function charSequence(helper) { return (needle => { return (input => { const src = input.src.slice(input.start, input.end); return (src.startsWith(needle) ? { succeeded: true, next: { src: input.src, start: input.start + needle.length, end: input.end, context: input.context, templateArgs: input.templateArgs, templateArgsPos: input.templateArgsPos, }, tokens: [helper(needle)], } : { succeeded: false, error: false, src: input.src, pos: input.start, message: `operator "charSequence(${needle})"`, }); }); }); } exports.charSequence = charSequence; function charClass(helper) { // NOTE: needles[i] should be one character. surrogate pair and/or ligature are accepted. return ((...needles) => { return (input => { const src = input.src.slice(input.start, input.end); let index = -1; const succeeded = needles.some((needle, idx) => { const matched = src.startsWith(needle); if (matched) { index = idx; return true; } }); return (succeeded ? { succeeded: true, next: { src: input.src, start: input.start + needles[index].length, end: input.end, context: input.context, templateArgs: input.templateArgs, templateArgsPos: input.templateArgsPos, }, tokens: [helper(needles[index])], } : { succeeded: false, error: false, src: input.src, pos: input.start, message: `operator "charClass(${needles.join(',')})"`, }); }); }); } exports.charClass = charClass; function charClassNot(helper) { // NOTE: needles[i] should be one character. surrogate pair and/or ligature are accepted. return ((...needles) => { return (input => { const src = input.src.slice(input.start, input.end); for (const needle of needles) { const matched = src.startsWith(needle); if (matched) { return ({ succeeded: false, error: false, src: input.src, pos: input.start, message: `operator "charClassNot(${needles.join(',')})"`, }); } } const p = input.src.codePointAt(input.start); if (p === void 0) { return ({ succeeded: false, error: false, src: input.src, pos: input.start, message: `operator "charClassNot(${needles.join(',')})"`, }); } const c = String.fromCodePoint(p); return ({ succeeded: true, next: { src: input.src, start: input.start + c.length, end: input.end, context: input.context, templateArgs: input.templateArgs, templateArgsPos: input.templateArgsPos, }, tokens: [helper(c)], }); }); }); } exports.charClassNot = charClassNot; function charClassByNeedleFn(helper) { // NOTE: needles[i] should be one character. surrogate pair and/or ligature are accepted. return (needle => { return (input => { const src = input.src.slice(input.start, input.end); const len = needle(src); return (len >= 0 ? { succeeded: true, next: { src: input.src, start: input.start + len, end: input.end, context: input.context, templateArgs: input.templateArgs, templateArgsPos: input.templateArgsPos, }, tokens: [helper(src.substring(0, len))], } : { succeeded: false, error: false, src: input.src, pos: input.start, message: `operator "charClassByNeedleFn"`, }); }); }); } exports.charClassByNeedleFn = charClassByNeedleFn; function templateStringsParam(criteria, conv) { return (input => { const src = input.src.slice(input.start, input.start + 1); if (src === '\x00') { if (input.templateArgsPos) { let argIdx = -1; const strIdx = input.templateArgsPos.findIndex((v, i) => { argIdx = i; return v === input.start; }); if (0 <= strIdx) { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-non-null-assertion const o = input.templateArgs[argIdx]; if (criteria(o)) { return ({ succeeded: true, next: { src: input.src, start: input.start + 1, end: input.end, context: input.context, templateArgs: input.templateArgs, templateArgsPos: input.templateArgsPos, }, // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment tokens: [(conv ? conv(o) : o)], }); } } } } return ({ succeeded: false, error: false, src: input.src, pos: input.start, message: `operator "stringTemplatesParam()"`, }); }); } exports.templateStringsParam = templateStringsParam; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types function getStringParsers(params) { const seq = charSequence(params.rawToToken); const cls = charClass(params.rawToToken); const notCls = charClassNot(params.rawToToken); const clsFn = charClassByNeedleFn(params.rawToToken); const cat = parser_1.transform(params.concatTokens); const once = parser_1.quantify(1, 1); const repeat = parser_1.quantify(); // TODO: reduce unneccessary call for adding types. const qty = (min, max) => parser_1.quantify(min, max); const combine = parser_1.transform(); const erase = parser_1.transform(tokens => []); const isAlpha = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return ((('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) ? c.length : -1); }); const isUpper = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return (('A' <= c && c <= 'Z') ? c.length : -1); }); const isLower = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return (('a' <= c && c <= 'z') ? c.length : -1); }); const isNumber = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return (('0' <= c && c <= '9') ? c.length : -1); }); const isNonZeroNumber = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return (('1' <= c && c <= '9') ? c.length : -1); }); const isBinNum = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return (('0' <= c && c <= '1') ? c.length : -1); }); const isOctNum = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return (('0' <= c && c <= '7') ? c.length : -1); }); const isHexNum = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return ((('A' <= c && c <= 'F') || ('a' <= c && c <= 'f') || ('0' <= c && c <= '9')) ? c.length : -1); }); const isAlNum = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return ((('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) ? c.length : -1); }); const isSpace = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return ((' \f\n\r\t\v​\u00a0\u1680​\u180e' + '\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a' + '​\u2028\u2029\u202f\u205f​\u3000\ufeff').includes(c) ? c.length : -1); }); const isSpaceWithinSingleLine = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return ((' \f\t\v​\u00a0\u1680​\u180e' + '\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a' + '​\u2028\u2029\u202f\u205f​\u3000\ufeff').includes(c) ? c.length : -1); }); const isControl = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return (((0x0000 <= p && p <= 0x001f) || (0x007f <= p && p <= 0x009f)) ? c.length : -1); }); const isWord = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return (((' \f\n\r\t\v​\u00a0\u1680​\u180e' + '\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a' + '​\u2028\u2029\u202f\u205f​\u3000\ufeff').includes(c)) || ((0x0000 <= p && p <= 0x001f) || (0x007f <= p && p <= 0x009f)) ? -1 : c.length); }); const isNewline = cls('\r\n', '\n', '\r'); const isAny = clsFn(src => { const p = src.codePointAt(0); if (p === void 0) { return -1; } const c = String.fromCodePoint(p); return c.length; }); const binSep = parser_1.first(isBinNum, cls('_')); const octSep = parser_1.first(isOctNum, cls('_')); const hexSep = parser_1.first(isHexNum, cls('_')); const binaryIntegerNumber = (...prefixes) => combine(erase(parser_1.first(...prefixes)), cat(once(isBinNum), repeat(binSep))); const octalIntegerNumber = (...prefixes) => combine(erase(parser_1.first(...prefixes)), cat(once(isOctNum), repeat(octSep))); const hexIntegerValue = (...prefixes) => combine(erase(parser_1.first(...prefixes)), cat(once(isHexNum), repeat(hexSep))); const decimalIntegerNumber = combine(cat(qty(0, 1)(cls('+', '-')), parser_1.first(combine(once(isNonZeroNumber), repeat(parser_1.first(isNumber, cls('_')))), seq('0')))); const bigDecimalIntegerNumber = combine(cat(decimalIntegerNumber, erase(seq('n')))); const floatingPointNumber = combine(cat(qty(0, 1)(cls('+', '-')), parser_1.first(combine(once(isNonZeroNumber), repeat(parser_1.first(isNumber, cls('_')))), seq('0')), qty(0, 1)(combine(seq('.'), qty(1)(parser_1.first(isNumber, cls('_'))))), qty(0, 1)(combine(cls('E', 'e'), qty(0, 1)(cls('+', '-')), parser_1.first(combine(once(isNonZeroNumber), repeat(isNumber)), seq('0')))))); // TODO: reduce unneccessary call for adding types. return ({ seq, cls, notCls, clsFn, classes: { alpha: isAlpha, upper: isUpper, lower: isLower, num: isNumber, nonzero: isNonZeroNumber, bin: isBinNum, oct: isOctNum, hex: isHexNum, alnum: isAlNum, space: isSpace, spaceWithinSingleLine: isSpaceWithinSingleLine, ctrl: isControl, newline: isNewline, word: isWord, any: isAny, }, numbers: { bin: binaryIntegerNumber, oct: octalIntegerNumber, hex: hexIntegerValue, int: decimalIntegerNumber, bigint: bigDecimalIntegerNumber, float: floatingPointNumber, }, isParam: templateStringsParam, cat, once, repeat, qty, zeroWidth: (helper) => parser_1.zeroWidth(helper), err: (message) => parser_1.zeroWidthError(message), beginning: (helper) => parser_1.beginning(helper), end: (helper) => parser_1.end(helper), first: (...parsers) => parser_1.first(...parsers), or: (...parsers) => parser_1.or(...parsers), combine, erase, trans: (fn) => parser_1.transform(fn), ahead: (...parsers) => parser_1.lookAhead(...parsers), behind: (n, helper) => parser_1.lookBehind(n, helper), rules: (args) => parser_1.applyProductionRules(args), makeProgram: // TODO: parser_1.makeProgram, }); } exports.getStringParsers = getStringParsers; //# sourceMappingURL=string-parser.js.map