fruitsconfits
Version:
FruitsConfits - A well typed and sugared parser combinator framework for TypeScript/JavaScript.
183 lines • 7.17 kB
JavaScript
;
// Copyright (c) 2019 Shellyl_N and Authors
// license: ISC
// https://github.com/shellyln
Object.defineProperty(exports, "__esModule", { value: true });
exports.getObjectParsers = exports.objClassByNeedleFn = exports.objClassNot = exports.objClass = exports.objSequence = void 0;
const parser_1 = require("./parser");
function objSequence(helper, comparator) {
return (needle => {
return (input => {
const len = Math.max(0, input.end - input.start);
let matched = true;
if (len >= needle.length) {
for (let i = 0; i < needle.length; i++) {
if (!comparator(input.src[input.start + i], needle[i])) {
matched = false;
break;
}
}
}
else {
matched = false;
}
return (matched ? {
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,
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
message: `operator "objSequence(${needle})"`,
});
});
});
}
exports.objSequence = objSequence;
function objClass(helper, comparator) {
// NOTE: <T> version `needles` type is `T`.
return ((...needles) => {
return (input => {
const len = Math.max(0, input.end - input.start);
let index = -1;
const succeeded = len > 0 ? needles.some((needle, idx) => {
if (comparator(input.src[input.start], needle)) {
index = idx;
return true;
}
}) : false;
return (succeeded ? {
succeeded: true,
next: {
src: input.src,
start: input.start + 1,
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 "objClass(${needles.join(',')})"`,
});
});
});
}
exports.objClass = objClass;
function objClassNot(helper, comparator) {
// NOTE: <T> version `needles` type is `T`.
return ((...needles) => {
return (input => {
const len = Math.max(0, input.end - input.start);
if (len > 0) {
for (const needle of needles) {
let matched = true;
if (!comparator(input.src[input.start], needle)) {
matched = false;
break;
}
if (matched) {
return ({
succeeded: false,
error: false,
src: input.src,
pos: input.start,
message: `operator "objClassNot(${needles.join(',')})"`,
});
}
}
}
return ({
succeeded: true,
next: {
src: input.src,
start: input.start + 1,
end: input.end,
context: input.context,
templateArgs: input.templateArgs,
templateArgsPos: input.templateArgsPos,
},
tokens: [helper(input.src[input.start])],
});
});
});
}
exports.objClassNot = objClassNot;
function objClassByNeedleFn(helper, comparator) {
// NOTE: needles[i] should be one character. surrogate pair and/or ligature are accepted.
// NOTE: <T> version `needles` type is `T`.
return (needle => {
return (input => {
const len = Math.max(0, input.end - input.start);
const matched = len > 0 ? needle(input.src[input.start]) : false;
return (matched ? {
succeeded: true,
next: {
src: input.src,
start: input.start + 1,
end: input.end,
context: input.context,
templateArgs: input.templateArgs,
templateArgsPos: input.templateArgsPos,
},
tokens: [helper(input.src[input.start])],
} : {
succeeded: false,
error: false,
src: input.src,
pos: input.start,
message: `operator "objClassByNeedleFn"`,
});
});
});
}
exports.objClassByNeedleFn = objClassByNeedleFn;
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function getObjectParsers(params) {
const clsFn = objClassByNeedleFn(params.rawToToken, params.comparator);
const isAny = clsFn(src => true);
// TODO: reduce unneccessary call for adding types.
return ({
seq: objSequence(params.rawToToken, params.comparator),
cls: objClass(params.rawToToken, params.comparator),
notCls: objClassNot(params.rawToToken, params.comparator),
clsFn,
classes: {
any: isAny,
},
cat: parser_1.transform(params.concatTokens),
once: parser_1.quantify(1, 1),
repeat: parser_1.quantify(),
qty: (min, max) => parser_1.quantify(min, max),
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: parser_1.transform(),
erase: parser_1.transform(tokens => []),
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.getObjectParsers = getObjectParsers;
//# sourceMappingURL=object-parser.js.map