tarsec 0.0.8 → 0.0.9
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/README.md +6 -6
- package/dist/combinators.d.ts +8 -6
- package/dist/combinators.js +130 -57
- package/dist/lib/combinators.d.ts +17 -0
- package/dist/lib/combinators.js +272 -0
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.js +29 -0
- package/dist/lib/parsers.d.ts +17 -0
- package/dist/lib/parsers.js +87 -0
- package/dist/lib/trace.d.ts +3 -0
- package/dist/lib/trace.js +42 -0
- package/dist/lib/types.d.ts +33 -0
- package/dist/lib/types.js +49 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.js +48 -0
- package/dist/parsers.d.ts +1 -1
- package/dist/parsers.js +12 -39
- package/dist/trace.d.ts +3 -3
- package/dist/trace.js +1 -1
- package/dist/types.d.ts +25 -9
- package/dist/types.js +37 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -19,14 +19,14 @@ npm install tarsec
|
|
|
19
19
|
## Hello world
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
|
-
import { str, seq, space } from "tarsec";
|
|
22
|
+
import { getResults, str, seq, space } from "tarsec";
|
|
23
23
|
|
|
24
24
|
// define a parser
|
|
25
25
|
const parser = seq([
|
|
26
26
|
str("hello"),
|
|
27
27
|
space,
|
|
28
28
|
str("world")
|
|
29
|
-
]);
|
|
29
|
+
], getResults);
|
|
30
30
|
|
|
31
31
|
// then use it
|
|
32
32
|
parser("hello world"); // success
|
|
@@ -55,12 +55,12 @@ const parser = seq([
|
|
|
55
55
|
*/
|
|
56
56
|
capture(many1WithJoin(noneOf("!")), "person"),
|
|
57
57
|
char("!"),
|
|
58
|
-
]);
|
|
58
|
+
], getCaptures);
|
|
59
59
|
|
|
60
60
|
// parse
|
|
61
|
-
const
|
|
61
|
+
const parsed = parser("hello adit!");
|
|
62
62
|
|
|
63
|
-
console.log(
|
|
64
|
-
console.log(result
|
|
63
|
+
console.log(parsed.success); // true
|
|
64
|
+
console.log(parsed.result); // { person: "adit" }
|
|
65
65
|
```
|
|
66
66
|
|
package/dist/combinators.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { Parser } from "./types";
|
|
1
|
+
import { CaptureParser, GeneralParser, MergedCaptures, MergedResults, Parser, Prettify } from "./types";
|
|
2
2
|
export declare function many<T>(parser: Parser<T>): Parser<T[]>;
|
|
3
3
|
export declare function many1<T>(parser: Parser<T>): Parser<T[]>;
|
|
4
|
+
export declare function count<T>(parser: Parser<T>): Parser<number>;
|
|
4
5
|
export declare function manyWithJoin(parser: Parser<string>): Parser<string>;
|
|
5
6
|
export declare function many1WithJoin(parser: Parser<string>): Parser<string>;
|
|
6
|
-
export declare function or<T>(parsers:
|
|
7
|
+
export declare function or<const T extends readonly Parser<any>[]>(parsers: T, name?: string): Parser<MergedResults<T>>;
|
|
7
8
|
export declare function optional<T>(parser: Parser<T>): Parser<T | null>;
|
|
8
9
|
export declare function not(parser: Parser<any>): Parser<null>;
|
|
9
10
|
export declare function between<O, C, P>(open: Parser<O>, close: Parser<C>, parser: Parser<P>): Parser<P>;
|
|
10
11
|
export declare function sepBy<S, P>(separator: Parser<S>, parser: Parser<P>): Parser<P[]>;
|
|
11
|
-
export declare function
|
|
12
|
-
export declare function
|
|
13
|
-
export declare function
|
|
14
|
-
export declare function
|
|
12
|
+
export declare function getResults<R, C>(results: R, captures: C): R;
|
|
13
|
+
export declare function getCaptures<R, C>(results: R, captures: C): C;
|
|
14
|
+
export declare function seq<const T extends readonly GeneralParser<any, any>[], U>(parsers: T, transform: (results: MergedResults<T>[], captures: MergedCaptures<T>) => U, debugName?: string): Parser<U>;
|
|
15
|
+
export declare function capture<T, const S extends string>(parser: Parser<T>, name: S): CaptureParser<T, Record<S, T>>;
|
|
16
|
+
export declare function wrap<T, const S extends string>(parser: Parser<T>, name: S): Parser<Prettify<Record<S, T>>>;
|
|
15
17
|
export declare function transform<T, X>(parser: Parser<T>, transformerFunc: (x: T) => X): Parser<X>;
|
package/dist/combinators.js
CHANGED
|
@@ -4,25 +4,26 @@
|
|
|
4
4
|
if (v !== undefined) module.exports = v;
|
|
5
5
|
}
|
|
6
6
|
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "./trace", "./utils"], factory);
|
|
7
|
+
define(["require", "exports", "./trace", "./types", "./utils"], factory);
|
|
8
8
|
}
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.transform = exports.
|
|
12
|
+
exports.transform = exports.wrap = exports.capture = exports.seq = exports.getCaptures = exports.getResults = exports.sepBy = exports.between = exports.not = exports.optional = exports.or = exports.many1WithJoin = exports.manyWithJoin = exports.count = exports.many1 = exports.many = void 0;
|
|
13
13
|
const trace_1 = require("./trace");
|
|
14
|
+
const types_1 = require("./types");
|
|
14
15
|
const utils_1 = require("./utils");
|
|
15
16
|
function many(parser) {
|
|
16
17
|
return (0, trace_1.trace)("many", (input) => {
|
|
17
|
-
let
|
|
18
|
+
let results = [];
|
|
18
19
|
let rest = input;
|
|
19
20
|
while (true) {
|
|
20
|
-
let
|
|
21
|
-
if (!
|
|
22
|
-
return
|
|
21
|
+
let parsed = parser(rest);
|
|
22
|
+
if (!parsed.success) {
|
|
23
|
+
return (0, types_1.success)(results, rest);
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
rest =
|
|
25
|
+
results.push(parsed.result);
|
|
26
|
+
rest = parsed.rest;
|
|
26
27
|
}
|
|
27
28
|
});
|
|
28
29
|
}
|
|
@@ -42,6 +43,16 @@
|
|
|
42
43
|
});
|
|
43
44
|
}
|
|
44
45
|
exports.many1 = many1;
|
|
46
|
+
function count(parser) {
|
|
47
|
+
return (0, trace_1.trace)("count", (input) => {
|
|
48
|
+
const result = many(parser)(input);
|
|
49
|
+
if (result.success) {
|
|
50
|
+
return (0, types_1.success)(result.result.length, result.rest);
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
exports.count = count;
|
|
45
56
|
function manyWithJoin(parser) {
|
|
46
57
|
return transform(many(parser), (x) => x.join(""));
|
|
47
58
|
}
|
|
@@ -50,6 +61,10 @@
|
|
|
50
61
|
return transform(many1(parser), (x) => x.join(""));
|
|
51
62
|
}
|
|
52
63
|
exports.many1WithJoin = many1WithJoin;
|
|
64
|
+
/* seq<, U>(
|
|
65
|
+
parsers: T,
|
|
66
|
+
transform: (results: MergedResults<T>[], captures: MergedCaptures<T>) => U,
|
|
67
|
+
*/
|
|
53
68
|
function or(parsers, name = "") {
|
|
54
69
|
return (0, trace_1.trace)(`or(${name})`, (input) => {
|
|
55
70
|
for (let parser of parsers) {
|
|
@@ -58,11 +73,7 @@
|
|
|
58
73
|
return result;
|
|
59
74
|
}
|
|
60
75
|
}
|
|
61
|
-
return
|
|
62
|
-
success: false,
|
|
63
|
-
rest: input,
|
|
64
|
-
message: "all parsers failed",
|
|
65
|
-
};
|
|
76
|
+
return (0, types_1.failure)(`all parsers failed`, input);
|
|
66
77
|
});
|
|
67
78
|
}
|
|
68
79
|
exports.or = or;
|
|
@@ -72,7 +83,7 @@
|
|
|
72
83
|
if (result.success) {
|
|
73
84
|
return result;
|
|
74
85
|
}
|
|
75
|
-
return
|
|
86
|
+
return (0, types_1.success)(null, input);
|
|
76
87
|
});
|
|
77
88
|
}
|
|
78
89
|
exports.optional = optional;
|
|
@@ -86,7 +97,7 @@
|
|
|
86
97
|
message: "unexpected match",
|
|
87
98
|
};
|
|
88
99
|
}
|
|
89
|
-
return
|
|
100
|
+
return (0, types_1.success)(null, input);
|
|
90
101
|
});
|
|
91
102
|
}
|
|
92
103
|
exports.not = not;
|
|
@@ -104,95 +115,157 @@
|
|
|
104
115
|
if (!result2.success) {
|
|
105
116
|
return result2;
|
|
106
117
|
}
|
|
107
|
-
return
|
|
118
|
+
return (0, types_1.success)(parserResult.result, result2.rest);
|
|
108
119
|
};
|
|
109
120
|
}
|
|
110
121
|
exports.between = between;
|
|
111
122
|
function sepBy(separator, parser) {
|
|
112
123
|
return (input) => {
|
|
113
|
-
let
|
|
124
|
+
let results = [];
|
|
114
125
|
let rest = input;
|
|
115
126
|
while (true) {
|
|
116
127
|
const result = parser(rest);
|
|
117
128
|
if (!result.success) {
|
|
118
|
-
return
|
|
129
|
+
return (0, types_1.success)(results, rest);
|
|
119
130
|
}
|
|
120
|
-
|
|
131
|
+
results.push(result.result);
|
|
121
132
|
rest = result.rest;
|
|
122
133
|
const sepResult = separator(rest);
|
|
123
134
|
if (!sepResult.success) {
|
|
124
|
-
return
|
|
135
|
+
return (0, types_1.success)(results, rest);
|
|
125
136
|
}
|
|
126
137
|
rest = sepResult.rest;
|
|
127
138
|
}
|
|
128
139
|
};
|
|
129
140
|
}
|
|
130
141
|
exports.sepBy = sepBy;
|
|
131
|
-
function
|
|
132
|
-
return
|
|
133
|
-
|
|
142
|
+
function getResults(results, captures) {
|
|
143
|
+
return results;
|
|
144
|
+
}
|
|
145
|
+
exports.getResults = getResults;
|
|
146
|
+
function getCaptures(results, captures) {
|
|
147
|
+
return captures;
|
|
148
|
+
}
|
|
149
|
+
exports.getCaptures = getCaptures;
|
|
150
|
+
function seq(parsers, transform, debugName = "") {
|
|
151
|
+
return (0, trace_1.trace)(`seq(${debugName})`, (input) => {
|
|
152
|
+
const results = [];
|
|
134
153
|
let rest = input;
|
|
135
|
-
|
|
136
|
-
let captures = {};
|
|
154
|
+
const captures = {};
|
|
137
155
|
for (let parser of parsers) {
|
|
138
|
-
let
|
|
139
|
-
if (!
|
|
140
|
-
return
|
|
156
|
+
let parsed = parser(rest);
|
|
157
|
+
if (!parsed.success) {
|
|
158
|
+
return parsed;
|
|
141
159
|
}
|
|
142
|
-
|
|
143
|
-
rest =
|
|
144
|
-
if (
|
|
145
|
-
|
|
160
|
+
results.push(parsed.result);
|
|
161
|
+
rest = parsed.rest;
|
|
162
|
+
if ((0, types_1.isCaptureResult)(parsed)) {
|
|
163
|
+
for (const key in parsed.captures) {
|
|
164
|
+
captures[key] = parsed.captures[key];
|
|
165
|
+
}
|
|
146
166
|
}
|
|
147
167
|
}
|
|
148
|
-
|
|
168
|
+
const result = transform(results, captures);
|
|
169
|
+
return (0, types_1.success)(result, rest);
|
|
149
170
|
});
|
|
150
171
|
}
|
|
151
172
|
exports.seq = seq;
|
|
152
173
|
function capture(parser, name) {
|
|
153
|
-
return (0, trace_1.trace)(`
|
|
174
|
+
return (0, trace_1.trace)(`capture(${(0, utils_1.escape)(name)})`, (input) => {
|
|
154
175
|
let result = parser(input);
|
|
155
176
|
if (result.success) {
|
|
156
177
|
const captures = {
|
|
157
|
-
[name]: result.
|
|
178
|
+
[name]: result.result,
|
|
158
179
|
};
|
|
159
|
-
return Object.assign(Object.assign({}, result), { captures
|
|
180
|
+
return Object.assign(Object.assign({}, result), { captures });
|
|
160
181
|
}
|
|
161
182
|
return result;
|
|
162
183
|
});
|
|
163
184
|
}
|
|
164
185
|
exports.capture = capture;
|
|
165
|
-
function
|
|
166
|
-
return (0, trace_1.trace)(`
|
|
186
|
+
function wrap(parser, name) {
|
|
187
|
+
return (0, trace_1.trace)(`capture(${(0, utils_1.escape)(name)})`, (input) => {
|
|
167
188
|
let result = parser(input);
|
|
168
189
|
if (result.success) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return Object.assign(Object.assign({}, result), { captures: (0, utils_1.mergeCaptures)(result.captures || {}, captures) });
|
|
190
|
+
return Object.assign(Object.assign({}, result), { result: {
|
|
191
|
+
[name]: result.result,
|
|
192
|
+
} });
|
|
173
193
|
}
|
|
174
194
|
return result;
|
|
175
195
|
});
|
|
176
196
|
}
|
|
177
|
-
exports.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
197
|
+
exports.wrap = wrap;
|
|
198
|
+
/*
|
|
199
|
+
export function setCapturesAsMatch<M, C extends PlainObject>(
|
|
200
|
+
parser: Parser<M, C>
|
|
201
|
+
): Parser<C> {
|
|
202
|
+
return trace(`setCapturesAsMatch`, (input: string) => {
|
|
203
|
+
let result = parser(input);
|
|
204
|
+
if (result.success) {
|
|
205
|
+
return {
|
|
206
|
+
...result,
|
|
207
|
+
match: result.captures as any,
|
|
208
|
+
captures: {},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function captureCaptures<
|
|
216
|
+
M,
|
|
217
|
+
C extends PlainObject,
|
|
218
|
+
const S extends string
|
|
219
|
+
>(parser: Parser<M, C>, name: S): Parser<C, Record<S, C>> {
|
|
220
|
+
return trace(`captureCaptures(${escape(name)})`, (input: string) => {
|
|
221
|
+
return capture(setCapturesAsMatch(parser), name)(input);
|
|
222
|
+
});
|
|
223
|
+
} */
|
|
224
|
+
/* export function captureCaptures<M, C extends string>(
|
|
225
|
+
parser: Parser<M>,
|
|
226
|
+
name: string
|
|
227
|
+
): Parser<M, C> {
|
|
228
|
+
return trace(`captures(${escape(name)})`, (input: string) => {
|
|
229
|
+
let result = parser(input);
|
|
230
|
+
if (result.success) {
|
|
231
|
+
const captures: Record<string, any> = {
|
|
232
|
+
[name]: result.captures,
|
|
233
|
+
};
|
|
234
|
+
return {
|
|
235
|
+
...result,
|
|
236
|
+
captures: mergeCaptures(result.captures || {}, captures),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
return result;
|
|
240
|
+
});
|
|
187
241
|
}
|
|
188
|
-
|
|
242
|
+
|
|
243
|
+
*/
|
|
244
|
+
/* export function shapeCaptures<M, C extends string>(
|
|
245
|
+
parser: Parser<M>,
|
|
246
|
+
func: (captures: Record<string, any>) => Record<string, any>,
|
|
247
|
+
name: string
|
|
248
|
+
): Parser<M, C> {
|
|
249
|
+
return trace(`captures(${escape(name)})`, (input: string) => {
|
|
250
|
+
let result = parser(input);
|
|
251
|
+
if (result.success) {
|
|
252
|
+
const captures: Record<string, any> = result.captures || {};
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
...result,
|
|
256
|
+
captures: func(captures),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return result;
|
|
260
|
+
});
|
|
261
|
+
} */
|
|
189
262
|
function transform(parser, transformerFunc) {
|
|
190
263
|
return (0, trace_1.trace)(`transform(${transformerFunc})`, (input) => {
|
|
191
|
-
let
|
|
192
|
-
if (
|
|
193
|
-
return Object.assign(Object.assign({},
|
|
264
|
+
let parsed = parser(input);
|
|
265
|
+
if (parsed.success) {
|
|
266
|
+
return Object.assign(Object.assign({}, parsed), { result: transformerFunc(parsed.result) });
|
|
194
267
|
}
|
|
195
|
-
return
|
|
268
|
+
return parsed;
|
|
196
269
|
});
|
|
197
270
|
}
|
|
198
271
|
exports.transform = transform;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CaptureParser, GeneralParser, MergedCaptures, MergedResults, Parser, Prettify } from "./types";
|
|
2
|
+
export declare function many<T>(parser: Parser<T>): Parser<T[]>;
|
|
3
|
+
export declare function many1<T>(parser: Parser<T>): Parser<T[]>;
|
|
4
|
+
export declare function count<T>(parser: Parser<T>): Parser<number>;
|
|
5
|
+
export declare function manyWithJoin(parser: Parser<string>): Parser<string>;
|
|
6
|
+
export declare function many1WithJoin(parser: Parser<string>): Parser<string>;
|
|
7
|
+
export declare function or<const T extends readonly Parser<any>[]>(parsers: T, name?: string): Parser<MergedResults<T>>;
|
|
8
|
+
export declare function optional<T>(parser: Parser<T>): Parser<T | null>;
|
|
9
|
+
export declare function not(parser: Parser<any>): Parser<null>;
|
|
10
|
+
export declare function between<O, C, P>(open: Parser<O>, close: Parser<C>, parser: Parser<P>): Parser<P>;
|
|
11
|
+
export declare function sepBy<S, P>(separator: Parser<S>, parser: Parser<P>): Parser<P[]>;
|
|
12
|
+
export declare function getResults<R, C>(results: R, captures: C): R;
|
|
13
|
+
export declare function getCaptures<R, C>(results: R, captures: C): C;
|
|
14
|
+
export declare function seq<const T extends readonly GeneralParser<any, any>[], U>(parsers: T, transform: (results: MergedResults<T>[], captures: MergedCaptures<T>) => U, debugName?: string): Parser<U>;
|
|
15
|
+
export declare function capture<T, const S extends string>(parser: Parser<T>, name: S): CaptureParser<T, Record<S, T>>;
|
|
16
|
+
export declare function wrap<T, const S extends string>(parser: Parser<T>, name: S): Parser<Prettify<Record<S, T>>>;
|
|
17
|
+
export declare function transform<T, X>(parser: Parser<T>, transformerFunc: (x: T) => X): Parser<X>;
|
|
@@ -0,0 +1,272 @@
|
|
|
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", "./utils"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.transform = exports.wrap = exports.capture = exports.seq = exports.getCaptures = exports.getResults = exports.sepBy = exports.between = exports.not = exports.optional = exports.or = exports.many1WithJoin = exports.manyWithJoin = exports.count = exports.many1 = exports.many = void 0;
|
|
13
|
+
const trace_1 = require("./trace");
|
|
14
|
+
const types_1 = require("./types");
|
|
15
|
+
const utils_1 = require("./utils");
|
|
16
|
+
function many(parser) {
|
|
17
|
+
return (0, trace_1.trace)("many", (input) => {
|
|
18
|
+
let results = [];
|
|
19
|
+
let rest = input;
|
|
20
|
+
while (true) {
|
|
21
|
+
let parsed = parser(rest);
|
|
22
|
+
if (!parsed.success) {
|
|
23
|
+
return (0, types_1.success)(results, rest);
|
|
24
|
+
}
|
|
25
|
+
results.push(parsed.result);
|
|
26
|
+
rest = parsed.rest;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
exports.many = many;
|
|
31
|
+
function many1(parser) {
|
|
32
|
+
return (0, trace_1.trace)(`many1`, (input) => {
|
|
33
|
+
let result = many(parser)(input);
|
|
34
|
+
// this logic doesn't work with optional and not
|
|
35
|
+
if (result.rest !== input) {
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
success: false,
|
|
40
|
+
rest: input,
|
|
41
|
+
message: "expected at least one match",
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
exports.many1 = many1;
|
|
46
|
+
function count(parser) {
|
|
47
|
+
return (0, trace_1.trace)("count", (input) => {
|
|
48
|
+
const result = many(parser)(input);
|
|
49
|
+
if (result.success) {
|
|
50
|
+
return (0, types_1.success)(result.result.length, result.rest);
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
exports.count = count;
|
|
56
|
+
function manyWithJoin(parser) {
|
|
57
|
+
return transform(many(parser), (x) => x.join(""));
|
|
58
|
+
}
|
|
59
|
+
exports.manyWithJoin = manyWithJoin;
|
|
60
|
+
function many1WithJoin(parser) {
|
|
61
|
+
return transform(many1(parser), (x) => x.join(""));
|
|
62
|
+
}
|
|
63
|
+
exports.many1WithJoin = many1WithJoin;
|
|
64
|
+
/* seq<, U>(
|
|
65
|
+
parsers: T,
|
|
66
|
+
transform: (results: MergedResults<T>[], captures: MergedCaptures<T>) => U,
|
|
67
|
+
*/
|
|
68
|
+
function or(parsers, name = "") {
|
|
69
|
+
return (0, trace_1.trace)(`or(${name})`, (input) => {
|
|
70
|
+
for (let parser of parsers) {
|
|
71
|
+
let result = parser(input);
|
|
72
|
+
if (result.success) {
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return (0, types_1.failure)(`all parsers failed`, input);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
exports.or = or;
|
|
80
|
+
function optional(parser) {
|
|
81
|
+
return (0, trace_1.trace)("optional", (input) => {
|
|
82
|
+
let result = parser(input);
|
|
83
|
+
if (result.success) {
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
return (0, types_1.success)(null, input);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
exports.optional = optional;
|
|
90
|
+
function not(parser) {
|
|
91
|
+
return (0, trace_1.trace)("not", (input) => {
|
|
92
|
+
let result = parser(input);
|
|
93
|
+
if (result.success) {
|
|
94
|
+
return {
|
|
95
|
+
success: false,
|
|
96
|
+
rest: input,
|
|
97
|
+
message: "unexpected match",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return (0, types_1.success)(null, input);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
exports.not = not;
|
|
104
|
+
function between(open, close, parser) {
|
|
105
|
+
return (input) => {
|
|
106
|
+
const result1 = open(input);
|
|
107
|
+
if (!result1.success) {
|
|
108
|
+
return result1;
|
|
109
|
+
}
|
|
110
|
+
const parserResult = parser(result1.rest);
|
|
111
|
+
if (!parserResult.success) {
|
|
112
|
+
return parserResult;
|
|
113
|
+
}
|
|
114
|
+
const result2 = close(parserResult.rest);
|
|
115
|
+
if (!result2.success) {
|
|
116
|
+
return result2;
|
|
117
|
+
}
|
|
118
|
+
return (0, types_1.success)(parserResult.result, result2.rest);
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
exports.between = between;
|
|
122
|
+
function sepBy(separator, parser) {
|
|
123
|
+
return (input) => {
|
|
124
|
+
let results = [];
|
|
125
|
+
let rest = input;
|
|
126
|
+
while (true) {
|
|
127
|
+
const result = parser(rest);
|
|
128
|
+
if (!result.success) {
|
|
129
|
+
return (0, types_1.success)(results, rest);
|
|
130
|
+
}
|
|
131
|
+
results.push(result.result);
|
|
132
|
+
rest = result.rest;
|
|
133
|
+
const sepResult = separator(rest);
|
|
134
|
+
if (!sepResult.success) {
|
|
135
|
+
return (0, types_1.success)(results, rest);
|
|
136
|
+
}
|
|
137
|
+
rest = sepResult.rest;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
exports.sepBy = sepBy;
|
|
142
|
+
function getResults(results, captures) {
|
|
143
|
+
return results;
|
|
144
|
+
}
|
|
145
|
+
exports.getResults = getResults;
|
|
146
|
+
function getCaptures(results, captures) {
|
|
147
|
+
return captures;
|
|
148
|
+
}
|
|
149
|
+
exports.getCaptures = getCaptures;
|
|
150
|
+
function seq(parsers, transform, debugName = "") {
|
|
151
|
+
return (0, trace_1.trace)(`seq(${debugName})`, (input) => {
|
|
152
|
+
const results = [];
|
|
153
|
+
let rest = input;
|
|
154
|
+
const captures = {};
|
|
155
|
+
for (let parser of parsers) {
|
|
156
|
+
let parsed = parser(rest);
|
|
157
|
+
if (!parsed.success) {
|
|
158
|
+
return parsed;
|
|
159
|
+
}
|
|
160
|
+
results.push(parsed.result);
|
|
161
|
+
rest = parsed.rest;
|
|
162
|
+
if ((0, types_1.isCaptureResult)(parsed)) {
|
|
163
|
+
for (const key in parsed.captures) {
|
|
164
|
+
captures[key] = parsed.captures[key];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const result = transform(results, captures);
|
|
169
|
+
return (0, types_1.success)(result, rest);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
exports.seq = seq;
|
|
173
|
+
function capture(parser, name) {
|
|
174
|
+
return (0, trace_1.trace)(`capture(${(0, utils_1.escape)(name)})`, (input) => {
|
|
175
|
+
let result = parser(input);
|
|
176
|
+
if (result.success) {
|
|
177
|
+
const captures = {
|
|
178
|
+
[name]: result.result,
|
|
179
|
+
};
|
|
180
|
+
return Object.assign(Object.assign({}, result), { captures });
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
exports.capture = capture;
|
|
186
|
+
function wrap(parser, name) {
|
|
187
|
+
return (0, trace_1.trace)(`capture(${(0, utils_1.escape)(name)})`, (input) => {
|
|
188
|
+
let result = parser(input);
|
|
189
|
+
if (result.success) {
|
|
190
|
+
return Object.assign(Object.assign({}, result), { result: {
|
|
191
|
+
[name]: result.result,
|
|
192
|
+
} });
|
|
193
|
+
}
|
|
194
|
+
return result;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
exports.wrap = wrap;
|
|
198
|
+
/*
|
|
199
|
+
export function setCapturesAsMatch<M, C extends PlainObject>(
|
|
200
|
+
parser: Parser<M, C>
|
|
201
|
+
): Parser<C> {
|
|
202
|
+
return trace(`setCapturesAsMatch`, (input: string) => {
|
|
203
|
+
let result = parser(input);
|
|
204
|
+
if (result.success) {
|
|
205
|
+
return {
|
|
206
|
+
...result,
|
|
207
|
+
match: result.captures as any,
|
|
208
|
+
captures: {},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function captureCaptures<
|
|
216
|
+
M,
|
|
217
|
+
C extends PlainObject,
|
|
218
|
+
const S extends string
|
|
219
|
+
>(parser: Parser<M, C>, name: S): Parser<C, Record<S, C>> {
|
|
220
|
+
return trace(`captureCaptures(${escape(name)})`, (input: string) => {
|
|
221
|
+
return capture(setCapturesAsMatch(parser), name)(input);
|
|
222
|
+
});
|
|
223
|
+
} */
|
|
224
|
+
/* export function captureCaptures<M, C extends string>(
|
|
225
|
+
parser: Parser<M>,
|
|
226
|
+
name: string
|
|
227
|
+
): Parser<M, C> {
|
|
228
|
+
return trace(`captures(${escape(name)})`, (input: string) => {
|
|
229
|
+
let result = parser(input);
|
|
230
|
+
if (result.success) {
|
|
231
|
+
const captures: Record<string, any> = {
|
|
232
|
+
[name]: result.captures,
|
|
233
|
+
};
|
|
234
|
+
return {
|
|
235
|
+
...result,
|
|
236
|
+
captures: mergeCaptures(result.captures || {}, captures),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
return result;
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
*/
|
|
244
|
+
/* export function shapeCaptures<M, C extends string>(
|
|
245
|
+
parser: Parser<M>,
|
|
246
|
+
func: (captures: Record<string, any>) => Record<string, any>,
|
|
247
|
+
name: string
|
|
248
|
+
): Parser<M, C> {
|
|
249
|
+
return trace(`captures(${escape(name)})`, (input: string) => {
|
|
250
|
+
let result = parser(input);
|
|
251
|
+
if (result.success) {
|
|
252
|
+
const captures: Record<string, any> = result.captures || {};
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
...result,
|
|
256
|
+
captures: func(captures),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return result;
|
|
260
|
+
});
|
|
261
|
+
} */
|
|
262
|
+
function transform(parser, transformerFunc) {
|
|
263
|
+
return (0, trace_1.trace)(`transform(${transformerFunc})`, (input) => {
|
|
264
|
+
let parsed = parser(input);
|
|
265
|
+
if (parsed.success) {
|
|
266
|
+
return Object.assign(Object.assign({}, parsed), { result: transformerFunc(parsed.result) });
|
|
267
|
+
}
|
|
268
|
+
return parsed;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
exports.transform = transform;
|
|
272
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
2
|
+
if (k2 === undefined) k2 = k;
|
|
3
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
4
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
5
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
6
|
+
}
|
|
7
|
+
Object.defineProperty(o, k2, desc);
|
|
8
|
+
}) : (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
o[k2] = m[k];
|
|
11
|
+
}));
|
|
12
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
13
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
14
|
+
};
|
|
15
|
+
(function (factory) {
|
|
16
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
17
|
+
var v = factory(require, exports);
|
|
18
|
+
if (v !== undefined) module.exports = v;
|
|
19
|
+
}
|
|
20
|
+
else if (typeof define === "function" && define.amd) {
|
|
21
|
+
define(["require", "exports", "./parsers", "./combinators", "./trace"], factory);
|
|
22
|
+
}
|
|
23
|
+
})(function (require, exports) {
|
|
24
|
+
"use strict";
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
__exportStar(require("./parsers"), exports);
|
|
27
|
+
__exportStar(require("./combinators"), exports);
|
|
28
|
+
__exportStar(require("./trace"), exports);
|
|
29
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Parser } from "./types";
|
|
2
|
+
export declare function char(c: string): Parser<string>;
|
|
3
|
+
export declare function str(s: string): Parser<string>;
|
|
4
|
+
export declare function oneOf(chars: string): Parser<string>;
|
|
5
|
+
export declare function noneOf(chars: string): Parser<string>;
|
|
6
|
+
export declare function anyChar(input: string): Parser<string>;
|
|
7
|
+
export declare const space: Parser<string>;
|
|
8
|
+
export declare const spaces: Parser<string>;
|
|
9
|
+
export declare const digit: Parser<string>;
|
|
10
|
+
export declare const letter: Parser<string>;
|
|
11
|
+
export declare const alphanum: Parser<string>;
|
|
12
|
+
export declare const word: Parser<string>;
|
|
13
|
+
export declare const num: Parser<string>;
|
|
14
|
+
export declare const quote: Parser<string>;
|
|
15
|
+
export declare const tab: Parser<string>;
|
|
16
|
+
export declare const newline: Parser<string>;
|
|
17
|
+
export declare const quotedString: Parser<string>;
|
|
@@ -0,0 +1,87 @@
|
|
|
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", "./combinators", "./trace", "./types", "./utils"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.quotedString = 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 = void 0;
|
|
13
|
+
const combinators_1 = require("./combinators");
|
|
14
|
+
const trace_1 = require("./trace");
|
|
15
|
+
const types_1 = require("./types");
|
|
16
|
+
const utils_1 = require("./utils");
|
|
17
|
+
function char(c) {
|
|
18
|
+
return (0, trace_1.trace)(`char(${(0, utils_1.escape)(c)})`, (input) => {
|
|
19
|
+
if (input.length === 0) {
|
|
20
|
+
return {
|
|
21
|
+
success: false,
|
|
22
|
+
rest: input,
|
|
23
|
+
message: "unexpected end of input",
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (input[0] === c) {
|
|
27
|
+
return (0, types_1.success)(c, input.slice(1));
|
|
28
|
+
}
|
|
29
|
+
return (0, types_1.failure)(`expected ${c}, got ${input[0]}`, input);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
exports.char = char;
|
|
33
|
+
function str(s) {
|
|
34
|
+
return (0, trace_1.trace)(`str(${(0, utils_1.escape)(s)})`, (input) => {
|
|
35
|
+
if (input.substring(0, s.length) === s) {
|
|
36
|
+
return (0, types_1.success)(s, input.slice(s.length));
|
|
37
|
+
}
|
|
38
|
+
return (0, types_1.failure)(`expected ${s}, got ${input.substring(0, s.length)}`, input);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
exports.str = str;
|
|
42
|
+
function oneOf(chars) {
|
|
43
|
+
return (0, trace_1.trace)(`oneOf(${(0, utils_1.escape)(chars)})`, (input) => {
|
|
44
|
+
if (input.length === 0) {
|
|
45
|
+
return (0, types_1.failure)("unexpected end of input", input);
|
|
46
|
+
}
|
|
47
|
+
const c = input[0];
|
|
48
|
+
if (chars.includes(c)) {
|
|
49
|
+
return char(c)(input);
|
|
50
|
+
}
|
|
51
|
+
return (0, types_1.failure)(`expected one of ${(0, utils_1.escape)(chars)}, got ${c}`, input);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
exports.oneOf = oneOf;
|
|
55
|
+
function noneOf(chars) {
|
|
56
|
+
return (0, trace_1.trace)(`noneOf(${(0, utils_1.escape)(chars)})`, (input) => {
|
|
57
|
+
if (input.length === 0) {
|
|
58
|
+
return (0, types_1.failure)("unexpected end of input", input);
|
|
59
|
+
}
|
|
60
|
+
if (chars.includes(input[0])) {
|
|
61
|
+
return (0, types_1.failure)(`expected none of ${(0, utils_1.escape)(chars)}, got ${input[0]}`, input);
|
|
62
|
+
}
|
|
63
|
+
return char(input[0])(input);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
exports.noneOf = noneOf;
|
|
67
|
+
function anyChar(input) {
|
|
68
|
+
return (0, trace_1.trace)("anyChar", (input) => {
|
|
69
|
+
if (input.length === 0) {
|
|
70
|
+
return (0, types_1.failure)("unexpected end of input", input);
|
|
71
|
+
}
|
|
72
|
+
return { success: true, match: input[0], rest: input.slice(1) };
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
exports.anyChar = anyChar;
|
|
76
|
+
exports.space = oneOf(" \t\n\r");
|
|
77
|
+
exports.spaces = (0, combinators_1.many1WithJoin)(exports.space);
|
|
78
|
+
exports.digit = oneOf("0123456789");
|
|
79
|
+
exports.letter = oneOf("abcdefghijklmnopqrstuvwxyz");
|
|
80
|
+
exports.alphanum = oneOf("abcdefghijklmnopqrstuvwxyz0123456789");
|
|
81
|
+
exports.word = (0, combinators_1.many1WithJoin)(exports.letter);
|
|
82
|
+
exports.num = (0, combinators_1.many1WithJoin)(exports.digit);
|
|
83
|
+
exports.quote = oneOf(`'"`);
|
|
84
|
+
exports.tab = char("\t");
|
|
85
|
+
exports.newline = char("\n");
|
|
86
|
+
exports.quotedString = (0, combinators_1.transform)((0, combinators_1.seq)([exports.quote, exports.word, exports.quote], combinators_1.getResults), (x) => x.join(""));
|
|
87
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
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", "./utils"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.trace = exports.resultToString = void 0;
|
|
13
|
+
const utils_1 = require("./utils");
|
|
14
|
+
const STEP = 2;
|
|
15
|
+
function resultToString(name, result) {
|
|
16
|
+
if (result.success) {
|
|
17
|
+
return `✅ ${name} -- match: ${(0, utils_1.escape)(result.result)}, rest: ${(0, utils_1.escape)(result.rest)}`;
|
|
18
|
+
}
|
|
19
|
+
return `❌ ${name} -- message: ${(0, utils_1.escape)(result.message)}, rest: ${(0, utils_1.escape)(result.rest)}`;
|
|
20
|
+
}
|
|
21
|
+
exports.resultToString = resultToString;
|
|
22
|
+
let level = 0;
|
|
23
|
+
function trace(name, parser) {
|
|
24
|
+
return (input) => {
|
|
25
|
+
if (process.env.DEBUG) {
|
|
26
|
+
console.log(" ".repeat(level) + `🔍 ${name} -- input: ${(0, utils_1.escape)(input)}`);
|
|
27
|
+
}
|
|
28
|
+
level += STEP;
|
|
29
|
+
const result = parser(input);
|
|
30
|
+
level -= STEP;
|
|
31
|
+
if (process.env.DEBUG) {
|
|
32
|
+
console.log(" ".repeat(level) + resultToString(name, result));
|
|
33
|
+
if (result.success && result.captures) {
|
|
34
|
+
console.log(" ".repeat(level) +
|
|
35
|
+
`⭐ ${name} -- captures: ${JSON.stringify(result.captures)}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
exports.trace = trace;
|
|
42
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type PlainObject = Record<string, unknown>;
|
|
2
|
+
export type ParserSuccess<T> = {
|
|
3
|
+
success: true;
|
|
4
|
+
result: T;
|
|
5
|
+
rest: string;
|
|
6
|
+
};
|
|
7
|
+
export type CaptureParserSuccess<T, C extends PlainObject> = ParserSuccess<T> & {
|
|
8
|
+
captures: C;
|
|
9
|
+
};
|
|
10
|
+
export type ParserFailure = {
|
|
11
|
+
success: false;
|
|
12
|
+
rest: string;
|
|
13
|
+
message: string;
|
|
14
|
+
};
|
|
15
|
+
export type ParserResult<T> = ParserSuccess<T> | ParserFailure;
|
|
16
|
+
export type CaptureParserResult<T, C extends PlainObject> = CaptureParserSuccess<T, C> | ParserFailure;
|
|
17
|
+
export type Parser<T> = (input: string) => ParserResult<T>;
|
|
18
|
+
export type CaptureParser<T, C extends PlainObject> = (input: string) => CaptureParserResult<T, C>;
|
|
19
|
+
export type GeneralParser<T, C extends PlainObject> = Parser<T> | CaptureParser<T, C>;
|
|
20
|
+
export declare function isCaptureResult<T, C extends PlainObject>(result: ParserResult<T>): result is CaptureParserSuccess<T, C>;
|
|
21
|
+
export declare function success<T>(result: T, rest: string): ParserSuccess<T>;
|
|
22
|
+
export declare function captureSuccess<T, C extends PlainObject>(result: T, rest: string, captures: C): CaptureParserSuccess<T, C>;
|
|
23
|
+
export declare function failure(message: string, rest: string): ParserFailure;
|
|
24
|
+
export type Prettify<T> = {
|
|
25
|
+
[K in keyof T]: T[K];
|
|
26
|
+
} & {};
|
|
27
|
+
export type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
28
|
+
type ExtractResults<T> = T extends Parser<infer U> ? U : never;
|
|
29
|
+
type ExtractCaptures<T> = T extends CaptureParser<any, infer U> ? U : never;
|
|
30
|
+
type ExtractCaptureParsers<T extends readonly GeneralParser<any, any>[]> = Extract<T[number], CaptureParser<any, any>>;
|
|
31
|
+
export type MergedCaptures<T extends readonly GeneralParser<any, any>[]> = Prettify<UnionToIntersection<ExtractCaptures<ExtractCaptureParsers<T>>>>;
|
|
32
|
+
export type MergedResults<T extends readonly GeneralParser<any, any>[]> = ExtractResults<T[number]>;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
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"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.failure = exports.captureSuccess = exports.success = exports.isCaptureResult = void 0;
|
|
13
|
+
function isCaptureResult(result) {
|
|
14
|
+
return "captures" in result;
|
|
15
|
+
}
|
|
16
|
+
exports.isCaptureResult = isCaptureResult;
|
|
17
|
+
function success(result, rest) {
|
|
18
|
+
return { success: true, result, rest };
|
|
19
|
+
}
|
|
20
|
+
exports.success = success;
|
|
21
|
+
function captureSuccess(result, rest, captures) {
|
|
22
|
+
return { success: true, result, rest, captures };
|
|
23
|
+
}
|
|
24
|
+
exports.captureSuccess = captureSuccess;
|
|
25
|
+
function failure(message, rest) {
|
|
26
|
+
return { success: false, message, rest };
|
|
27
|
+
}
|
|
28
|
+
exports.failure = failure;
|
|
29
|
+
});
|
|
30
|
+
/* export type Merge2<O extends Array<T>, T = any> = Prettify<
|
|
31
|
+
UnionToIntersection<O[number]>
|
|
32
|
+
>;
|
|
33
|
+
|
|
34
|
+
export type NonNullObject<T> = {
|
|
35
|
+
[K in keyof T]: T[K] extends null | undefined ? never : T[K];
|
|
36
|
+
}; */
|
|
37
|
+
/* export type NonNullableUnionOfObjects<T> = T extends object
|
|
38
|
+
? RemoveNeverKeys<DeepNonNullable<T>>
|
|
39
|
+
: T;
|
|
40
|
+
|
|
41
|
+
export type DeepNonNullable<T> = {
|
|
42
|
+
[P in keyof T]-?: NonNullable<T[P]>;
|
|
43
|
+
}; */
|
|
44
|
+
/* export type FilterNeverKeys<T> = {
|
|
45
|
+
[K in keyof T]: T[K] extends never ? never : K;
|
|
46
|
+
};
|
|
47
|
+
*/
|
|
48
|
+
/* type ValueOf<T> = T[keyof T]; */
|
|
49
|
+
/* type RemoveNeverKeys<T> = Pick<T, ValueOf<FilterNeverKeys<T>>>; */
|
|
@@ -0,0 +1,48 @@
|
|
|
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"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.mergeCaptures = exports.merge = exports.escape = void 0;
|
|
13
|
+
function escape(str) {
|
|
14
|
+
return JSON.stringify(str);
|
|
15
|
+
}
|
|
16
|
+
exports.escape = escape;
|
|
17
|
+
function merge(a, b) {
|
|
18
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
19
|
+
return [...a, ...b];
|
|
20
|
+
}
|
|
21
|
+
else if (Array.isArray(a)) {
|
|
22
|
+
return [...a, b];
|
|
23
|
+
}
|
|
24
|
+
else if (Array.isArray(b)) {
|
|
25
|
+
return [a, ...b];
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return [a, b];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.merge = merge;
|
|
32
|
+
function mergeCaptures(a, b) {
|
|
33
|
+
const result = {};
|
|
34
|
+
Object.keys(a).forEach((key) => {
|
|
35
|
+
result[key] = a[key];
|
|
36
|
+
});
|
|
37
|
+
Object.keys(b).forEach((key) => {
|
|
38
|
+
if (result[key]) {
|
|
39
|
+
result[key] = merge(result[key], b[key]);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
result[key] = b[key];
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
exports.mergeCaptures = mergeCaptures;
|
|
48
|
+
});
|
package/dist/parsers.d.ts
CHANGED
|
@@ -14,4 +14,4 @@ export declare const num: Parser<string>;
|
|
|
14
14
|
export declare const quote: Parser<string>;
|
|
15
15
|
export declare const tab: Parser<string>;
|
|
16
16
|
export declare const newline: Parser<string>;
|
|
17
|
-
export declare const quotedString: Parser<string
|
|
17
|
+
export declare const quotedString: Parser<string>;
|
package/dist/parsers.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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", "./utils"], factory);
|
|
7
|
+
define(["require", "exports", "./combinators", "./trace", "./types", "./utils"], factory);
|
|
8
8
|
}
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
exports.quotedString = 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 = void 0;
|
|
13
13
|
const combinators_1 = require("./combinators");
|
|
14
14
|
const trace_1 = require("./trace");
|
|
15
|
+
const types_1 = require("./types");
|
|
15
16
|
const utils_1 = require("./utils");
|
|
16
17
|
function char(c) {
|
|
17
18
|
return (0, trace_1.trace)(`char(${(0, utils_1.escape)(c)})`, (input) => {
|
|
@@ -23,65 +24,41 @@
|
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
if (input[0] === c) {
|
|
26
|
-
return
|
|
27
|
+
return (0, types_1.success)(c, input.slice(1));
|
|
27
28
|
}
|
|
28
|
-
return {
|
|
29
|
-
success: false,
|
|
30
|
-
rest: input,
|
|
31
|
-
message: `expected ${c}, got ${input[0]}`,
|
|
32
|
-
};
|
|
29
|
+
return (0, types_1.failure)(`expected ${c}, got ${input[0]}`, input);
|
|
33
30
|
});
|
|
34
31
|
}
|
|
35
32
|
exports.char = char;
|
|
36
33
|
function str(s) {
|
|
37
34
|
return (0, trace_1.trace)(`str(${(0, utils_1.escape)(s)})`, (input) => {
|
|
38
35
|
if (input.substring(0, s.length) === s) {
|
|
39
|
-
return
|
|
36
|
+
return (0, types_1.success)(s, input.slice(s.length));
|
|
40
37
|
}
|
|
41
|
-
return {
|
|
42
|
-
success: false,
|
|
43
|
-
rest: input,
|
|
44
|
-
message: `expected ${s}, got ${input.substring(0, s.length)}`,
|
|
45
|
-
};
|
|
38
|
+
return (0, types_1.failure)(`expected ${s}, got ${input.substring(0, s.length)}`, input);
|
|
46
39
|
});
|
|
47
40
|
}
|
|
48
41
|
exports.str = str;
|
|
49
42
|
function oneOf(chars) {
|
|
50
43
|
return (0, trace_1.trace)(`oneOf(${(0, utils_1.escape)(chars)})`, (input) => {
|
|
51
44
|
if (input.length === 0) {
|
|
52
|
-
return
|
|
53
|
-
success: false,
|
|
54
|
-
rest: input,
|
|
55
|
-
message: "unexpected end of input",
|
|
56
|
-
};
|
|
45
|
+
return (0, types_1.failure)("unexpected end of input", input);
|
|
57
46
|
}
|
|
58
47
|
const c = input[0];
|
|
59
48
|
if (chars.includes(c)) {
|
|
60
49
|
return char(c)(input);
|
|
61
50
|
}
|
|
62
|
-
return {
|
|
63
|
-
success: false,
|
|
64
|
-
rest: input,
|
|
65
|
-
message: `expected one of ${(0, utils_1.escape)(chars)}, got ${c}`,
|
|
66
|
-
};
|
|
51
|
+
return (0, types_1.failure)(`expected one of ${(0, utils_1.escape)(chars)}, got ${c}`, input);
|
|
67
52
|
});
|
|
68
53
|
}
|
|
69
54
|
exports.oneOf = oneOf;
|
|
70
55
|
function noneOf(chars) {
|
|
71
56
|
return (0, trace_1.trace)(`noneOf(${(0, utils_1.escape)(chars)})`, (input) => {
|
|
72
57
|
if (input.length === 0) {
|
|
73
|
-
return
|
|
74
|
-
success: false,
|
|
75
|
-
rest: input,
|
|
76
|
-
message: "unexpected end of input",
|
|
77
|
-
};
|
|
58
|
+
return (0, types_1.failure)("unexpected end of input", input);
|
|
78
59
|
}
|
|
79
60
|
if (chars.includes(input[0])) {
|
|
80
|
-
return {
|
|
81
|
-
success: false,
|
|
82
|
-
rest: input,
|
|
83
|
-
message: `expected none of ${chars}`,
|
|
84
|
-
};
|
|
61
|
+
return (0, types_1.failure)(`expected none of ${(0, utils_1.escape)(chars)}, got ${input[0]}`, input);
|
|
85
62
|
}
|
|
86
63
|
return char(input[0])(input);
|
|
87
64
|
});
|
|
@@ -90,11 +67,7 @@
|
|
|
90
67
|
function anyChar(input) {
|
|
91
68
|
return (0, trace_1.trace)("anyChar", (input) => {
|
|
92
69
|
if (input.length === 0) {
|
|
93
|
-
return
|
|
94
|
-
success: false,
|
|
95
|
-
rest: input,
|
|
96
|
-
message: "unexpected end of input",
|
|
97
|
-
};
|
|
70
|
+
return (0, types_1.failure)("unexpected end of input", input);
|
|
98
71
|
}
|
|
99
72
|
return { success: true, match: input[0], rest: input.slice(1) };
|
|
100
73
|
});
|
|
@@ -110,5 +83,5 @@
|
|
|
110
83
|
exports.quote = oneOf(`'"`);
|
|
111
84
|
exports.tab = char("\t");
|
|
112
85
|
exports.newline = char("\n");
|
|
113
|
-
exports.quotedString = (0, combinators_1.transform)((0, combinators_1.seq)([exports.quote, exports.word, exports.quote],
|
|
86
|
+
exports.quotedString = (0, combinators_1.transform)((0, combinators_1.seq)([exports.quote, exports.word, exports.quote], combinators_1.getResults), (x) => x.join(""));
|
|
114
87
|
});
|
package/dist/trace.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { ParserResult
|
|
2
|
-
export declare function resultToString<T>(name: string, result: ParserResult<T
|
|
3
|
-
export declare function trace
|
|
1
|
+
import { ParserResult } from "./types";
|
|
2
|
+
export declare function resultToString<T>(name: string, result: ParserResult<T>): string;
|
|
3
|
+
export declare function trace(name: string, parser: any): any;
|
package/dist/trace.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
const STEP = 2;
|
|
15
15
|
function resultToString(name, result) {
|
|
16
16
|
if (result.success) {
|
|
17
|
-
return `✅ ${name} -- match: ${(0, utils_1.escape)(result.
|
|
17
|
+
return `✅ ${name} -- match: ${(0, utils_1.escape)(result.result)}, rest: ${(0, utils_1.escape)(result.rest)}`;
|
|
18
18
|
}
|
|
19
19
|
return `❌ ${name} -- message: ${(0, utils_1.escape)(result.message)}, rest: ${(0, utils_1.escape)(result.rest)}`;
|
|
20
20
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
|
-
export type
|
|
2
|
-
export type ParserSuccess<
|
|
1
|
+
export type PlainObject = Record<string, unknown>;
|
|
2
|
+
export type ParserSuccess<T> = {
|
|
3
3
|
success: true;
|
|
4
|
-
|
|
5
|
-
captures?: Record<C, any>;
|
|
4
|
+
result: T;
|
|
6
5
|
rest: string;
|
|
7
6
|
};
|
|
7
|
+
export type CaptureParserSuccess<T, C extends PlainObject> = ParserSuccess<T> & {
|
|
8
|
+
captures: C;
|
|
9
|
+
};
|
|
8
10
|
export type ParserFailure = {
|
|
9
11
|
success: false;
|
|
10
12
|
rest: string;
|
|
11
13
|
message: string;
|
|
12
14
|
};
|
|
13
|
-
export type
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export type
|
|
17
|
-
export type
|
|
15
|
+
export type ParserResult<T> = ParserSuccess<T> | ParserFailure;
|
|
16
|
+
export type CaptureParserResult<T, C extends PlainObject> = CaptureParserSuccess<T, C> | ParserFailure;
|
|
17
|
+
export type Parser<T> = (input: string) => ParserResult<T>;
|
|
18
|
+
export type CaptureParser<T, C extends PlainObject> = (input: string) => CaptureParserResult<T, C>;
|
|
19
|
+
export type GeneralParser<T, C extends PlainObject> = Parser<T> | CaptureParser<T, C>;
|
|
20
|
+
export declare function isCaptureResult<T, C extends PlainObject>(result: ParserResult<T>): result is CaptureParserSuccess<T, C>;
|
|
21
|
+
export declare function success<T>(result: T, rest: string): ParserSuccess<T>;
|
|
22
|
+
export declare function captureSuccess<T, C extends PlainObject>(result: T, rest: string, captures: C): CaptureParserSuccess<T, C>;
|
|
23
|
+
export declare function failure(message: string, rest: string): ParserFailure;
|
|
24
|
+
export type Prettify<T> = {
|
|
25
|
+
[K in keyof T]: T[K];
|
|
26
|
+
} & {};
|
|
27
|
+
export type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
28
|
+
type ExtractResults<T> = T extends Parser<infer U> ? U : never;
|
|
29
|
+
type ExtractCaptures<T> = T extends CaptureParser<any, infer U> ? U : never;
|
|
30
|
+
type ExtractCaptureParsers<T extends readonly GeneralParser<any, any>[]> = Extract<T[number], CaptureParser<any, any>>;
|
|
31
|
+
export type MergedCaptures<T extends readonly GeneralParser<any, any>[]> = Prettify<UnionToIntersection<ExtractCaptures<ExtractCaptureParsers<T>>>>;
|
|
32
|
+
export type MergedResults<T extends readonly GeneralParser<any, any>[]> = ExtractResults<T[number]>;
|
|
33
|
+
export {};
|
package/dist/types.js
CHANGED
|
@@ -9,4 +9,41 @@
|
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.failure = exports.captureSuccess = exports.success = exports.isCaptureResult = void 0;
|
|
13
|
+
function isCaptureResult(result) {
|
|
14
|
+
return "captures" in result;
|
|
15
|
+
}
|
|
16
|
+
exports.isCaptureResult = isCaptureResult;
|
|
17
|
+
function success(result, rest) {
|
|
18
|
+
return { success: true, result, rest };
|
|
19
|
+
}
|
|
20
|
+
exports.success = success;
|
|
21
|
+
function captureSuccess(result, rest, captures) {
|
|
22
|
+
return { success: true, result, rest, captures };
|
|
23
|
+
}
|
|
24
|
+
exports.captureSuccess = captureSuccess;
|
|
25
|
+
function failure(message, rest) {
|
|
26
|
+
return { success: false, message, rest };
|
|
27
|
+
}
|
|
28
|
+
exports.failure = failure;
|
|
12
29
|
});
|
|
30
|
+
/* export type Merge2<O extends Array<T>, T = any> = Prettify<
|
|
31
|
+
UnionToIntersection<O[number]>
|
|
32
|
+
>;
|
|
33
|
+
|
|
34
|
+
export type NonNullObject<T> = {
|
|
35
|
+
[K in keyof T]: T[K] extends null | undefined ? never : T[K];
|
|
36
|
+
}; */
|
|
37
|
+
/* export type NonNullableUnionOfObjects<T> = T extends object
|
|
38
|
+
? RemoveNeverKeys<DeepNonNullable<T>>
|
|
39
|
+
: T;
|
|
40
|
+
|
|
41
|
+
export type DeepNonNullable<T> = {
|
|
42
|
+
[P in keyof T]-?: NonNullable<T[P]>;
|
|
43
|
+
}; */
|
|
44
|
+
/* export type FilterNeverKeys<T> = {
|
|
45
|
+
[K in keyof T]: T[K] extends never ? never : K;
|
|
46
|
+
};
|
|
47
|
+
*/
|
|
48
|
+
/* type ValueOf<T> = T[keyof T]; */
|
|
49
|
+
/* type RemoveNeverKeys<T> = Pick<T, ValueOf<FilterNeverKeys<T>>>; */
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tarsec",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "A parser combinator library for TypeScript, inspired by Parsec.",
|
|
5
5
|
"homepage": "https://github.com/egonSchiele/tarsec",
|
|
6
|
-
|
|
7
6
|
"scripts": {
|
|
8
7
|
"test": "vitest",
|
|
9
8
|
"build": "tsc",
|
|
@@ -11,7 +10,7 @@
|
|
|
11
10
|
},
|
|
12
11
|
"files": [
|
|
13
12
|
"./dist"
|
|
14
|
-
],
|
|
13
|
+
],
|
|
15
14
|
"exports": {
|
|
16
15
|
".": {
|
|
17
16
|
"import": "./dist/index.js",
|
|
@@ -23,6 +22,7 @@
|
|
|
23
22
|
"license": "ISC",
|
|
24
23
|
"devDependencies": {
|
|
25
24
|
"@types/node": "^20.11.28",
|
|
25
|
+
"typescript": "^5.4.2",
|
|
26
26
|
"vitest": "^1.4.0"
|
|
27
27
|
}
|
|
28
28
|
}
|