parser-combinators 1.1.3 → 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.
@@ -1,43 +1,96 @@
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;
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
+ }
@@ -1,28 +1,31 @@
1
- import { Parser } from '../types';
2
- /** Parses 0 or more spaces
3
- */
4
- export declare const spaces: Parser<string>;
5
- /** Parses 1 or more spaces
6
- */
7
- export declare const spacesPlus: Parser<string>;
8
- /** Parses 0 or more whitespace characters
9
- */
10
- export declare const wspaces: Parser<string | null>;
11
- /** Parses a boolean (true or false) and returns a string
12
- */
13
- export declare const bool: Parser<'true' | 'false'>;
14
- /** Parses a boolean (true or false) and returns a boolean
15
- */
16
- export declare const boolP: Parser<boolean>;
17
- /** Parses an integer and returns a string
18
- */
19
- export declare const int: Parser<string>;
20
- /** Parses an integer and returns a number
21
- */
22
- export declare const intP: Parser<number>;
23
- /** Parses a standard real number (X.X) and returns a string
24
- */
25
- export declare const real: Parser<`${number}.${number}`>;
26
- /** Parses a standard real number (X.X) and returns a number
27
- */
28
- export declare const realP: Parser<number>;
1
+ import { Parser } from '../types';
2
+ /** Parses 0 or more spaces
3
+ */
4
+ export declare const spaces: Parser<string>;
5
+ /** Parses 1 or more spaces
6
+ */
7
+ export declare const spacesPlus: Parser<string>;
8
+ /** Parses 0 or more whitespace characters
9
+ */
10
+ export declare const wspaces: Parser<string | null>;
11
+ /** Parses a boolean (true or false) and returns a string
12
+ */
13
+ export declare const bool: Parser<'true' | 'false'>;
14
+ /** Parses a boolean (true or false) and returns a boolean
15
+ */
16
+ export declare const boolP: Parser<boolean>;
17
+ /** Parses an integer and returns a string
18
+ */
19
+ export declare const int: Parser<string>;
20
+ /** Parses an integer and returns a number
21
+ */
22
+ export declare const intP: Parser<number>;
23
+ /** Parses a standard real number (X.X) and returns a string
24
+ */
25
+ export declare const real: Parser<`${number}.${number}`>;
26
+ /** Parses a standard real number (X.X) and returns a number
27
+ */
28
+ export declare const realP: Parser<number>;
29
+ /** Parses an end of text/file. Fails if the parser is not at the end.
30
+ */
31
+ export declare const eof: Parser<void>;
@@ -1,36 +1,48 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.realP = exports.real = exports.intP = exports.int = exports.boolP = exports.bool = exports.wspaces = exports.spacesPlus = exports.spaces = void 0;
4
- const map_1 = require("./map");
5
- const opt_1 = require("./opt");
6
- const regex_1 = require("./regex");
7
- const seq_1 = require("./seq");
8
- const str_1 = require("./str");
9
- const utilities_1 = require("./utilities");
10
- /** Parses 0 or more spaces
11
- */
12
- exports.spaces = (0, regex_1.regex)(/ */, 'spaces');
13
- /** Parses 1 or more spaces
14
- */
15
- exports.spacesPlus = (0, regex_1.regex)(/ +/, 'spaces');
16
- /** Parses 0 or more whitespace characters
17
- */
18
- exports.wspaces = (0, opt_1.opt)((0, regex_1.regex)(/(?:\s|\t|\n|\r)+/, 'whitespace characters'));
19
- /** Parses a boolean (true or false) and returns a string
20
- */
21
- exports.bool = (0, regex_1.regex)(/true|false/, 'boolean');
22
- /** Parses a boolean (true or false) and returns a boolean
23
- */
24
- exports.boolP = (0, map_1.map)(exports.bool, val => val === 'true');
25
- /** Parses an integer and returns a string
26
- */
27
- exports.int = (0, regex_1.regex)(/\d+/, 'integer');
28
- /** Parses an integer and returns a number
29
- */
30
- exports.intP = (0, map_1.map)(exports.int, seq => parseInt(seq, 10));
31
- /** Parses a standard real number (X.X) and returns a string
32
- */
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
- /** Parses a standard real number (X.X) and returns a number
35
- */
36
- exports.realP = (0, map_1.map)(exports.real, (seq) => parseFloat(seq));
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.eof = exports.realP = exports.real = exports.intP = exports.int = exports.boolP = exports.bool = exports.wspaces = exports.spacesPlus = exports.spaces = void 0;
4
+ const types_1 = require("../types");
5
+ const map_1 = require("./map");
6
+ const opt_1 = require("./opt");
7
+ const regex_1 = require("./regex");
8
+ const seq_1 = require("./seq");
9
+ const str_1 = require("./str");
10
+ const utilities_1 = require("./utilities");
11
+ /** Parses 0 or more spaces
12
+ */
13
+ exports.spaces = (0, regex_1.regex)(/ */, 'spaces');
14
+ /** Parses 1 or more spaces
15
+ */
16
+ exports.spacesPlus = (0, regex_1.regex)(/ +/, 'spaces');
17
+ /** Parses 0 or more whitespace characters
18
+ */
19
+ exports.wspaces = (0, opt_1.opt)((0, regex_1.regex)(/(?:\s|\t|\n|\r)+/, 'whitespace characters'));
20
+ /** Parses a boolean (true or false) and returns a string
21
+ */
22
+ exports.bool = (0, regex_1.regex)(/true|false/, 'boolean');
23
+ /** Parses a boolean (true or false) and returns a boolean
24
+ */
25
+ exports.boolP = (0, map_1.map)(exports.bool, val => val === 'true');
26
+ /** Parses an integer and returns a string
27
+ */
28
+ exports.int = (0, regex_1.regex)(/\d+/, 'integer');
29
+ /** Parses an integer and returns a number
30
+ */
31
+ exports.intP = (0, map_1.map)(exports.int, seq => parseInt(seq, 10));
32
+ /** Parses a standard real number (X.X) and returns a string
33
+ */
34
+ 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');
35
+ /** Parses a standard real number (X.X) and returns a number
36
+ */
37
+ exports.realP = (0, map_1.map)(exports.real, (seq) => parseFloat(seq));
38
+ /** Parses an end of text/file. Fails if the parser is not at the end.
39
+ */
40
+ const eof = (ctx) => {
41
+ if (ctx.index === ctx.text.length) {
42
+ return (0, types_1.success)(ctx, void 0);
43
+ }
44
+ else {
45
+ return (0, types_1.failure)(ctx, "End Of File", ["EOF"]);
46
+ }
47
+ };
48
+ exports.eof = eof;
package/dist/types.d.ts CHANGED
@@ -1,33 +1,40 @@
1
- export declare type Parser<T> = (ctx: Context) => Result<T>;
2
- export declare type Context = Readonly<{
3
- text: string;
4
- path: string;
5
- index: number;
6
- }>;
7
- export declare type Result<T> = Success<T> | Failure;
8
- export declare type Success<T> = Readonly<{
9
- success: true;
10
- value: T;
11
- ctx: Context;
12
- }>;
13
- export declare type Failure = Readonly<{
14
- success: false;
15
- expected: string;
16
- ctx: Context;
17
- history: string[];
18
- }>;
19
- export declare function isFailure(input: unknown): input is Failure;
20
- export declare function success<T>(ctx: Context, value: T): Success<T>;
21
- export declare function failure(ctx: Context, expected: string, history: string[]): Failure;
22
- export declare function result<T>(value: T): Parser<T>;
23
- export declare function fail<T>(reason: string): Parser<T>;
24
- export declare class ParseError extends Error {
25
- readonly index: number;
26
- readonly history: string[];
27
- readonly line: string;
28
- readonly column: number;
29
- readonly row: number;
30
- constructor(message: string, input: string, index: number, history: string[]);
31
- private getInputData;
32
- getPrettyErrorMessage(): string;
33
- }
1
+ export type Parser<T> = (ctx: Context) => Result<T>;
2
+ export type Context = Readonly<{
3
+ text: string;
4
+ path: string;
5
+ index: number;
6
+ }>;
7
+ export type Result<T> = Success<T> | Failure;
8
+ export type Success<T> = Readonly<{
9
+ success: true;
10
+ value: T;
11
+ ctx: Context;
12
+ }>;
13
+ export type Failure = Readonly<{
14
+ success: false;
15
+ expected: string;
16
+ ctx: Context;
17
+ history: string[];
18
+ }>;
19
+ export type TokenRange = {
20
+ start: number;
21
+ end: number;
22
+ };
23
+ export type Token<T> = TokenRange & {
24
+ value: T;
25
+ };
26
+ export declare function isFailure(input: unknown): input is Failure;
27
+ export declare function success<T>(ctx: Context, value: T): Success<T>;
28
+ export declare function failure(ctx: Context, expected: string, history: string[]): Failure;
29
+ export declare function result<T>(value: T): Parser<T>;
30
+ export declare function fail<T>(reason: string): Parser<T>;
31
+ export declare class ParseError extends Error {
32
+ readonly index: number;
33
+ readonly history: string[];
34
+ readonly line: string;
35
+ readonly column: number;
36
+ readonly row: number;
37
+ constructor(message: string, input: string, index: number, history: string[]);
38
+ private getInputData;
39
+ getPrettyErrorMessage(): string;
40
+ }
package/dist/types.js CHANGED
@@ -1,47 +1,47 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ParseError = exports.fail = exports.result = exports.failure = exports.success = exports.isFailure = void 0;
4
- function isFailure(input) {
5
- return !input.success;
6
- }
7
- exports.isFailure = isFailure;
8
- function success(ctx, value) {
9
- return { success: true, value, ctx };
10
- }
11
- exports.success = success;
12
- function failure(ctx, expected, history) {
13
- return { success: false, expected, ctx, history };
14
- }
15
- exports.failure = failure;
16
- function result(value) {
17
- return (ctx) => success(ctx, value);
18
- }
19
- exports.result = result;
20
- function fail(reason) {
21
- return (ctx) => failure(ctx, reason, [reason]);
22
- }
23
- exports.fail = fail;
24
- class ParseError extends Error {
25
- constructor(message, input, index, history) {
26
- super(message);
27
- this.index = index;
28
- this.history = history;
29
- [this.line, this.column, this.row] = this.getInputData(input, index);
30
- }
31
- getInputData(input, index) {
32
- const lines = input.split('\n');
33
- let row = 0;
34
- while (index > 0) {
35
- if (lines[row].length > index) {
36
- return [lines[row], index + 1, row + 1];
37
- }
38
- index -= lines[row].length + 1;
39
- row += 1;
40
- }
41
- return [lines[row], index + 1, row + 1];
42
- }
43
- getPrettyErrorMessage() {
44
- return `${this.message} (line ${this.row}, col ${this.column})\n${this.line}\n${(this.column ? ' '.repeat(this.column - 1) : '') + '^'}`;
45
- }
46
- }
47
- exports.ParseError = ParseError;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ParseError = void 0;
4
+ exports.isFailure = isFailure;
5
+ exports.success = success;
6
+ exports.failure = failure;
7
+ exports.result = result;
8
+ exports.fail = fail;
9
+ function isFailure(input) {
10
+ return !input.success;
11
+ }
12
+ function success(ctx, value) {
13
+ return { success: true, value, ctx };
14
+ }
15
+ function failure(ctx, expected, history) {
16
+ return { success: false, expected, ctx, history };
17
+ }
18
+ function result(value) {
19
+ return (ctx) => success(ctx, value);
20
+ }
21
+ function fail(reason) {
22
+ return (ctx) => failure(ctx, reason, [reason]);
23
+ }
24
+ class ParseError extends Error {
25
+ constructor(message, input, index, history) {
26
+ super(message);
27
+ this.index = index;
28
+ this.history = history;
29
+ [this.line, this.column, this.row] = this.getInputData(input, index);
30
+ }
31
+ getInputData(input, index) {
32
+ const lines = input.split('\n');
33
+ let row = 0;
34
+ while (index > 0) {
35
+ if (lines[row].length > index) {
36
+ return [lines[row], index + 1, row + 1];
37
+ }
38
+ index -= lines[row].length + 1;
39
+ row += 1;
40
+ }
41
+ return [lines[row], index + 1, row + 1];
42
+ }
43
+ getPrettyErrorMessage() {
44
+ return `${this.message} (line ${this.row}, col ${this.column}):\n${this.line}\n${(this.column > 0 ? '-'.repeat(this.column - 1) : '') + '^'}`;
45
+ }
46
+ }
47
+ exports.ParseError = ParseError;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "parser-combinators",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "license": "ISC",
5
5
  "maintainers": [
6
6
  "Micha_i"
7
7
  ],
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "https://github.com/michalusio/Parser.git"
10
+ "url": "git+https://github.com/michalusio/Parser.git"
11
11
  },
12
12
  "bugs": {
13
13
  "url": "https://github.com/michalusio/Parser/issues"
@@ -18,24 +18,29 @@
18
18
  "build": "tsc",
19
19
  "start": "tsc && node .",
20
20
  "lint": "eslint . --ext .ts",
21
- "test:unit": "cross-env TS_NODE_PROJECT=tsconfig.spec.json mocha tests/**/*.ts",
22
- "test": "nyc -e '.ts' --r html -r lcov -r text npm run test:unit",
23
- "test:report": "nyc report --reporter=json > coverage/coverage.json"
21
+ "test:mutate": "stryker run",
22
+ "test:unit": "mocha",
23
+ "test": "nyc -e '.ts' --r html -r lcov -r text npm run test:unit"
24
24
  },
25
25
  "author": "Micha_i <isalski.michal@gmail.com> (https://github.com/michalusio)",
26
26
  "main": "./dist/index.js",
27
27
  "types": "./dist/index.d.ts",
28
+ "engines": {
29
+ "node": ">=18"
30
+ },
28
31
  "devDependencies": {
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"
32
+ "@stryker-mutator/core": "^9.4.0",
33
+ "@stryker-mutator/mocha-runner": "^9.4.0",
34
+ "@stryker-mutator/typescript-checker": "^9.4.0",
35
+ "@types/mocha": "10.0.10",
36
+ "@types/node": "25.0.6",
37
+ "cross-env": "10.1.0",
38
+ "eslint": "9.39.2",
39
+ "mocha": "11.7.5",
40
+ "nyc": "17.1.0",
41
+ "ts-node": "10.9.2",
42
+ "typescript": "5.9.3",
43
+ "typescript-eslint": "8.52.0"
39
44
  },
40
45
  "keywords": [
41
46
  "parser",