tarsec 0.0.11 → 0.0.13
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/dist/combinators/seq.d.ts +1 -2
- package/dist/combinators/seq.js +1 -112
- package/dist/combinators.d.ts +135 -8
- package/dist/combinators.js +337 -86
- package/dist/parsers/within.d.ts +2 -0
- package/dist/parsers/within.js +51 -0
- package/dist/parsers.d.ts +16 -1
- package/dist/parsers.js +30 -5
- package/dist/trace.d.ts +3 -0
- package/dist/trace.js +70 -8
- package/dist/types.d.ts +63 -4
- package/dist/types.js +8 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +5 -1
- package/package.json +2 -1
- package/dist/parsers/betweenWithin.d.ts +0 -2
- package/dist/parsers/betweenWithin.js +0 -68
package/dist/parsers.js
CHANGED
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
if (v !== undefined) module.exports = v;
|
|
5
5
|
}
|
|
6
6
|
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "./combinators", "./trace", "./types", "./utils", "./parsers/
|
|
7
|
+
define(["require", "exports", "./combinators", "./trace", "./types", "./utils", "./parsers/within"], factory);
|
|
8
8
|
}
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.quotedString = exports.eof = exports.newline = exports.tab = exports.quote = exports.num = exports.word = exports.alphanum = exports.letter = exports.digit = exports.spaces = exports.space = exports.anyChar = exports.noneOf = exports.oneOf = exports.str = exports.char = exports.betweenWithin = void 0;
|
|
12
|
+
exports.regexParser = exports.quotedString = exports.eof = exports.newline = exports.tab = exports.quote = exports.num = exports.word = exports.alphanum = exports.letter = exports.digit = exports.spaces = exports.space = exports.anyChar = exports.noneOf = exports.oneOf = exports.str = exports.char = exports.betweenWithin = void 0;
|
|
13
13
|
const combinators_1 = require("./combinators");
|
|
14
14
|
const trace_1 = require("./trace");
|
|
15
15
|
const types_1 = require("./types");
|
|
16
16
|
const utils_1 = require("./utils");
|
|
17
|
-
var
|
|
18
|
-
Object.defineProperty(exports, "betweenWithin", { enumerable: true, get: function () { return
|
|
17
|
+
var within_1 = require("./parsers/within");
|
|
18
|
+
Object.defineProperty(exports, "betweenWithin", { enumerable: true, get: function () { return within_1.within; } });
|
|
19
19
|
/**
|
|
20
20
|
* Takes a character. Returns a parser that parses that character.
|
|
21
21
|
*
|
|
@@ -105,16 +105,27 @@
|
|
|
105
105
|
}
|
|
106
106
|
return (0, types_1.success)(input[0], input.slice(1));
|
|
107
107
|
});
|
|
108
|
+
/** A parser that matches one of " \t\n\r". */
|
|
108
109
|
exports.space = oneOf(" \t\n\r");
|
|
110
|
+
/** A parser that matches one or more spaces. */
|
|
109
111
|
exports.spaces = (0, combinators_1.many1WithJoin)(exports.space);
|
|
112
|
+
/** A parser that matches one digit. */
|
|
110
113
|
exports.digit = oneOf("0123456789");
|
|
114
|
+
/** A parser that matches one letter, currently lowercase only. */
|
|
111
115
|
exports.letter = oneOf("abcdefghijklmnopqrstuvwxyz");
|
|
116
|
+
/** A parser that matches one digit or letter, currently lowercase only. */
|
|
112
117
|
exports.alphanum = oneOf("abcdefghijklmnopqrstuvwxyz0123456789");
|
|
118
|
+
/** A parser that matches one lowercase word. */
|
|
113
119
|
exports.word = (0, combinators_1.many1WithJoin)(exports.letter);
|
|
120
|
+
/** A parser that matches one or more digits. */
|
|
114
121
|
exports.num = (0, combinators_1.many1WithJoin)(exports.digit);
|
|
122
|
+
/** A parser that matches one single or double quote. */
|
|
115
123
|
exports.quote = oneOf(`'"`);
|
|
124
|
+
/** A parser that matches one tab character. */
|
|
116
125
|
exports.tab = char("\t");
|
|
126
|
+
/** A parser that matches one newline ("\n" only) character. */
|
|
117
127
|
exports.newline = char("\n");
|
|
128
|
+
/** A parser that succeeds on an empty string. Returns `null` as the result. */
|
|
118
129
|
const eof = (input) => {
|
|
119
130
|
if (input === "") {
|
|
120
131
|
return (0, types_1.success)(null, input);
|
|
@@ -122,5 +133,19 @@
|
|
|
122
133
|
return (0, types_1.failure)("expected end of input", input);
|
|
123
134
|
};
|
|
124
135
|
exports.eof = eof;
|
|
125
|
-
|
|
136
|
+
/** A parser that matches a quoted string, in single or double quotes.
|
|
137
|
+
* Returns the string as the result, including the quotes.
|
|
138
|
+
*/
|
|
139
|
+
exports.quotedString = (0, combinators_1.seq)([exports.quote, (0, combinators_1.manyWithJoin)(noneOf(`"'`)), exports.quote], (results) => results.join(""));
|
|
140
|
+
function regexParser(str) {
|
|
141
|
+
const re = typeof str === "string" ? new RegExp(`^(${str})`) : str;
|
|
142
|
+
return (0, trace_1.trace)(`regex(${str})`, (input) => {
|
|
143
|
+
const match = input.match(re);
|
|
144
|
+
if (match) {
|
|
145
|
+
return (0, types_1.success)(match[0], input.slice(match[0].length));
|
|
146
|
+
}
|
|
147
|
+
return (0, types_1.failure)(`expected ${str}, got ${input.slice(0, 10)}`, input);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
exports.regexParser = regexParser;
|
|
126
151
|
});
|
package/dist/trace.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { ParserResult } from "./types";
|
|
2
2
|
export declare function resultToString<T>(name: string, result: ParserResult<T>): string;
|
|
3
3
|
export declare function trace(name: string, parser: any): any;
|
|
4
|
+
export declare function parserTime(callback: Function): number | null;
|
|
5
|
+
export declare function printTime(name: string, callback: Function): void;
|
|
6
|
+
export declare function parserDebug(name: string, callback: Function): void;
|
package/dist/trace.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.trace = exports.resultToString = void 0;
|
|
12
|
+
exports.parserDebug = exports.printTime = exports.parserTime = exports.trace = exports.resultToString = void 0;
|
|
13
13
|
const utils_1 = require("./utils");
|
|
14
14
|
const STEP = 2;
|
|
15
15
|
function resultToString(name, result) {
|
|
@@ -20,23 +20,85 @@
|
|
|
20
20
|
}
|
|
21
21
|
exports.resultToString = resultToString;
|
|
22
22
|
let level = 0;
|
|
23
|
+
let counts = {};
|
|
24
|
+
let times = {};
|
|
25
|
+
let debugFlag = !!process.env.DEBUG;
|
|
26
|
+
let stepCount = 0;
|
|
27
|
+
let stepLimit = -1;
|
|
23
28
|
function trace(name, parser) {
|
|
24
29
|
return (input) => {
|
|
25
|
-
if (
|
|
30
|
+
if (debugFlag) {
|
|
26
31
|
console.log(" ".repeat(level) + `🔍 ${name} -- input: ${(0, utils_1.escape)(input)}`);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
let result;
|
|
33
|
+
const time = parserTime(() => {
|
|
34
|
+
level += STEP;
|
|
35
|
+
result = parser(input);
|
|
36
|
+
level -= STEP;
|
|
37
|
+
});
|
|
38
|
+
counts[name] = counts[name] ? counts[name] + 1 : 1;
|
|
39
|
+
stepCount += 1;
|
|
40
|
+
if (time) {
|
|
41
|
+
times[name] = times[name] ? times[name] + time : time;
|
|
42
|
+
}
|
|
32
43
|
console.log(" ".repeat(level) + resultToString(name, result));
|
|
33
44
|
if (result.success && result.captures) {
|
|
34
45
|
console.log(" ".repeat(level) +
|
|
35
46
|
`⭐ ${name} -- captures: ${JSON.stringify(result.captures)}`);
|
|
36
47
|
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return parser(input);
|
|
37
52
|
}
|
|
38
|
-
return result;
|
|
39
53
|
};
|
|
40
54
|
}
|
|
41
55
|
exports.trace = trace;
|
|
56
|
+
function parserTime(callback) {
|
|
57
|
+
if (performance && performance.now) {
|
|
58
|
+
const start = performance.now();
|
|
59
|
+
callback();
|
|
60
|
+
const end = performance.now();
|
|
61
|
+
return end - start;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.error("performance.now not available");
|
|
65
|
+
callback();
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.parserTime = parserTime;
|
|
70
|
+
function printTime(name, callback) {
|
|
71
|
+
const time = parserTime(callback);
|
|
72
|
+
if (time) {
|
|
73
|
+
console.log(`⏱ ${name} -- time: ${(0, utils_1.round)(time)}ms`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.printTime = printTime;
|
|
77
|
+
function parserDebug(name, callback) {
|
|
78
|
+
debugFlag = true;
|
|
79
|
+
stepCount = 0;
|
|
80
|
+
counts = {};
|
|
81
|
+
times = {};
|
|
82
|
+
printTime(name, callback);
|
|
83
|
+
debugFlag = false;
|
|
84
|
+
console.log("\n");
|
|
85
|
+
console.log(`📊 ${name} -- counts:`);
|
|
86
|
+
const sorted = Object.entries(counts).sort((a, b) => b[1] - a[1]);
|
|
87
|
+
for (const [name, count] of sorted) {
|
|
88
|
+
console.log(` ${name}: ${count}`);
|
|
89
|
+
}
|
|
90
|
+
console.log("\n");
|
|
91
|
+
console.log(`📊 ${name} -- times:`);
|
|
92
|
+
const sortedTimes = Object.entries(times).sort((a, b) => b[1] - a[1]);
|
|
93
|
+
for (const [name, time] of sortedTimes) {
|
|
94
|
+
console.log(` ${name}: ${(0, utils_1.round)(time)}ms`);
|
|
95
|
+
}
|
|
96
|
+
console.log("\n");
|
|
97
|
+
console.log(`📊 ${name} -- step count: ${stepCount}`);
|
|
98
|
+
console.log("\n\n");
|
|
99
|
+
stepCount = 0;
|
|
100
|
+
counts = {};
|
|
101
|
+
times = {};
|
|
102
|
+
}
|
|
103
|
+
exports.parserDebug = parserDebug;
|
|
42
104
|
});
|
package/dist/types.d.ts
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
/** A generic object type. */
|
|
1
2
|
export type PlainObject = Record<string, unknown>;
|
|
3
|
+
/** Represents a parse success with no captures. */
|
|
2
4
|
export type ParserSuccess<T> = {
|
|
3
5
|
success: true;
|
|
4
6
|
result: T;
|
|
5
7
|
rest: string;
|
|
6
|
-
nextParser?:
|
|
8
|
+
nextParser?: Parser<any>;
|
|
7
9
|
};
|
|
8
|
-
|
|
10
|
+
/** Represents a parse success with captures. Notice nextParser is also a CaptureParser. */
|
|
11
|
+
export type CaptureParserSuccess<T, C extends PlainObject> = {
|
|
12
|
+
success: true;
|
|
13
|
+
result: T;
|
|
14
|
+
rest: string;
|
|
9
15
|
captures: C;
|
|
16
|
+
nextParser?: CaptureParser<any, any>;
|
|
10
17
|
};
|
|
18
|
+
/** Represents a parse failure. */
|
|
11
19
|
export type ParserFailure = {
|
|
12
20
|
success: false;
|
|
13
21
|
rest: string;
|
|
@@ -15,22 +23,67 @@ export type ParserFailure = {
|
|
|
15
23
|
};
|
|
16
24
|
export type ParserResult<T> = ParserSuccess<T> | ParserFailure;
|
|
17
25
|
export type CaptureParserResult<T, C extends PlainObject> = CaptureParserSuccess<T, C> | ParserFailure;
|
|
26
|
+
/** A parser is any function that takes a string and returns a ParserResult. */
|
|
18
27
|
export type Parser<T> = (input: string) => ParserResult<T>;
|
|
28
|
+
/** A capture parser is any function that takes a string and returns a CaptureParserResult.
|
|
29
|
+
* A CaptureParserResult is the same as a ParserResult, except it also includes captures,
|
|
30
|
+
* i.e. matches selected using `capture`. */
|
|
19
31
|
export type CaptureParser<T, C extends PlainObject> = (input: string) => CaptureParserResult<T, C>;
|
|
20
32
|
export type GeneralParser<T, C extends PlainObject> = Parser<T> | CaptureParser<T, C>;
|
|
21
33
|
export declare function isCaptureResult<T, C extends PlainObject>(result: ParserResult<T>): result is CaptureParserSuccess<T, C>;
|
|
34
|
+
/** Convenience function to return a ParserSuccess */
|
|
22
35
|
export declare function success<T>(result: T, rest: string): ParserSuccess<T>;
|
|
36
|
+
/** Convenience function to return a CaptureParserSuccess */
|
|
23
37
|
export declare function captureSuccess<T, C extends PlainObject>(result: T, rest: string, captures: C): CaptureParserSuccess<T, C>;
|
|
38
|
+
/** Convenience function to return a ParserFailure */
|
|
24
39
|
export declare function failure(message: string, rest: string): ParserFailure;
|
|
40
|
+
/** Prettify an intersected type, to make it easier to read. */
|
|
25
41
|
export type Prettify<T> = {
|
|
26
42
|
[K in keyof T]: T[K];
|
|
27
43
|
} & {};
|
|
44
|
+
/** see <https://stackoverflow.com/a/50375286/3625> */
|
|
28
45
|
export type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
46
|
+
/** Convenience type to get the result type out of a parser. */
|
|
29
47
|
type ExtractResults<T> = T extends Parser<infer U> ? U : never;
|
|
48
|
+
/** Convenience type to get the capture type out of a capture parser. */
|
|
30
49
|
type ExtractCaptures<T> = T extends CaptureParser<any, infer U> ? U : never;
|
|
50
|
+
/** Convenience type where given an array of parsers and capture parsers,
|
|
51
|
+
* it returns the types of the capture parsers, like
|
|
52
|
+
* CaptureParser<string, { name: string }> | CaptureParser<number, { age: number }>
|
|
53
|
+
*/
|
|
31
54
|
type ExtractCaptureParsers<T extends readonly GeneralParser<any, any>[]> = Extract<T[number], CaptureParser<any, any>>;
|
|
32
|
-
|
|
55
|
+
/** Convenience type where given an array of parsers and capture parsers,
|
|
56
|
+
* it returns a single capture type that merges all the capture types. */
|
|
57
|
+
export type MergedCaptures<T extends readonly GeneralParser<any, any>[]> = Prettify<UnionToIntersection<UnionOfCaptures<T>>>;
|
|
58
|
+
/** Convenience type where given an array of parsers and capture parsers,
|
|
59
|
+
* it first gets the capture parsers, then extracts the capture types,
|
|
60
|
+
* and returns a union of all the capture types. Example:
|
|
61
|
+
* { name: string } | { age: number }
|
|
62
|
+
*/
|
|
63
|
+
export type UnionOfCaptures<T extends readonly GeneralParser<any, any>[]> = Prettify<ExtractCaptures<ExtractCaptureParsers<T>>>;
|
|
64
|
+
/** Convenience type where given an array of parsers and capture parsers,
|
|
65
|
+
* it returns true if there are any capture parsers, otherwise false. */
|
|
66
|
+
export type HasCaptureParsers<T extends readonly GeneralParser<any, any>[]> = ExtractCaptureParsers<T> extends never ? false : true;
|
|
67
|
+
/**
|
|
68
|
+
* For a given array of GeneralParsers, if any of them is a CaptureParser,
|
|
69
|
+
* PickParserType says the array is an array of CaptureParsers,
|
|
70
|
+
* otherwise it's an array of Parsers. It also correctly merges
|
|
71
|
+
* the result and capture types. This is useful for a combinator like `or`
|
|
72
|
+
* which is not able to infer its return type correctly.
|
|
73
|
+
*/
|
|
74
|
+
export type PickParserType<T extends readonly GeneralParser<any, any>[]> = HasCaptureParsers<T> extends true ? CaptureParser<MergedResults<T>, UnionOfCaptures<T>> : Parser<MergedResults<T>>;
|
|
75
|
+
/** This is used to generate a return type for the `many` and `many1` combinators.
|
|
76
|
+
* Given a parser we want to apply `many` to. Suppose its type is `Parser<string>`.
|
|
77
|
+
* This will return `Parser<string[]>` as the return type.
|
|
78
|
+
*
|
|
79
|
+
* Suppose the parser is a `CaptureParser<string, { name: string }>`.
|
|
80
|
+
* This will return `CaptureParser<string[], { captures: { name: string }[] }>` as the return type.
|
|
81
|
+
*/
|
|
82
|
+
export type InferManyReturnType<T extends GeneralParser<any, any>> = T extends CaptureParser<infer R, infer C> ? CaptureParser<R[], {
|
|
83
|
+
captures: C[];
|
|
84
|
+
}> : Parser<T[]>;
|
|
33
85
|
export type MergedResults<T extends readonly GeneralParser<any, any>[]> = ExtractResults<T[number]>;
|
|
86
|
+
/** Used to create a parser tree for backtracking. */
|
|
34
87
|
export type Node = ParserNode | EmptyNode;
|
|
35
88
|
export type ParserNode = {
|
|
36
89
|
parent: Node;
|
|
@@ -40,8 +93,14 @@ export type ParserNode = {
|
|
|
40
93
|
closed: boolean;
|
|
41
94
|
};
|
|
42
95
|
export type EmptyNode = null;
|
|
96
|
+
/** Convenience function to create a ParserNode. */
|
|
43
97
|
export declare function createNode(parent: Node | null, parser: GeneralParser<any, any>): ParserNode;
|
|
98
|
+
/** Convenience function where, given an array of parsers, it creates a tree we can use for backtracking.
|
|
99
|
+
* This tree is what `seq` use. It's used to keep track of the parsers we've tried so far,
|
|
100
|
+
* so we can backtrack if we need to.
|
|
101
|
+
*/
|
|
44
102
|
export declare function createTree(parsers: readonly GeneralParser<any, any>[]): Node;
|
|
103
|
+
/** Used by `within`. */
|
|
45
104
|
export type Matched = {
|
|
46
105
|
type: "matched";
|
|
47
106
|
value: string;
|
|
@@ -50,5 +109,5 @@ export type Unmatched = {
|
|
|
50
109
|
type: "unmatched";
|
|
51
110
|
value: string;
|
|
52
111
|
};
|
|
53
|
-
export type
|
|
112
|
+
export type WithinResult = Matched | Unmatched;
|
|
54
113
|
export {};
|
package/dist/types.js
CHANGED
|
@@ -14,18 +14,22 @@
|
|
|
14
14
|
return "captures" in result;
|
|
15
15
|
}
|
|
16
16
|
exports.isCaptureResult = isCaptureResult;
|
|
17
|
+
/** Convenience function to return a ParserSuccess */
|
|
17
18
|
function success(result, rest) {
|
|
18
19
|
return { success: true, result, rest };
|
|
19
20
|
}
|
|
20
21
|
exports.success = success;
|
|
22
|
+
/** Convenience function to return a CaptureParserSuccess */
|
|
21
23
|
function captureSuccess(result, rest, captures) {
|
|
22
24
|
return { success: true, result, rest, captures };
|
|
23
25
|
}
|
|
24
26
|
exports.captureSuccess = captureSuccess;
|
|
27
|
+
/** Convenience function to return a ParserFailure */
|
|
25
28
|
function failure(message, rest) {
|
|
26
29
|
return { success: false, message, rest };
|
|
27
30
|
}
|
|
28
31
|
exports.failure = failure;
|
|
32
|
+
/** Convenience function to create a ParserNode. */
|
|
29
33
|
function createNode(parent, parser) {
|
|
30
34
|
return {
|
|
31
35
|
parent,
|
|
@@ -35,6 +39,10 @@
|
|
|
35
39
|
};
|
|
36
40
|
}
|
|
37
41
|
exports.createNode = createNode;
|
|
42
|
+
/** Convenience function where, given an array of parsers, it creates a tree we can use for backtracking.
|
|
43
|
+
* This tree is what `seq` use. It's used to keep track of the parsers we've tried so far,
|
|
44
|
+
* so we can backtrack if we need to.
|
|
45
|
+
*/
|
|
38
46
|
function createTree(parsers) {
|
|
39
47
|
if (parsers.length === 0) {
|
|
40
48
|
return null;
|
package/dist/utils.d.ts
CHANGED
|
@@ -4,3 +4,4 @@ export declare function merge(a: any | any[], b: any | any[]): any[];
|
|
|
4
4
|
export declare function mergeCaptures(a: Record<string, any>, b: Record<string, any>): Record<string, any>;
|
|
5
5
|
export declare function findAncestorWithNextParser(node: Node, count?: number): [Node, number];
|
|
6
6
|
export declare function popMany(arr: any[], count: number): void;
|
|
7
|
+
export declare function round(num: number, places?: number): number;
|
package/dist/utils.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.popMany = exports.findAncestorWithNextParser = exports.mergeCaptures = exports.merge = exports.escape = void 0;
|
|
12
|
+
exports.round = exports.popMany = exports.findAncestorWithNextParser = exports.mergeCaptures = exports.merge = exports.escape = void 0;
|
|
13
13
|
function escape(str) {
|
|
14
14
|
return JSON.stringify(str);
|
|
15
15
|
}
|
|
@@ -63,4 +63,8 @@
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
exports.popMany = popMany;
|
|
66
|
+
function round(num, places = 2) {
|
|
67
|
+
return Math.round(num * 10 ** places) / 10 ** places;
|
|
68
|
+
}
|
|
69
|
+
exports.round = round;
|
|
66
70
|
});
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tarsec",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "A parser combinator library for TypeScript, inspired by Parsec.",
|
|
5
5
|
"homepage": "https://github.com/egonSchiele/tarsec",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "vitest",
|
|
8
|
+
"test:tsc": "tsc -p tests/tsconfig.json",
|
|
8
9
|
"coverage": "vitest --coverage",
|
|
9
10
|
"build": "rm -rf dist && tsc",
|
|
10
11
|
"start": "cd dist && node index.js",
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
(function (factory) {
|
|
2
|
-
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
-
var v = factory(require, exports);
|
|
4
|
-
if (v !== undefined) module.exports = v;
|
|
5
|
-
}
|
|
6
|
-
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "../trace", "../types"], factory);
|
|
8
|
-
}
|
|
9
|
-
})(function (require, exports) {
|
|
10
|
-
"use strict";
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.betweenWithin = void 0;
|
|
13
|
-
const trace_1 = require("../trace");
|
|
14
|
-
const types_1 = require("../types");
|
|
15
|
-
function betweenWithin(parser) {
|
|
16
|
-
return (0, trace_1.trace)("betweenWithin", (input) => {
|
|
17
|
-
let start = 0;
|
|
18
|
-
let current = 0;
|
|
19
|
-
let currentlyMatching = false;
|
|
20
|
-
const results = [];
|
|
21
|
-
while (current < input.length) {
|
|
22
|
-
const parsed = parser(input.slice(current));
|
|
23
|
-
if (parsed.success) {
|
|
24
|
-
if (currentlyMatching) {
|
|
25
|
-
const value = input.slice(start, current + parsed.result.length);
|
|
26
|
-
if (value.length > 0) {
|
|
27
|
-
results.push({
|
|
28
|
-
type: "matched",
|
|
29
|
-
value,
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
current += parsed.result.length;
|
|
33
|
-
start = current;
|
|
34
|
-
currentlyMatching = false;
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
const value = input.slice(start, current);
|
|
38
|
-
if (value.length > 0) {
|
|
39
|
-
results.push({
|
|
40
|
-
type: "unmatched",
|
|
41
|
-
value,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
currentlyMatching = true;
|
|
45
|
-
start = current;
|
|
46
|
-
current += parsed.result.length;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
current += 1;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if (start < current) {
|
|
54
|
-
if (currentlyMatching) {
|
|
55
|
-
return (0, types_1.failure)("unexpected end of input", "");
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
results.push({
|
|
59
|
-
type: "unmatched",
|
|
60
|
-
value: input.slice(start, current),
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return (0, types_1.success)(results, "");
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
exports.betweenWithin = betweenWithin;
|
|
68
|
-
});
|