parser-combinators 1.0.7 → 1.1.3
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.
- package/LICENSE +12 -0
- package/README.md +5 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +19 -0
- package/{parser.d.ts → dist/parser.d.ts} +0 -0
- package/{parser.js → dist/parser.js} +1 -1
- package/{parsers → dist/parsers}/any.d.ts +2 -0
- package/dist/parsers/any.js +29 -0
- package/{parsers → dist/parsers}/between.d.ts +0 -0
- package/{parsers → dist/parsers}/between.js +6 -6
- package/{parsers → dist/parsers}/exhaust.d.ts +0 -0
- package/{parsers → dist/parsers}/exhaust.js +5 -5
- package/{parsers → dist/parsers}/index.d.ts +0 -0
- package/{parsers → dist/parsers}/index.js +5 -1
- package/{parsers → dist/parsers}/many.d.ts +1 -1
- package/{parsers → dist/parsers}/many.js +11 -8
- package/{parsers → dist/parsers}/map.d.ts +0 -0
- package/{parsers → dist/parsers}/map.js +4 -5
- package/{parsers → dist/parsers}/opt.d.ts +0 -0
- package/{parsers → dist/parsers}/opt.js +2 -2
- package/{parsers → dist/parsers}/regex.d.ts +0 -0
- package/dist/parsers/regex.js +21 -0
- package/{parsers → dist/parsers}/seq.d.ts +2 -0
- package/{parsers → dist/parsers}/seq.js +3 -3
- package/{parsers → dist/parsers}/str.d.ts +0 -0
- package/{parsers → dist/parsers}/str.js +3 -3
- package/{parsers → dist/parsers}/utilities.d.ts +5 -1
- package/dist/parsers/utilities.js +43 -0
- package/{parsers → dist/parsers}/values.d.ts +0 -0
- package/{parsers → dist/parsers}/values.js +9 -9
- package/{types.d.ts → dist/types.d.ts} +0 -0
- package/{types.js → dist/types.js} +0 -0
- package/package.json +15 -22
- package/parsers/any.js +0 -20
- package/parsers/regex.js +0 -19
- package/parsers/utilities.js +0 -30
package/LICENSE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Copyright 2022 Michał Isalski
|
|
2
|
+
|
|
3
|
+
Permission to use, copy, modify, and/or distribute
|
|
4
|
+
this software for any purpose with or without fee is hereby granted,
|
|
5
|
+
provided that the above copyright notice and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
8
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
|
9
|
+
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
|
10
|
+
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
11
|
+
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
12
|
+
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
[](https://badge.fury.io/js/parser-combinators)
|
|
9
|
-
[](https://status.david-dm.org/)
|
|
10
9
|
|
|
11
10
|
A library of parser combinators, with which you can create your own parsers.
|
|
12
11
|
|
|
@@ -38,6 +37,8 @@ A library of parser combinators, with which you can create your own parsers.
|
|
|
38
37
|
- Utility combinators:
|
|
39
38
|
- `ref`er
|
|
40
39
|
- `expect`
|
|
40
|
+
- `expectErase`
|
|
41
|
+
- `surely`
|
|
41
42
|
- Ready-made value combinators:
|
|
42
43
|
- `spaces`
|
|
43
44
|
- `spacesPlus`
|
|
@@ -45,6 +46,9 @@ A library of parser combinators, with which you can create your own parsers.
|
|
|
45
46
|
- `bool` (and `boolP`)
|
|
46
47
|
- `int` (and `intP`)
|
|
47
48
|
- `real` (and `realP`)
|
|
49
|
+
- Whole parsers:
|
|
50
|
+
- Extended Backus-Naur Form (`EBNF`)
|
|
51
|
+
- JavaScript Object Notation (`JSON`)
|
|
48
52
|
|
|
49
53
|
### Example usage:
|
|
50
54
|
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./parsers"), exports);
|
|
19
|
+
__exportStar(require("./parser"), exports);
|
|
File without changes
|
|
@@ -23,7 +23,7 @@ exports.ParseFile = ParseFile;
|
|
|
23
23
|
*/
|
|
24
24
|
function ParseText(text, parser, path = '') {
|
|
25
25
|
const res = parser({ text, path, index: 0 });
|
|
26
|
-
if (types_1.isFailure(res)) {
|
|
26
|
+
if ((0, types_1.isFailure)(res)) {
|
|
27
27
|
throw new types_1.ParseError(`Parse error, expected ${[...res.history].pop()} at char ${res.ctx.index}`, text, res.ctx.index, res.history);
|
|
28
28
|
}
|
|
29
29
|
if (res.ctx.index !== text.length) {
|
|
@@ -13,3 +13,5 @@ export declare function any<T, U, V, W>(...parsers: [Parser<T>, Parser<U>, Parse
|
|
|
13
13
|
export declare function any<T, U, V>(...parsers: [Parser<T>, Parser<U>, Parser<V>]): Parser<T | U | V>;
|
|
14
14
|
export declare function any<T, U>(...parsers: [Parser<T>, Parser<U>]): Parser<T | U>;
|
|
15
15
|
export declare function any<T>(...parsers: [Parser<T>]): Parser<T>;
|
|
16
|
+
export declare function any<T>(...parsers: Parser<T>[]): Parser<T>;
|
|
17
|
+
export declare function surely<T>(parser: Parser<T>): Parser<T>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.surely = exports.any = void 0;
|
|
4
|
+
const _1 = require(".");
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
function any(...parsers) {
|
|
7
|
+
return (ctx) => {
|
|
8
|
+
const expected = [];
|
|
9
|
+
for (const parser of parsers) {
|
|
10
|
+
const res = parser(ctx);
|
|
11
|
+
if ((0, types_1.isFailure)(res)) {
|
|
12
|
+
if (res.history.includes('surely')) {
|
|
13
|
+
console.log('shot');
|
|
14
|
+
return (0, types_1.failure)(res.ctx, res.expected, res.history.filter(h => h !== 'surely'));
|
|
15
|
+
}
|
|
16
|
+
expected.push(res);
|
|
17
|
+
}
|
|
18
|
+
else
|
|
19
|
+
return res;
|
|
20
|
+
}
|
|
21
|
+
const longest = expected.reduce((a, b) => a.history.length > b.history.length ? a : b);
|
|
22
|
+
return (0, types_1.failure)(longest.ctx, longest.expected, ['any', ...longest.history]);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
exports.any = any;
|
|
26
|
+
function surely(parser) {
|
|
27
|
+
return (0, _1.expect)(parser, 'surely');
|
|
28
|
+
}
|
|
29
|
+
exports.surely = surely;
|
|
File without changes
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.between = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
|
-
const map_1 = require("./map");
|
|
6
5
|
const seq_1 = require("./seq");
|
|
7
6
|
/** Parses a sequence of three parsers.
|
|
8
7
|
* @returns A parser returning only the middle parser's result.
|
|
9
8
|
*/
|
|
10
9
|
function between(left, parser, right) {
|
|
10
|
+
const sequence = (0, seq_1.seq)(left, parser, right);
|
|
11
11
|
return (ctx) => {
|
|
12
|
-
const res =
|
|
13
|
-
if (types_1.isFailure(res)) {
|
|
12
|
+
const res = sequence(ctx);
|
|
13
|
+
if ((0, types_1.isFailure)(res)) {
|
|
14
14
|
const newHistory = [...res.history];
|
|
15
|
-
newHistory.splice(0,
|
|
16
|
-
return types_1.failure(res.ctx, res.expected, ['between', ...newHistory]);
|
|
15
|
+
newHistory.splice(0, 1);
|
|
16
|
+
return (0, types_1.failure)(res.ctx, res.expected, ['between', ...newHistory]);
|
|
17
17
|
}
|
|
18
|
-
return res;
|
|
18
|
+
return { ...res, value: res.value[1] };
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
exports.between = between;
|
|
File without changes
|
|
@@ -11,16 +11,16 @@ function exhaust(parser, until = null) {
|
|
|
11
11
|
// eslint-disable-next-line no-constant-condition
|
|
12
12
|
while (true) {
|
|
13
13
|
const res = parser(ctx);
|
|
14
|
-
if (types_1.isFailure(res)) {
|
|
15
|
-
if (until === null || types_1.isFailure(until(ctx))) {
|
|
16
|
-
return types_1.failure(res.ctx, res.expected, ['exhaust', ...res.history]);
|
|
14
|
+
if ((0, types_1.isFailure)(res)) {
|
|
15
|
+
if (until === null || (0, types_1.isFailure)(until(ctx))) {
|
|
16
|
+
return (0, types_1.failure)(res.ctx, res.expected, ['exhaust', ...res.history]);
|
|
17
17
|
}
|
|
18
|
-
return types_1.success(ctx, results);
|
|
18
|
+
return (0, types_1.success)(ctx, results);
|
|
19
19
|
}
|
|
20
20
|
ctx = res.ctx;
|
|
21
21
|
results.push(res.value);
|
|
22
22
|
if (res.ctx.index === res.ctx.text.length)
|
|
23
|
-
return types_1.success(res.ctx, results);
|
|
23
|
+
return (0, types_1.success)(res.ctx, results);
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
26
|
}
|
|
File without changes
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -10,7 +10,7 @@ export declare function zeroOrMany<T, V>(item: Parser<T>, separator: Parser<V>):
|
|
|
10
10
|
/** Parses one or more occurences of the given parser, separated with the separator parser.
|
|
11
11
|
* @returns A parser returning an array of many parses, omitting the separator.
|
|
12
12
|
*/
|
|
13
|
-
export declare function oneOrMany<T, V>(item: Parser<T>, separator
|
|
13
|
+
export declare function oneOrMany<T, V>(item: Parser<T>, separator?: Parser<V> | undefined): Parser<T[]>;
|
|
14
14
|
/** Parses one or more occurences of the given parser, separated with the separator parser.
|
|
15
15
|
* @returns A parser returning the result of many parses, reduced using the `reducer` function passed in.
|
|
16
16
|
*/
|
|
@@ -14,8 +14,8 @@ function many(parser) {
|
|
|
14
14
|
// eslint-disable-next-line no-constant-condition
|
|
15
15
|
while (true) {
|
|
16
16
|
const res = parser(ctx);
|
|
17
|
-
if (types_1.isFailure(res)) {
|
|
18
|
-
return types_1.success(ctx, results);
|
|
17
|
+
if ((0, types_1.isFailure)(res)) {
|
|
18
|
+
return (0, types_1.success)(ctx, results);
|
|
19
19
|
}
|
|
20
20
|
ctx = res.ctx;
|
|
21
21
|
results.push(res.value);
|
|
@@ -27,19 +27,22 @@ exports.many = many;
|
|
|
27
27
|
* @returns A parser returning an array of many parses, omitting the separator.
|
|
28
28
|
*/
|
|
29
29
|
function zeroOrMany(item, separator) {
|
|
30
|
-
return map_1.map(opt_1.opt(oneOrMany(item, separator)), t => t
|
|
30
|
+
return (0, map_1.map)((0, opt_1.opt)(oneOrMany(item, separator)), t => t !== null && t !== void 0 ? t : []);
|
|
31
31
|
}
|
|
32
32
|
exports.zeroOrMany = zeroOrMany;
|
|
33
33
|
/** Parses one or more occurences of the given parser, separated with the separator parser.
|
|
34
34
|
* @returns A parser returning an array of many parses, omitting the separator.
|
|
35
35
|
*/
|
|
36
|
-
function oneOrMany(item, separator) {
|
|
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]));
|
|
37
40
|
return (ctx) => {
|
|
38
|
-
const res =
|
|
39
|
-
if (types_1.isFailure(res)) {
|
|
41
|
+
const res = sequencer(ctx);
|
|
42
|
+
if ((0, types_1.isFailure)(res)) {
|
|
40
43
|
const newHistory = [...res.history];
|
|
41
44
|
newHistory.splice(0, 2);
|
|
42
|
-
return types_1.failure(res.ctx, res.expected, ['oneOrMany', ...newHistory]);
|
|
45
|
+
return (0, types_1.failure)(res.ctx, res.expected, ['oneOrMany', ...newHistory]);
|
|
43
46
|
}
|
|
44
47
|
return res;
|
|
45
48
|
};
|
|
@@ -49,7 +52,7 @@ exports.oneOrMany = oneOrMany;
|
|
|
49
52
|
* @returns A parser returning the result of many parses, reduced using the `reducer` function passed in.
|
|
50
53
|
*/
|
|
51
54
|
function oneOrManyRed(item, separator, reducer) {
|
|
52
|
-
return map_1.map(map_1.map(seq_1.seq(map_1.map(item, (x) => [null, x]), many(seq_1.seq(separator, item))), ([t, ts]) => ([t, ...ts])), ts => {
|
|
55
|
+
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 => {
|
|
53
56
|
let result = ts[0][1];
|
|
54
57
|
for (let i = 1; i < ts.length; i++) {
|
|
55
58
|
result = reducer(result, ts[i][1], ts[i][0]);
|
|
File without changes
|
|
@@ -8,15 +8,14 @@ const types_1 = require("../types");
|
|
|
8
8
|
function map(parser, mapper) {
|
|
9
9
|
return (ctx) => {
|
|
10
10
|
const res = parser(ctx);
|
|
11
|
-
if (types_1.isFailure(res))
|
|
12
|
-
return types_1.failure(res.ctx, res.expected, ['map', ...res.history]);
|
|
11
|
+
if ((0, types_1.isFailure)(res))
|
|
12
|
+
return (0, types_1.failure)(res.ctx, res.expected, ['map', ...res.history]);
|
|
13
13
|
try {
|
|
14
14
|
const newValue = mapper(res.value);
|
|
15
|
-
return types_1.success(res.ctx, newValue);
|
|
15
|
+
return (0, types_1.success)(res.ctx, newValue);
|
|
16
16
|
}
|
|
17
17
|
catch (e) {
|
|
18
|
-
|
|
19
|
-
return types_1.failure(res.ctx, 'Error while mapping', ['map']);
|
|
18
|
+
return (0, types_1.failure)(res.ctx, 'Error while mapping', ['map']);
|
|
20
19
|
}
|
|
21
20
|
};
|
|
22
21
|
}
|
|
File without changes
|
|
@@ -8,8 +8,8 @@ const types_1 = require("../types");
|
|
|
8
8
|
function opt(parser) {
|
|
9
9
|
return (ctx) => {
|
|
10
10
|
const parseResult = parser(ctx);
|
|
11
|
-
if (types_1.isFailure(parseResult)) {
|
|
12
|
-
return types_1.success(ctx, null);
|
|
11
|
+
if ((0, types_1.isFailure)(parseResult)) {
|
|
12
|
+
return (0, types_1.success)(ctx, null);
|
|
13
13
|
}
|
|
14
14
|
return parseResult;
|
|
15
15
|
};
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
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;
|
|
@@ -12,3 +12,5 @@ export declare function seq<T, U, V, W, X>(...parsers: [Parser<T>, Parser<U>, Pa
|
|
|
12
12
|
export declare function seq<T, U, V, W>(...parsers: [Parser<T>, Parser<U>, Parser<V>, Parser<W>]): Parser<[T, U, V, W]>;
|
|
13
13
|
export declare function seq<T, U, V>(...parsers: [Parser<T>, Parser<U>, Parser<V>]): Parser<[T, U, V]>;
|
|
14
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[]>;
|
|
@@ -8,11 +8,11 @@ function seq(...parsers) {
|
|
|
8
8
|
for (const parser of parsers) {
|
|
9
9
|
const res = parser(ctx);
|
|
10
10
|
ctx = res.ctx;
|
|
11
|
-
if (types_1.isFailure(res))
|
|
12
|
-
return types_1.failure(res.ctx, res.expected, ['seq', ...res.history]);
|
|
11
|
+
if ((0, types_1.isFailure)(res))
|
|
12
|
+
return (0, types_1.failure)(res.ctx, res.expected, ['seq', ...res.history]);
|
|
13
13
|
values.push(res.value);
|
|
14
14
|
}
|
|
15
|
-
return types_1.success(ctx, values);
|
|
15
|
+
return (0, types_1.success)(ctx, values);
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
exports.seq = seq;
|
|
File without changes
|
|
@@ -7,11 +7,11 @@ const types_1 = require("../types");
|
|
|
7
7
|
*/
|
|
8
8
|
function str(match) {
|
|
9
9
|
return (ctx) => {
|
|
10
|
-
if (ctx.text.
|
|
11
|
-
return types_1.success({ ...ctx, index: ctx.index + match.length }, match);
|
|
10
|
+
if (ctx.text.startsWith(match, ctx.index)) {
|
|
11
|
+
return (0, types_1.success)({ ...ctx, index: ctx.index + match.length }, match);
|
|
12
12
|
}
|
|
13
13
|
else {
|
|
14
|
-
return types_1.failure(ctx, match, [match]);
|
|
14
|
+
return (0, types_1.failure)(ctx, match, [match]);
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
17
|
}
|
|
@@ -2,8 +2,12 @@ import { Parser } from '../types';
|
|
|
2
2
|
/** Allows to make a condition on the result of the parsing function.
|
|
3
3
|
* @returns A parser returning the same but also performing a given check on the result.
|
|
4
4
|
*/
|
|
5
|
-
export declare function ref<T>(parser: Parser<T>, check: ((p: T) => boolean), expected
|
|
5
|
+
export declare function ref<T>(parser: Parser<T>, check: ((p: T) => boolean), expected?: string): Parser<T>;
|
|
6
6
|
/** Changes the expected value for when the parser fails.
|
|
7
7
|
* @returns A parser returning the same but with a different expected value.
|
|
8
8
|
*/
|
|
9
9
|
export declare function expect<T>(parser: Parser<T>, expected: string): Parser<T>;
|
|
10
|
+
/** Changes the expected value for when the parser fails. Erases the previous history.
|
|
11
|
+
* @returns A parser returning the same but with a different expected value.
|
|
12
|
+
*/
|
|
13
|
+
export declare function expectErase<T>(parser: Parser<T>, expected: string): Parser<T>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.expectErase = exports.expect = exports.ref = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
/** Allows to make a condition on the result of the parsing function.
|
|
6
|
+
* @returns A parser returning the same but also performing a given check on the result.
|
|
7
|
+
*/
|
|
8
|
+
function ref(parser, check, expected) {
|
|
9
|
+
return (ctx) => {
|
|
10
|
+
const res = parser(ctx);
|
|
11
|
+
if (!(0, types_1.isFailure)(res) && !check(res.value)) {
|
|
12
|
+
return (0, types_1.failure)(res.ctx, expected !== null && expected !== void 0 ? expected : 'check', [`ref: ${expected !== null && expected !== void 0 ? expected : 'check'}`]);
|
|
13
|
+
}
|
|
14
|
+
return res;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
exports.ref = ref;
|
|
18
|
+
/** Changes the expected value for when the parser fails.
|
|
19
|
+
* @returns A parser returning the same but with a different expected value.
|
|
20
|
+
*/
|
|
21
|
+
function expect(parser, expected) {
|
|
22
|
+
return (ctx) => {
|
|
23
|
+
const res = parser(ctx);
|
|
24
|
+
if ((0, types_1.isFailure)(res)) {
|
|
25
|
+
return (0, types_1.failure)(res.ctx, expected, [expected, ...res.history]);
|
|
26
|
+
}
|
|
27
|
+
return res;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
exports.expect = expect;
|
|
31
|
+
/** Changes the expected value for when the parser fails. Erases the previous history.
|
|
32
|
+
* @returns A parser returning the same but with a different expected value.
|
|
33
|
+
*/
|
|
34
|
+
function expectErase(parser, expected) {
|
|
35
|
+
return (ctx) => {
|
|
36
|
+
const res = parser(ctx);
|
|
37
|
+
if ((0, types_1.isFailure)(res)) {
|
|
38
|
+
return (0, types_1.failure)(res.ctx, expected, [expected]);
|
|
39
|
+
}
|
|
40
|
+
return res;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
exports.expectErase = expectErase;
|
|
File without changes
|
|
@@ -9,28 +9,28 @@ const str_1 = require("./str");
|
|
|
9
9
|
const utilities_1 = require("./utilities");
|
|
10
10
|
/** Parses 0 or more spaces
|
|
11
11
|
*/
|
|
12
|
-
exports.spaces = regex_1.regex(/ */, 'spaces');
|
|
12
|
+
exports.spaces = (0, regex_1.regex)(/ */, 'spaces');
|
|
13
13
|
/** Parses 1 or more spaces
|
|
14
14
|
*/
|
|
15
|
-
exports.spacesPlus = regex_1.regex(/ +/, 'spaces');
|
|
15
|
+
exports.spacesPlus = (0, regex_1.regex)(/ +/, 'spaces');
|
|
16
16
|
/** Parses 0 or more whitespace characters
|
|
17
17
|
*/
|
|
18
|
-
exports.wspaces = opt_1.opt(regex_1.regex(/(?:\s|\t|\n|\r)+/, 'whitespace characters'));
|
|
18
|
+
exports.wspaces = (0, opt_1.opt)((0, regex_1.regex)(/(?:\s|\t|\n|\r)+/, 'whitespace characters'));
|
|
19
19
|
/** Parses a boolean (true or false) and returns a string
|
|
20
20
|
*/
|
|
21
|
-
exports.bool = regex_1.regex(/true|false/, 'boolean');
|
|
21
|
+
exports.bool = (0, regex_1.regex)(/true|false/, 'boolean');
|
|
22
22
|
/** Parses a boolean (true or false) and returns a boolean
|
|
23
23
|
*/
|
|
24
|
-
exports.boolP = map_1.map(exports.bool, val => val === 'true');
|
|
24
|
+
exports.boolP = (0, map_1.map)(exports.bool, val => val === 'true');
|
|
25
25
|
/** Parses an integer and returns a string
|
|
26
26
|
*/
|
|
27
|
-
exports.int = regex_1.regex(/\d+/, 'integer');
|
|
27
|
+
exports.int = (0, regex_1.regex)(/\d+/, 'integer');
|
|
28
28
|
/** Parses an integer and returns a number
|
|
29
29
|
*/
|
|
30
|
-
exports.intP = map_1.map(exports.int, seq => parseInt(seq, 10));
|
|
30
|
+
exports.intP = (0, map_1.map)(exports.int, seq => parseInt(seq, 10));
|
|
31
31
|
/** Parses a standard real number (X.X) and returns a string
|
|
32
32
|
*/
|
|
33
|
-
exports.real = utilities_1.expect(map_1.map(seq_1.seq(exports.int, str_1.str('.'), exports.int), ([intPart, , decimalPart]) => `${intPart}.${decimalPart}`), 'real');
|
|
33
|
+
exports.real = (0, utilities_1.expect)((0, map_1.map)((0, seq_1.seq)(exports.int, (0, str_1.str)('.'), exports.int), ([intPart, , decimalPart]) => `${intPart}.${decimalPart}`), 'real');
|
|
34
34
|
/** Parses a standard real number (X.X) and returns a number
|
|
35
35
|
*/
|
|
36
|
-
exports.realP = map_1.map(exports.real, (seq) => parseFloat(seq));
|
|
36
|
+
exports.realP = (0, map_1.map)(exports.real, (seq) => parseFloat(seq));
|
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "parser-combinators",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"maintainers": [
|
|
6
6
|
"Micha_i"
|
|
@@ -16,33 +16,26 @@
|
|
|
16
16
|
"description": "A library of parser combinators, with which you can create your own parsers. The library will be continuously improved in time.",
|
|
17
17
|
"scripts": {
|
|
18
18
|
"build": "tsc",
|
|
19
|
-
"publishing:prepare": "copy package.json dist && copy README.md dist",
|
|
20
|
-
"publishing:patch": "npm version patch && npm run publishing:prepare",
|
|
21
|
-
"publishing:minor": "npm version minor && npm run publishing:prepare",
|
|
22
|
-
"publishing:major": "npm version major && npm run publishing:prepare",
|
|
23
19
|
"start": "tsc && node .",
|
|
24
20
|
"lint": "eslint . --ext .ts",
|
|
25
|
-
"test:unit": "cross-env TS_NODE_PROJECT=tsconfig.spec.json mocha",
|
|
21
|
+
"test:unit": "cross-env TS_NODE_PROJECT=tsconfig.spec.json mocha tests/**/*.ts",
|
|
26
22
|
"test": "nyc -e '.ts' --r html -r lcov -r text npm run test:unit",
|
|
27
|
-
"test:report": "nyc report --reporter=json > coverage/coverage.json
|
|
23
|
+
"test:report": "nyc report --reporter=json > coverage/coverage.json"
|
|
28
24
|
},
|
|
29
25
|
"author": "Micha_i <isalski.michal@gmail.com> (https://github.com/michalusio)",
|
|
30
|
-
"main": "./
|
|
31
|
-
"types": "./
|
|
32
|
-
"dependencies": {},
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
33
28
|
"devDependencies": {
|
|
34
|
-
"@types/mocha": "
|
|
35
|
-
"@types/node": "
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "
|
|
37
|
-
"@typescript-eslint/parser": "
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"ts-node": "^10.2.1",
|
|
45
|
-
"typescript": "^4.2.4"
|
|
29
|
+
"@types/mocha": "10.0.0",
|
|
30
|
+
"@types/node": "18.11.3",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "5.40.1",
|
|
32
|
+
"@typescript-eslint/parser": "5.40.1",
|
|
33
|
+
"cross-env": "7.0.3",
|
|
34
|
+
"eslint": "8.25.0",
|
|
35
|
+
"mocha": "10.1.0",
|
|
36
|
+
"nyc": "15.1.0",
|
|
37
|
+
"ts-node": "10.9.1",
|
|
38
|
+
"typescript": "4.8.4"
|
|
46
39
|
},
|
|
47
40
|
"keywords": [
|
|
48
41
|
"parser",
|
package/parsers/any.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.any = void 0;
|
|
4
|
-
const types_1 = require("../types");
|
|
5
|
-
function any(...parsers) {
|
|
6
|
-
return (ctx) => {
|
|
7
|
-
const expected = [];
|
|
8
|
-
for (const parser of parsers) {
|
|
9
|
-
const res = parser(ctx);
|
|
10
|
-
if (types_1.isFailure(res)) {
|
|
11
|
-
expected.push(res);
|
|
12
|
-
}
|
|
13
|
-
else
|
|
14
|
-
return res;
|
|
15
|
-
}
|
|
16
|
-
const longest = expected.reduce((a, b) => a.ctx.index > b.ctx.index ? a : b);
|
|
17
|
-
return types_1.failure(longest.ctx, longest.expected, ['any', ...longest.history]);
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
exports.any = any;
|
package/parsers/regex.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
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
|
-
return (ctx) => {
|
|
10
|
-
const regexMatch = ctx.text.substr(ctx.index).match(match);
|
|
11
|
-
if (regexMatch !== undefined && regexMatch !== null && regexMatch.index === 0) {
|
|
12
|
-
return types_1.success({ ...ctx, index: ctx.index + regexMatch[0].length }, ctx.text.substr(ctx.index, regexMatch[0].length));
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
return types_1.failure(ctx, expected, [expected]);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
exports.regex = regex;
|
package/parsers/utilities.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.expect = exports.ref = void 0;
|
|
4
|
-
const types_1 = require("../types");
|
|
5
|
-
/** Allows to make a condition on the result of the parsing function.
|
|
6
|
-
* @returns A parser returning the same but also performing a given check on the result.
|
|
7
|
-
*/
|
|
8
|
-
function ref(parser, check, expected) {
|
|
9
|
-
return (ctx) => {
|
|
10
|
-
const res = parser(ctx);
|
|
11
|
-
if (!types_1.isFailure(res) && !check(res.value)) {
|
|
12
|
-
return types_1.failure(res.ctx, expected, [`ref: ${expected}`]);
|
|
13
|
-
}
|
|
14
|
-
return res;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
exports.ref = ref;
|
|
18
|
-
/** Changes the expected value for when the parser fails.
|
|
19
|
-
* @returns A parser returning the same but with a different expected value.
|
|
20
|
-
*/
|
|
21
|
-
function expect(parser, expected) {
|
|
22
|
-
return (ctx) => {
|
|
23
|
-
const res = parser(ctx);
|
|
24
|
-
if (types_1.isFailure(res)) {
|
|
25
|
-
return types_1.failure(res.ctx, expected, [expected, ...res.history]);
|
|
26
|
-
}
|
|
27
|
-
return res;
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
exports.expect = expect;
|