@spakhm/ts-parsec 0.2.0 → 0.4.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.
- package/dist/base.d.ts +2 -2
- package/dist/base.d.ts.map +1 -1
- package/dist/index.js +49 -23
- package/dist/lib.d.ts +3 -2
- package/dist/lib.d.ts.map +1 -1
- package/dist/stream.d.ts +3 -2
- package/dist/stream.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/base.ts +32 -23
- package/src/lib.ts +4 -2
- package/src/stream.ts +39 -9
package/dist/base.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare function toParser<T extends string>(p: T): parser<T>;
|
|
|
22
22
|
export declare function toParser<T>(p: parserlike<T>): parser<T>;
|
|
23
23
|
export declare const str: <T extends string>(match: T) => parser<T>;
|
|
24
24
|
export declare const lex: <T>(p: parserlike<T>) => parser<T>;
|
|
25
|
-
export declare const
|
|
26
|
-
export declare const ws: parser<{}>;
|
|
25
|
+
export declare const lexMode: (wsMode: "keep_all" | "keep_newlines") => <T>(p: parserlike<T>) => parser<T>;
|
|
26
|
+
export declare const ws: (wsMode: "drop_all" | "keep_newlines") => parser<{}>;
|
|
27
27
|
export declare const fwd: <T>(thunk: (() => parserlike<T>)) => parser<T>;
|
|
28
28
|
//# sourceMappingURL=base.d.ts.map
|
package/dist/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAKvC,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,CAAC,CAAC;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,CAAC,CAAC;CAAE,CAAC;AAC9E,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;CAAE,CAAC;AAEtE,eAAO,MAAM,EAAE,GAAI,CAAC,EAAE,KAAK,CAAC,KAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAA2B,CAAC;AAC1E,eAAO,MAAM,GAAG,GAAI,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,CAAC,KAAK,EAAE,YAAY,CAC3C,CAAC;AAK5C,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AACtE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG;IACpC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;CAC9C,CAAC;AACF,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AAK7D,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AA6BzD,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,CAAC,CAQpD,CAAC;AAEN,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAKvC,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,CAAC,CAAC;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,CAAC,CAAC;CAAE,CAAC;AAC9E,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;CAAE,CAAC;AAEtE,eAAO,MAAM,EAAE,GAAI,CAAC,EAAE,KAAK,CAAC,KAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAA2B,CAAC;AAC1E,eAAO,MAAM,GAAG,GAAI,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,CAAC,KAAK,EAAE,YAAY,CAC3C,CAAC;AAK5C,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AACtE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG;IACpC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;CAC9C,CAAC;AACF,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AAK7D,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AA6BzD,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,CAAC,CAQpD,CAAC;AAEN,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,cAUrC,CAAC;AAEH,eAAO,MAAM,OAAO,GAAI,QAAQ,UAAU,GAAG,eAAe,MACzD,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,cAOhB,CAAC;AAEP,eAAO,MAAM,EAAE,GAAI,QAAQ,UAAU,GAAG,eAAe,eAqBnD,CAAC;AAKL,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,CAAC,CACL,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -30,32 +30,35 @@ var str = (match) => lex(toParser((source) => {
|
|
|
30
30
|
return ok(match);
|
|
31
31
|
}));
|
|
32
32
|
var lex = (p) => toParser((source) => {
|
|
33
|
-
if (
|
|
33
|
+
if (source.ws_mode === "keep_all") {
|
|
34
34
|
return toParser(p)(source);
|
|
35
35
|
} else {
|
|
36
|
-
return
|
|
37
|
-
ws(source2);
|
|
36
|
+
return lexMode("keep_all")((source2) => {
|
|
37
|
+
ws("drop_all")(source2);
|
|
38
38
|
return toParser(p)(source2);
|
|
39
39
|
})(source);
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
|
-
var
|
|
43
|
-
const
|
|
44
|
-
source.
|
|
42
|
+
var lexMode = (wsMode) => (p) => toParser((source) => {
|
|
43
|
+
const prev_ws_mode = source.ws_mode;
|
|
44
|
+
source.ws_mode = wsMode;
|
|
45
45
|
const res = toParser(p)(source);
|
|
46
|
-
source.
|
|
46
|
+
source.ws_mode = prev_ws_mode;
|
|
47
47
|
return res;
|
|
48
48
|
});
|
|
49
|
-
var ws = toParser((source) => {
|
|
49
|
+
var ws = (wsMode) => toParser((source) => {
|
|
50
50
|
while (true) {
|
|
51
51
|
source.push();
|
|
52
52
|
const ch = source.next();
|
|
53
|
-
if (ch
|
|
54
|
-
source.
|
|
55
|
-
|
|
53
|
+
if (wsMode == "keep_newlines" && ch == "\n") {
|
|
54
|
+
source.pop_rollback();
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
if (ch === null || ch.trim() !== "") {
|
|
56
58
|
source.pop_rollback();
|
|
57
59
|
break;
|
|
58
60
|
}
|
|
61
|
+
source.pop_continue();
|
|
59
62
|
}
|
|
60
63
|
return ok({});
|
|
61
64
|
});
|
|
@@ -118,7 +121,7 @@ var many = (parser) => toParser((source) => {
|
|
|
118
121
|
});
|
|
119
122
|
var some = (parser) => seq(parser, many(parser)).map2((ft, rt) => [ft, ...rt]);
|
|
120
123
|
var digit = range("0", "9");
|
|
121
|
-
var nat = lex(some(digit)).map((val) =>
|
|
124
|
+
var nat = lex(some(digit)).map((val) => BigInt(val.join("")));
|
|
122
125
|
var maybe = (p) => toParser((source) => {
|
|
123
126
|
const res = attempt(p)(source);
|
|
124
127
|
return res.type == "ok" ? res : ok(null);
|
|
@@ -211,33 +214,55 @@ var anych = (opts) => toParser((source) => {
|
|
|
211
214
|
return res ? ok(res) : err(0, 0, "");
|
|
212
215
|
});
|
|
213
216
|
var eof = not(anych());
|
|
217
|
+
var eol = str("\n");
|
|
214
218
|
// src/stream.ts
|
|
215
219
|
class string_stream {
|
|
216
220
|
source;
|
|
217
|
-
|
|
221
|
+
ws_mode;
|
|
218
222
|
row = 1;
|
|
219
223
|
col = 1;
|
|
220
224
|
idx = 0;
|
|
221
225
|
stack = [];
|
|
222
|
-
constructor(source,
|
|
226
|
+
constructor(source, ws_mode = "drop_all") {
|
|
223
227
|
this.source = source;
|
|
224
|
-
this.
|
|
228
|
+
this.ws_mode = ws_mode;
|
|
225
229
|
}
|
|
226
230
|
next() {
|
|
227
231
|
if (this.idx == this.source.length) {
|
|
228
232
|
return null;
|
|
229
233
|
}
|
|
230
|
-
const ch = this.source[this.idx++];
|
|
231
|
-
this.col++;
|
|
234
|
+
const ch = this.normalizeNewline(this.source[this.idx++]);
|
|
232
235
|
if (ch == "\n") {
|
|
233
236
|
this.row++;
|
|
234
237
|
this.col = 1;
|
|
235
|
-
}
|
|
236
|
-
if (this.drop_ws && ch.trim() === "") {
|
|
237
|
-
return this.next();
|
|
238
238
|
} else {
|
|
239
|
+
this.col++;
|
|
240
|
+
}
|
|
241
|
+
if (this.ws_mode === "keep_all") {
|
|
239
242
|
return ch;
|
|
240
243
|
}
|
|
244
|
+
if (this.ws_mode === "drop_all" && ch.trim() === "") {
|
|
245
|
+
return this.next();
|
|
246
|
+
}
|
|
247
|
+
if (this.ws_mode === "keep_newlines") {
|
|
248
|
+
if (ch === "\n") {
|
|
249
|
+
return ch;
|
|
250
|
+
}
|
|
251
|
+
if (ch.trim() === "") {
|
|
252
|
+
return this.next();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return ch;
|
|
256
|
+
}
|
|
257
|
+
normalizeNewline(ch) {
|
|
258
|
+
const peek2 = () => this.idx == this.source.length ? null : this.source[this.idx];
|
|
259
|
+
if (ch == "\r") {
|
|
260
|
+
if (peek2() == "\n") {
|
|
261
|
+
this.idx++;
|
|
262
|
+
}
|
|
263
|
+
ch = "\n";
|
|
264
|
+
}
|
|
265
|
+
return ch;
|
|
241
266
|
}
|
|
242
267
|
push() {
|
|
243
268
|
this.stack.push({
|
|
@@ -256,8 +281,8 @@ class string_stream {
|
|
|
256
281
|
this.idx = x.idx;
|
|
257
282
|
}
|
|
258
283
|
}
|
|
259
|
-
var fromString = (source) => {
|
|
260
|
-
return new string_stream(source);
|
|
284
|
+
var fromString = (source, ws_mode = "drop_all") => {
|
|
285
|
+
return new string_stream(source, ws_mode);
|
|
261
286
|
};
|
|
262
287
|
export {
|
|
263
288
|
ws,
|
|
@@ -277,12 +302,13 @@ export {
|
|
|
277
302
|
maybe,
|
|
278
303
|
many,
|
|
279
304
|
lower,
|
|
305
|
+
lexMode,
|
|
280
306
|
lex,
|
|
281
|
-
keepWs,
|
|
282
307
|
int,
|
|
283
308
|
fwd,
|
|
284
309
|
fromString,
|
|
285
310
|
err,
|
|
311
|
+
eol,
|
|
286
312
|
eof,
|
|
287
313
|
either,
|
|
288
314
|
digit,
|
package/dist/lib.d.ts
CHANGED
|
@@ -9,9 +9,9 @@ export declare const seq: <Ts extends any[]>(...parsers: { [K in keyof Ts]: pars
|
|
|
9
9
|
export declare const many: <T>(parser: parserlike<T>) => parser<T[]>;
|
|
10
10
|
export declare const some: <T>(parser: parserlike<T>) => parser<T[]>;
|
|
11
11
|
export declare const digit: parser<string>;
|
|
12
|
-
export declare const nat: parser<
|
|
12
|
+
export declare const nat: parser<bigint>;
|
|
13
13
|
export declare const maybe: <T>(p: parserlike<T>) => parser<T | null>;
|
|
14
|
-
export declare const int: parser<
|
|
14
|
+
export declare const int: parser<bigint>;
|
|
15
15
|
export declare const lower: parser<string>;
|
|
16
16
|
export declare const upper: parser<string>;
|
|
17
17
|
export declare const alpha: parser<string>;
|
|
@@ -27,4 +27,5 @@ export declare const anych: (opts?: {
|
|
|
27
27
|
but: parserlike<unknown>;
|
|
28
28
|
}) => parser<string>;
|
|
29
29
|
export declare const eof: parser<null>;
|
|
30
|
+
export declare const eol: parser<"\n">;
|
|
30
31
|
//# sourceMappingURL=lib.d.ts.map
|
package/dist/lib.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGjD,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,QAAQ,UAAU,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,CAAC,CAUvD,CAAC;AAEL,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,CAAC,MAAM,CAM5D,CAAC;AAEL,eAAO,MAAM,MAAM,GAAI,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,SAAS,GAAG,CAAC,IAAI,MAAM,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAE,KAAG,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAS3G,CAAC;AAEL,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,GAAG,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG;IACpD,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;CACnD,CAAC;AAEF,eAAO,MAAM,GAAG,GAAI,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,SAAS,GAAG,CAAC,IAAI,MAAM,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAE,KAAG,UAAU,CAAC,EAAE,CAgBvG,CAAA;AAED,eAAO,MAAM,IAAI,GAAI,CAAC,EAAE,QAAQ,UAAU,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,CAAC,EAAE,CAatD,CAAC;AAEL,eAAO,MAAM,IAAI,GAAI,CAAC,EAAE,QAAQ,UAAU,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,CAAC,EAAE,CACD,CAAC;AAE1D,eAAO,MAAM,KAAK,gBAAkB,CAAC;AAErC,eAAO,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
|
package/dist/stream.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
export type ws_mode = 'keep_all' | 'drop_all' | 'keep_newlines';
|
|
1
2
|
export type stream = {
|
|
2
3
|
row: number;
|
|
3
4
|
col: number;
|
|
4
|
-
|
|
5
|
+
ws_mode: ws_mode;
|
|
5
6
|
next: () => string | null;
|
|
6
7
|
push: () => void;
|
|
7
8
|
pop_continue: () => void;
|
|
8
9
|
pop_rollback: () => void;
|
|
9
10
|
};
|
|
10
|
-
export declare const fromString: (source: string) => stream;
|
|
11
|
+
export declare const fromString: (source: string, ws_mode?: ws_mode) => stream;
|
|
11
12
|
//# sourceMappingURL=stream.d.ts.map
|
package/dist/stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,CAAC;AAEhE,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;AA+EF,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,EAAE,UAAS,OAAoB,KAAG,MAE1E,CAAA"}
|
package/package.json
CHANGED
package/src/base.ts
CHANGED
|
@@ -63,40 +63,49 @@ export const str = <T extends string>(match: T): parser<T> =>
|
|
|
63
63
|
}));
|
|
64
64
|
|
|
65
65
|
export const lex = <T>(p: parserlike<T>) => toParser((source: stream) => {
|
|
66
|
-
if (
|
|
67
|
-
//
|
|
68
|
-
// don't drop more whitespace
|
|
66
|
+
if (source.ws_mode === 'keep_all') {
|
|
67
|
+
// nested lex call, don't drop more whitespace
|
|
69
68
|
return toParser(p)(source);
|
|
70
69
|
} else {
|
|
71
|
-
return
|
|
72
|
-
ws(source);
|
|
70
|
+
return lexMode('keep_all')((source: stream) => {
|
|
71
|
+
ws('drop_all')(source); // lex always drops all ws including newlines
|
|
73
72
|
return toParser(p)(source);
|
|
74
73
|
})(source);
|
|
75
74
|
}
|
|
76
75
|
});
|
|
77
76
|
|
|
78
|
-
export const
|
|
77
|
+
export const lexMode = (wsMode: 'keep_all' | 'keep_newlines') =>
|
|
78
|
+
<T>(p: parserlike<T>) =>
|
|
79
|
+
toParser((source: stream) => {
|
|
80
|
+
const prev_ws_mode = source.ws_mode;
|
|
81
|
+
source.ws_mode = wsMode;
|
|
82
|
+
const res = toParser(p)(source);
|
|
83
|
+
source.ws_mode = prev_ws_mode;
|
|
84
|
+
return res;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
export const ws = (wsMode: 'drop_all' | 'keep_newlines') =>
|
|
79
88
|
toParser((source: stream) => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
while (true) {
|
|
90
|
+
source.push();
|
|
91
|
+
const ch = source.next();
|
|
92
|
+
|
|
93
|
+
// If we gotta keep newlines and we hit one, return it
|
|
94
|
+
if (wsMode == 'keep_newlines' && ch == '\n') {
|
|
95
|
+
source.pop_rollback();
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// If we hit eof or a non-whitespace character, return it
|
|
100
|
+
if (ch === null || ch.trim() !== '') {
|
|
101
|
+
source.pop_rollback();
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
86
104
|
|
|
87
|
-
export const ws = toParser((source: stream) => {
|
|
88
|
-
while (true) {
|
|
89
|
-
source.push();
|
|
90
|
-
const ch = source.next();
|
|
91
|
-
if (ch?.trim() === "") {
|
|
92
105
|
source.pop_continue();
|
|
93
|
-
} else {
|
|
94
|
-
source.pop_rollback();
|
|
95
|
-
break;
|
|
96
106
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
});
|
|
107
|
+
return ok({});
|
|
108
|
+
});
|
|
100
109
|
|
|
101
110
|
/*
|
|
102
111
|
Laziness helper
|
package/src/lib.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { stream } from './stream';
|
|
2
2
|
import type { parser, parserlike } from './base';
|
|
3
|
-
import { err, ok, toParser, lex } from './base';
|
|
3
|
+
import { err, ok, toParser, lex, str } from './base';
|
|
4
4
|
|
|
5
5
|
export const attempt = <T>(parser: parserlike<T>): parser<T> =>
|
|
6
6
|
toParser((source: stream) => {
|
|
@@ -76,7 +76,7 @@ export const some = <T>(parser: parserlike<T>): parser<T[]> =>
|
|
|
76
76
|
export const digit = range('0', '9');
|
|
77
77
|
|
|
78
78
|
export const nat = lex(some(digit)).map((val) =>
|
|
79
|
-
|
|
79
|
+
BigInt(val.join("")));
|
|
80
80
|
|
|
81
81
|
export const maybe = <T>(p: parserlike<T>) =>
|
|
82
82
|
toParser((source: stream) => {
|
|
@@ -198,3 +198,5 @@ export const anych = (opts?: { but: parserlike<unknown> }) => toParser((source:
|
|
|
198
198
|
});
|
|
199
199
|
|
|
200
200
|
export const eof = not(anych());
|
|
201
|
+
|
|
202
|
+
export const eol = str('\n');
|
package/src/stream.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
|
|
2
|
+
export type ws_mode = 'keep_all' | 'drop_all' | 'keep_newlines';
|
|
3
|
+
|
|
2
4
|
export type stream = {
|
|
3
5
|
row: number,
|
|
4
6
|
col: number,
|
|
5
|
-
|
|
7
|
+
ws_mode: ws_mode,
|
|
6
8
|
next: () => string | null,
|
|
7
9
|
push: () => void,
|
|
8
10
|
pop_continue: () => void,
|
|
@@ -20,24 +22,52 @@ class string_stream {
|
|
|
20
22
|
idx: number,
|
|
21
23
|
}[] = [];
|
|
22
24
|
|
|
23
|
-
constructor(public source: string, public
|
|
25
|
+
constructor(public source: string, public ws_mode: ws_mode = 'drop_all') {}
|
|
24
26
|
|
|
25
27
|
next(): string | null {
|
|
26
28
|
if (this.idx == this.source.length) {
|
|
27
29
|
return null;
|
|
28
30
|
}
|
|
29
|
-
|
|
30
|
-
this.
|
|
31
|
+
|
|
32
|
+
const ch = this.normalizeNewline(this.source[this.idx++]);
|
|
31
33
|
if (ch == '\n') {
|
|
32
34
|
this.row++;
|
|
33
35
|
this.col = 1;
|
|
36
|
+
} else {
|
|
37
|
+
this.col++;
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
if (this.
|
|
37
|
-
return this.next();
|
|
38
|
-
} else {
|
|
40
|
+
if (this.ws_mode === 'keep_all') {
|
|
39
41
|
return ch;
|
|
40
42
|
}
|
|
43
|
+
|
|
44
|
+
if (this.ws_mode === 'drop_all' && ch.trim() === '') {
|
|
45
|
+
return this.next();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (this.ws_mode === 'keep_newlines') {
|
|
49
|
+
if (ch === '\n') {
|
|
50
|
+
return ch;
|
|
51
|
+
}
|
|
52
|
+
if (ch.trim() === '') {
|
|
53
|
+
return this.next();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return ch;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private normalizeNewline(ch: string) {
|
|
61
|
+
const peek = () =>
|
|
62
|
+
this.idx == this.source.length ? null : this.source[this.idx];
|
|
63
|
+
|
|
64
|
+
if (ch == '\r') {
|
|
65
|
+
if (peek() == '\n') {
|
|
66
|
+
this.idx++;
|
|
67
|
+
}
|
|
68
|
+
ch = '\n';
|
|
69
|
+
}
|
|
70
|
+
return ch;
|
|
41
71
|
}
|
|
42
72
|
|
|
43
73
|
push() {
|
|
@@ -58,6 +88,6 @@ class string_stream {
|
|
|
58
88
|
}
|
|
59
89
|
}
|
|
60
90
|
|
|
61
|
-
export const fromString = (source: string): stream => {
|
|
62
|
-
return new string_stream(source);
|
|
91
|
+
export const fromString = (source: string, ws_mode: ws_mode = 'drop_all'): stream => {
|
|
92
|
+
return new string_stream(source, ws_mode);
|
|
63
93
|
}
|