parser-combinators 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/LICENSE +12 -0
  2. package/README.md +49 -4
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.js +19 -0
  5. package/{parser.d.ts → dist/parser.d.ts} +9 -16
  6. package/{parser.js → dist/parser.js} +21 -34
  7. package/{parsers → dist/parsers}/any.d.ts +16 -15
  8. package/dist/parsers/any.js +47 -0
  9. package/dist/parsers/anyString.d.ts +15 -0
  10. package/dist/parsers/anyString.js +85 -0
  11. package/{parsers → dist/parsers}/between.d.ts +5 -5
  12. package/{parsers → dist/parsers}/between.js +20 -21
  13. package/{parsers → dist/parsers}/exhaust.d.ts +5 -5
  14. package/{parsers → dist/parsers}/exhaust.js +25 -27
  15. package/{parsers → dist/parsers}/index.d.ts +12 -11
  16. package/{parsers → dist/parsers}/index.js +31 -23
  17. package/{parsers → dist/parsers}/many.d.ts +17 -17
  18. package/{parsers → dist/parsers}/many.js +61 -61
  19. package/{parsers → dist/parsers}/map.d.ts +5 -5
  20. package/{parsers → dist/parsers}/map.js +21 -22
  21. package/{parsers → dist/parsers}/opt.d.ts +5 -5
  22. package/{parsers → dist/parsers}/opt.js +16 -17
  23. package/dist/parsers/recovery.d.ts +14 -0
  24. package/dist/parsers/recovery.js +53 -0
  25. package/{parsers → dist/parsers}/regex.d.ts +5 -5
  26. package/{parsers → dist/parsers}/regex.js +20 -21
  27. package/{parsers → dist/parsers}/seq.d.ts +16 -15
  28. package/{parsers → dist/parsers}/seq.js +17 -18
  29. package/dist/parsers/str.d.ts +17 -0
  30. package/dist/parsers/str.js +36 -0
  31. package/dist/parsers/utilities.d.ts +33 -0
  32. package/dist/parsers/utilities.js +96 -0
  33. package/{parsers → dist/parsers}/values.d.ts +31 -28
  34. package/{parsers → dist/parsers}/values.js +48 -36
  35. package/{types.d.ts → dist/types.d.ts} +40 -33
  36. package/{types.js → dist/types.js} +47 -47
  37. package/package.json +22 -24
  38. package/parsers/any.js +0 -20
  39. package/parsers/str.d.ts +0 -5
  40. package/parsers/str.js +0 -18
  41. package/parsers/utilities.d.ts +0 -9
  42. package/parsers/utilities.js +0 -30
@@ -1,61 +1,61 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.oneOrManyRed = exports.oneOrMany = exports.zeroOrMany = exports.many = void 0;
4
- const types_1 = require("../types");
5
- const map_1 = require("./map");
6
- const opt_1 = require("./opt");
7
- const seq_1 = require("./seq");
8
- /** Parses zero or more occurences of the given parser.
9
- * @returns A parser returning an array of many parses.
10
- */
11
- function many(parser) {
12
- return (ctx) => {
13
- const results = [];
14
- // eslint-disable-next-line no-constant-condition
15
- while (true) {
16
- const res = parser(ctx);
17
- if ((0, types_1.isFailure)(res)) {
18
- return (0, types_1.success)(ctx, results);
19
- }
20
- ctx = res.ctx;
21
- results.push(res.value);
22
- }
23
- };
24
- }
25
- exports.many = many;
26
- /** Parses zero or more occurences of the given parser, separated with the separator parser.
27
- * @returns A parser returning an array of many parses, omitting the separator.
28
- */
29
- function zeroOrMany(item, separator) {
30
- return (0, map_1.map)((0, opt_1.opt)(oneOrMany(item, separator)), t => t !== null && t !== void 0 ? t : []);
31
- }
32
- exports.zeroOrMany = zeroOrMany;
33
- /** Parses one or more occurences of the given parser, separated with the separator parser.
34
- * @returns A parser returning an array of many parses, omitting the separator.
35
- */
36
- function oneOrMany(item, separator) {
37
- const sequencer = (0, map_1.map)((0, seq_1.seq)(item, many((0, map_1.map)((0, seq_1.seq)(separator, item), ([, t]) => t))), ([t, ts]) => ([t, ...ts]));
38
- return (ctx) => {
39
- const res = sequencer(ctx);
40
- if ((0, types_1.isFailure)(res)) {
41
- const newHistory = [...res.history];
42
- newHistory.splice(0, 2);
43
- return (0, types_1.failure)(res.ctx, res.expected, ['oneOrMany', ...newHistory]);
44
- }
45
- return res;
46
- };
47
- }
48
- exports.oneOrMany = oneOrMany;
49
- /** Parses one or more occurences of the given parser, separated with the separator parser.
50
- * @returns A parser returning the result of many parses, reduced using the `reducer` function passed in.
51
- */
52
- function oneOrManyRed(item, separator, reducer) {
53
- return (0, map_1.map)((0, map_1.map)((0, seq_1.seq)((0, map_1.map)(item, (x) => [null, x]), many((0, seq_1.seq)(separator, item))), ([t, ts]) => ([t, ...ts])), ts => {
54
- let result = ts[0][1];
55
- for (let i = 1; i < ts.length; i++) {
56
- result = reducer(result, ts[i][1], ts[i][0]);
57
- }
58
- return result;
59
- });
60
- }
61
- exports.oneOrManyRed = oneOrManyRed;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.many = many;
4
+ exports.zeroOrMany = zeroOrMany;
5
+ exports.oneOrMany = oneOrMany;
6
+ exports.oneOrManyRed = oneOrManyRed;
7
+ const types_1 = require("../types");
8
+ const map_1 = require("./map");
9
+ const opt_1 = require("./opt");
10
+ const seq_1 = require("./seq");
11
+ /** Parses zero or more occurences of the given parser.
12
+ * @returns A parser returning an array of many parses.
13
+ */
14
+ function many(parser) {
15
+ return (ctx) => {
16
+ const results = [];
17
+ while (true) {
18
+ const res = parser(ctx);
19
+ if ((0, types_1.isFailure)(res)) {
20
+ return (0, types_1.success)(ctx, results);
21
+ }
22
+ ctx = res.ctx;
23
+ results.push(res.value);
24
+ }
25
+ };
26
+ }
27
+ /** Parses zero or more occurences of the given parser, separated with the separator parser.
28
+ * @returns A parser returning an array of many parses, omitting the separator.
29
+ */
30
+ function zeroOrMany(item, separator) {
31
+ return (0, map_1.map)((0, opt_1.opt)(oneOrMany(item, separator)), t => t ?? []);
32
+ }
33
+ /** Parses one or more occurences of the given parser, separated with the separator parser.
34
+ * @returns A parser returning an array of many parses, omitting the separator.
35
+ */
36
+ function oneOrMany(item, separator = undefined) {
37
+ const sequencer = (0, map_1.map)((0, seq_1.seq)(item, many(separator
38
+ ? (0, map_1.map)((0, seq_1.seq)(separator, item), ([, t]) => t)
39
+ : item)), ([t, ts]) => ([t, ...ts]));
40
+ return (ctx) => {
41
+ const res = sequencer(ctx);
42
+ if ((0, types_1.isFailure)(res)) {
43
+ const newHistory = [...res.history];
44
+ newHistory.splice(0, 2);
45
+ return (0, types_1.failure)(res.ctx, res.expected, ['oneOrMany', ...newHistory]);
46
+ }
47
+ return res;
48
+ };
49
+ }
50
+ /** Parses one or more occurences of the given parser, separated with the separator parser.
51
+ * @returns A parser returning the result of many parses, reduced using the `reducer` function passed in.
52
+ */
53
+ function oneOrManyRed(item, separator, reducer) {
54
+ return (0, map_1.map)((0, map_1.map)((0, seq_1.seq)((0, map_1.map)(item, (x) => [null, x]), many((0, seq_1.seq)(separator, item))), ([t, ts]) => ([t, ...ts])), ts => {
55
+ let result = ts[0][1];
56
+ for (let i = 1; i < ts.length; i++) {
57
+ result = reducer(result, ts[i][1], ts[i][0]);
58
+ }
59
+ return result;
60
+ });
61
+ }
@@ -1,5 +1,5 @@
1
- import { Parser } from '../types';
2
- /** Parses the input using the given parser, then maps the output.
3
- * @returns A parser that parses the same input, but has output mapped using the mapping function.
4
- */
5
- export declare function map<A, B>(parser: Parser<A>, mapper: (val: A) => B): Parser<B>;
1
+ import { Parser } from '../types';
2
+ /** Parses the input using the given parser, then maps the output.
3
+ * @returns A parser that parses the same input, but has output mapped using the mapping function.
4
+ */
5
+ export declare function map<A, B>(parser: Parser<A>, mapper: (val: A) => B): Parser<B>;
@@ -1,22 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.map = void 0;
4
- const types_1 = require("../types");
5
- /** Parses the input using the given parser, then maps the output.
6
- * @returns A parser that parses the same input, but has output mapped using the mapping function.
7
- */
8
- function map(parser, mapper) {
9
- return (ctx) => {
10
- const res = parser(ctx);
11
- if ((0, types_1.isFailure)(res))
12
- return (0, types_1.failure)(res.ctx, res.expected, ['map', ...res.history]);
13
- try {
14
- const newValue = mapper(res.value);
15
- return (0, types_1.success)(res.ctx, newValue);
16
- }
17
- catch (e) {
18
- return (0, types_1.failure)(res.ctx, 'Error while mapping', ['map']);
19
- }
20
- };
21
- }
22
- exports.map = map;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.map = map;
4
+ const types_1 = require("../types");
5
+ /** Parses the input using the given parser, then maps the output.
6
+ * @returns A parser that parses the same input, but has output mapped using the mapping function.
7
+ */
8
+ function map(parser, mapper) {
9
+ return (ctx) => {
10
+ const res = parser(ctx);
11
+ if ((0, types_1.isFailure)(res))
12
+ return (0, types_1.failure)(res.ctx, res.expected, ['map', ...res.history]);
13
+ try {
14
+ const newValue = mapper(res.value);
15
+ return (0, types_1.success)(res.ctx, newValue);
16
+ }
17
+ catch {
18
+ return (0, types_1.failure)(res.ctx, 'Error while mapping', ['map']);
19
+ }
20
+ };
21
+ }
@@ -1,5 +1,5 @@
1
- import { Parser } from '../types';
2
- /** Makes the parser optional.
3
- * @returns A parser that succeeds with `null` result if the parsing didn't succeed.
4
- */
5
- export declare function opt<T>(parser: Parser<T>): Parser<T | null>;
1
+ import { Parser } from '../types';
2
+ /** Makes the parser optional.
3
+ * @returns A parser that succeeds with `null` result if the parsing didn't succeed.
4
+ */
5
+ export declare function opt<T>(parser: Parser<T>): Parser<T | null>;
@@ -1,17 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.opt = void 0;
4
- const types_1 = require("../types");
5
- /** Makes the parser optional.
6
- * @returns A parser that succeeds with `null` result if the parsing didn't succeed.
7
- */
8
- function opt(parser) {
9
- return (ctx) => {
10
- const parseResult = parser(ctx);
11
- if ((0, types_1.isFailure)(parseResult)) {
12
- return (0, types_1.success)(ctx, null);
13
- }
14
- return parseResult;
15
- };
16
- }
17
- exports.opt = opt;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.opt = opt;
4
+ const types_1 = require("../types");
5
+ /** Makes the parser optional.
6
+ * @returns A parser that succeeds with `null` result if the parsing didn't succeed.
7
+ */
8
+ function opt(parser) {
9
+ return (ctx) => {
10
+ const parseResult = parser(ctx);
11
+ if ((0, types_1.isFailure)(parseResult)) {
12
+ return (0, types_1.success)(ctx, null);
13
+ }
14
+ return parseResult;
15
+ };
16
+ }
@@ -0,0 +1,14 @@
1
+ import { Parser } from "../types";
2
+ /**
3
+ * Tries to automatically recover a parsing failure by removing characters from the front.
4
+ *
5
+ * If the inner parser fails, the recovery parser will restart parsing skipping a character, up to {@link chars} skips
6
+ */
7
+ export declare function recoverBySkippingChars<T>(parser: Parser<T>, chars: number): Parser<T>;
8
+ /**
9
+ * Tries to automatically recover a parsing failure by adding characters to the front.
10
+ *
11
+ * If the inner parser fails, the recovery parser will restart parsing adding a character, up to {@link chars}
12
+ * @todo Inserting characters in the middle of a context string is inefficient - maybe there's a better way?
13
+ */
14
+ export declare function recoverByAddingChars<T>(parser: Parser<T>, chars: string): Parser<T>;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.recoverBySkippingChars = recoverBySkippingChars;
4
+ exports.recoverByAddingChars = recoverByAddingChars;
5
+ const types_1 = require("../types");
6
+ /**
7
+ * Tries to automatically recover a parsing failure by removing characters from the front.
8
+ *
9
+ * If the inner parser fails, the recovery parser will restart parsing skipping a character, up to {@link chars} skips
10
+ */
11
+ function recoverBySkippingChars(parser, chars) {
12
+ return (ctx) => {
13
+ let firstFailure = null;
14
+ for (let i = 0; i <= chars; i++) {
15
+ const result = parser({
16
+ index: ctx.index + i,
17
+ path: ctx.path,
18
+ text: ctx.text,
19
+ });
20
+ if ((0, types_1.isFailure)(result)) {
21
+ firstFailure ??= result;
22
+ }
23
+ else
24
+ return result;
25
+ }
26
+ return firstFailure;
27
+ };
28
+ }
29
+ /**
30
+ * Tries to automatically recover a parsing failure by adding characters to the front.
31
+ *
32
+ * If the inner parser fails, the recovery parser will restart parsing adding a character, up to {@link chars}
33
+ * @todo Inserting characters in the middle of a context string is inefficient - maybe there's a better way?
34
+ */
35
+ function recoverByAddingChars(parser, chars) {
36
+ return (ctx) => {
37
+ let firstFailure = null;
38
+ for (let i = 0; i <= chars.length; i++) {
39
+ const addedChars = chars.slice(0, i);
40
+ const result = parser({
41
+ index: ctx.index,
42
+ path: ctx.path,
43
+ text: `${ctx.text.slice(0, ctx.index)}${addedChars}${ctx.text.slice(ctx.index)}`,
44
+ });
45
+ if ((0, types_1.isFailure)(result)) {
46
+ firstFailure ??= result;
47
+ }
48
+ else
49
+ return result;
50
+ }
51
+ return firstFailure;
52
+ };
53
+ }
@@ -1,5 +1,5 @@
1
- import { Parser } from '../types';
2
- /** Parses a regex and returns the matched result of the parse.
3
- * @returns A parser parsing a given regex and returning a match.
4
- */
5
- export declare function regex(match: RegExp | string, expected: string): Parser<string>;
1
+ import { Parser } from '../types';
2
+ /** Parses a regex and returns the matched result of the parse.
3
+ * @returns A parser parsing a given regex and returning a match.
4
+ */
5
+ export declare function regex(match: RegExp | string, expected: string): Parser<string>;
@@ -1,21 +1,20 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.regex = void 0;
4
- const types_1 = require("../types");
5
- /** Parses a regex and returns the matched result of the parse.
6
- * @returns A parser parsing a given regex and returning a match.
7
- */
8
- function regex(match, expected) {
9
- const regexp = new RegExp(match, typeof match === 'string' ? 'y' : match.flags + 'y');
10
- return (ctx) => {
11
- regexp.lastIndex = ctx.index;
12
- const regexMatch = regexp.exec(ctx.text);
13
- if (regexMatch !== null && regexMatch.index === ctx.index) {
14
- return (0, types_1.success)({ ...ctx, index: ctx.index + regexMatch[0].length }, regexMatch[0]);
15
- }
16
- else {
17
- return (0, types_1.failure)(ctx, expected, [expected]);
18
- }
19
- };
20
- }
21
- exports.regex = regex;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.regex = regex;
4
+ const types_1 = require("../types");
5
+ /** Parses a regex and returns the matched result of the parse.
6
+ * @returns A parser parsing a given regex and returning a match.
7
+ */
8
+ function regex(match, expected) {
9
+ const regexp = new RegExp(match, typeof match === 'string' ? 'y' : match.flags + 'y');
10
+ return (ctx) => {
11
+ regexp.lastIndex = ctx.index;
12
+ const regexMatch = regexp.exec(ctx.text);
13
+ if (regexMatch !== null && regexMatch.index === ctx.index) {
14
+ return (0, types_1.success)({ ...ctx, index: ctx.index + regexMatch[0].length }, regexMatch[0]);
15
+ }
16
+ else {
17
+ return (0, types_1.failure)(ctx, expected, [expected]);
18
+ }
19
+ };
20
+ }
@@ -1,15 +1,16 @@
1
- import { Parser } from '../types';
2
- /** Parses a sequence of parsers going from left to right, returning the results of the parsers.
3
- * @returns A parser parsing the sequence of parsers.
4
- */
5
- export declare function seq<T, U, V, W, X, Z, I, J, K, L, M>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>, Parser<J>, Parser<K>, Parser<L>, Parser<M>]): Parser<[T, U, V, W, X, Z, I, J, K, L, M]>;
6
- export declare function seq<T, U, V, W, X, Z, I, J, K, L>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>, Parser<J>, Parser<K>, Parser<L>]): Parser<[T, U, V, W, X, Z, I, J, K, L]>;
7
- export declare function seq<T, U, V, W, X, Z, I, J, K>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>, Parser<J>, Parser<K>]): Parser<[T, U, V, W, X, Z, I, J, K]>;
8
- export declare function seq<T, U, V, W, X, Z, I, J>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>, Parser<J>]): Parser<[T, U, V, W, X, Z, I, J]>;
9
- export declare function seq<T, U, V, W, X, Z, I>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>]): Parser<[T, U, V, W, X, Z, I]>;
10
- export declare function seq<T, U, V, W, X, Z>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>]): Parser<[T, U, V, W, X, Z]>;
11
- export declare function seq<T, U, V, W, X>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>]): Parser<[T, U, V, W, X]>;
12
- export declare function seq<T, U, V, W>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>]): Parser<[T, U, V, W]>;
13
- export declare function seq<T, U, V>(...parsers: [Parser<T>, Parser<U>, Parser<V>]): Parser<[T, U, V]>;
14
- export declare function seq<T, U>(...parsers: [Parser<T>, Parser<U>]): Parser<[T, U]>;
15
- export declare function seq<T>(...parsers: [Parser<T>]): Parser<[T]>;
1
+ import { Parser } from '../types';
2
+ /** Parses a sequence of parsers going from left to right, returning the results of the parsers.
3
+ * @returns A parser parsing the sequence of parsers.
4
+ */
5
+ export declare function seq<T, U, V, W, X, Z, I, J, K, L, M>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>, Parser<J>, Parser<K>, Parser<L>, Parser<M>]): Parser<[T, U, V, W, X, Z, I, J, K, L, M]>;
6
+ export declare function seq<T, U, V, W, X, Z, I, J, K, L>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>, Parser<J>, Parser<K>, Parser<L>]): Parser<[T, U, V, W, X, Z, I, J, K, L]>;
7
+ export declare function seq<T, U, V, W, X, Z, I, J, K>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>, Parser<J>, Parser<K>]): Parser<[T, U, V, W, X, Z, I, J, K]>;
8
+ export declare function seq<T, U, V, W, X, Z, I, J>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>, Parser<J>]): Parser<[T, U, V, W, X, Z, I, J]>;
9
+ export declare function seq<T, U, V, W, X, Z, I>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>, Parser<I>]): Parser<[T, U, V, W, X, Z, I]>;
10
+ export declare function seq<T, U, V, W, X, Z>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>, Parser<Z>]): Parser<[T, U, V, W, X, Z]>;
11
+ export declare function seq<T, U, V, W, X>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>, Parser<X>]): Parser<[T, U, V, W, X]>;
12
+ export declare function seq<T, U, V, W>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>]): Parser<[T, U, V, W]>;
13
+ export declare function seq<T, U, V>(...parsers: [Parser<T>, Parser<U>, Parser<V>]): Parser<[T, U, V]>;
14
+ export declare function seq<T, U>(...parsers: [Parser<T>, Parser<U>]): Parser<[T, U]>;
15
+ export declare function seq<T>(...parsers: [Parser<T>]): Parser<[T]>;
16
+ export declare function seq<T>(...parsers: Parser<T>[]): Parser<T[]>;
@@ -1,18 +1,17 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.seq = void 0;
4
- const types_1 = require("../types");
5
- function seq(...parsers) {
6
- return (ctx) => {
7
- const values = [];
8
- for (const parser of parsers) {
9
- const res = parser(ctx);
10
- ctx = res.ctx;
11
- if ((0, types_1.isFailure)(res))
12
- return (0, types_1.failure)(res.ctx, res.expected, ['seq', ...res.history]);
13
- values.push(res.value);
14
- }
15
- return (0, types_1.success)(ctx, values);
16
- };
17
- }
18
- exports.seq = seq;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.seq = seq;
4
+ const types_1 = require("../types");
5
+ function seq(...parsers) {
6
+ return (ctx) => {
7
+ const values = [];
8
+ for (const parser of parsers) {
9
+ const res = parser(ctx);
10
+ ctx = res.ctx;
11
+ if ((0, types_1.isFailure)(res))
12
+ return (0, types_1.failure)(res.ctx, res.expected, ['seq', ...res.history]);
13
+ values.push(res.value);
14
+ }
15
+ return (0, types_1.success)(ctx, values);
16
+ };
17
+ }
@@ -0,0 +1,17 @@
1
+ import { Parser } from '../types';
2
+ export type StrParser<T> = Parser<T> & {
3
+ parserType: 'str';
4
+ match: T;
5
+ };
6
+ /** Parses a string and returns it as a result of the parse.
7
+ * @returns A parser parsing a given string, case-sensitive.
8
+ */
9
+ export declare function str<T extends string>(match: T): StrParser<T>;
10
+ export type StrIParser<T> = Parser<T> & {
11
+ parserType: 'stri';
12
+ match: T;
13
+ };
14
+ /** Parses a string case-insensitively and returns it as a result of the parse.
15
+ * @returns A parser parsing a given string, case-insensitive.
16
+ */
17
+ export declare function stri<T extends string>(match: T): StrIParser<Lowercase<T>>;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.str = str;
4
+ exports.stri = stri;
5
+ const types_1 = require("../types");
6
+ /** Parses a string and returns it as a result of the parse.
7
+ * @returns A parser parsing a given string, case-sensitive.
8
+ */
9
+ function str(match) {
10
+ const inQuotes = `'${match}'`;
11
+ return Object.assign((ctx) => {
12
+ if (ctx.text.startsWith(match, ctx.index)) {
13
+ return (0, types_1.success)({ ...ctx, index: ctx.index + match.length }, match);
14
+ }
15
+ else {
16
+ return (0, types_1.failure)(ctx, inQuotes, [inQuotes]);
17
+ }
18
+ }, { parserType: 'str', match });
19
+ }
20
+ const collator = new Intl.Collator('en', { sensitivity: 'accent' });
21
+ /** Parses a string case-insensitively and returns it as a result of the parse.
22
+ * @returns A parser parsing a given string, case-insensitive.
23
+ */
24
+ function stri(match) {
25
+ const lowercase = match.toLowerCase();
26
+ const inQuotes = `'${lowercase}'`;
27
+ return Object.assign((ctx) => {
28
+ const textSlice = ctx.text.slice(ctx.index, ctx.index + match.length);
29
+ if (collator.compare(match, textSlice) == 0) {
30
+ return (0, types_1.success)({ ...ctx, index: ctx.index + match.length }, lowercase);
31
+ }
32
+ else {
33
+ return (0, types_1.failure)(ctx, inQuotes, [inQuotes]);
34
+ }
35
+ }, { parserType: 'stri', match: lowercase });
36
+ }
@@ -0,0 +1,33 @@
1
+ import { Parser, Token } from '../types';
2
+ export declare const shouldPerformFusions: () => boolean;
3
+ /**
4
+ * Disables all parser combinator fusions.
5
+ *
6
+ * Should probably be used only for testing performance.
7
+ */
8
+ export declare const toggleFusions: (value: boolean) => void;
9
+ /** Allows to make a condition on the result of the parsing function.
10
+ * @returns A parser returning the same but also performing a given check on the result.
11
+ */
12
+ export declare function ref<T>(parser: Parser<T>, check: ((p: T) => boolean), expected?: string): Parser<T>;
13
+ /** Changes the expected value for when the parser fails.
14
+ * @returns A parser returning the same but with a different expected value.
15
+ */
16
+ export declare function expect<T>(parser: Parser<T>, expected: string): Parser<T>;
17
+ /** Changes the expected value for when the parser fails. Erases the previous history.
18
+ * @returns A parser returning the same but with a different expected value.
19
+ */
20
+ export declare function expectErase<T>(parser: Parser<T>, expected: string): Parser<T>;
21
+ /**
22
+ * Marks a parser as a branch that has to be executed to the end by the {@link any} parser
23
+ */
24
+ export declare function surely<T>(parser: Parser<T>): Parser<T>;
25
+ /**
26
+ * Wraps the value returned by the parser with the token information (the start and end index in the text)
27
+ * @returns A parser returning the value wrapped in token information.
28
+ */
29
+ export declare function token<T>(parser: Parser<T>): Parser<Token<T>>;
30
+ /**
31
+ * Checks whether the parser parses successfully, but doesn't move the cursor forward
32
+ */
33
+ export declare function lookaround<T>(parser: Parser<T>): Parser<void>;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toggleFusions = exports.shouldPerformFusions = void 0;
4
+ exports.ref = ref;
5
+ exports.expect = expect;
6
+ exports.expectErase = expectErase;
7
+ exports.surely = surely;
8
+ exports.token = token;
9
+ exports.lookaround = lookaround;
10
+ const types_1 = require("../types");
11
+ const shouldPerformFusions = () => performFusions;
12
+ exports.shouldPerformFusions = shouldPerformFusions;
13
+ let performFusions = true;
14
+ /**
15
+ * Disables all parser combinator fusions.
16
+ *
17
+ * Should probably be used only for testing performance.
18
+ */
19
+ const toggleFusions = (value) => {
20
+ performFusions = value;
21
+ };
22
+ exports.toggleFusions = toggleFusions;
23
+ /** Allows to make a condition on the result of the parsing function.
24
+ * @returns A parser returning the same but also performing a given check on the result.
25
+ */
26
+ function ref(parser, check, expected) {
27
+ return (ctx) => {
28
+ const res = parser(ctx);
29
+ if (!(0, types_1.isFailure)(res) && !check(res.value)) {
30
+ return (0, types_1.failure)(res.ctx, expected ?? 'check', [`ref: ${expected ?? 'check'}`]);
31
+ }
32
+ return res;
33
+ };
34
+ }
35
+ /** Changes the expected value for when the parser fails.
36
+ * @returns A parser returning the same but with a different expected value.
37
+ */
38
+ function expect(parser, expected) {
39
+ return (ctx) => {
40
+ const res = parser(ctx);
41
+ if ((0, types_1.isFailure)(res)) {
42
+ return (0, types_1.failure)(res.ctx, expected, [expected, ...res.history]);
43
+ }
44
+ return res;
45
+ };
46
+ }
47
+ /** Changes the expected value for when the parser fails. Erases the previous history.
48
+ * @returns A parser returning the same but with a different expected value.
49
+ */
50
+ function expectErase(parser, expected) {
51
+ return (ctx) => {
52
+ const res = parser(ctx);
53
+ if ((0, types_1.isFailure)(res)) {
54
+ return (0, types_1.failure)(res.ctx, expected, [expected]);
55
+ }
56
+ return res;
57
+ };
58
+ }
59
+ /**
60
+ * Marks a parser as a branch that has to be executed to the end by the {@link any} parser
61
+ */
62
+ function surely(parser) {
63
+ return expect(parser, 'surely');
64
+ }
65
+ /**
66
+ * Wraps the value returned by the parser with the token information (the start and end index in the text)
67
+ * @returns A parser returning the value wrapped in token information.
68
+ */
69
+ function token(parser) {
70
+ return (ctx) => {
71
+ const result = parser(ctx);
72
+ if (result.success) {
73
+ return {
74
+ ...result,
75
+ value: {
76
+ value: result.value,
77
+ start: ctx.index,
78
+ end: result.ctx.index
79
+ }
80
+ };
81
+ }
82
+ return result;
83
+ };
84
+ }
85
+ /**
86
+ * Checks whether the parser parses successfully, but doesn't move the cursor forward
87
+ */
88
+ function lookaround(parser) {
89
+ return (ctx) => {
90
+ const result = parser(ctx);
91
+ if (result.success) {
92
+ return (0, types_1.success)(ctx, void 0);
93
+ }
94
+ return (0, types_1.failure)(ctx, result.expected, ['lookaround', ...result.history]);
95
+ };
96
+ }