@spakhm/ts-parsec 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/base.d.ts CHANGED
@@ -1,27 +1,28 @@
1
- import type { stream } from './stream';
2
- export declare type result<T, E> = {
3
- type: 'ok';
4
- res: T;
5
- } | {
6
- type: 'err';
7
- err: E;
8
- };
9
- export declare type parser_error = {
10
- row: number;
11
- col: number;
12
- msg: string;
13
- };
14
- export declare const ok: <T>(res: T) => result<T, never>;
15
- export declare const err: (row: number, col: number, msg: string) => result<never, parser_error>;
16
- export declare type parserFn<T> = (source: stream) => result<T, parser_error>;
17
- export declare type parser<T> = parserFn<T> & {
18
- map: <U>(fn: ((value: T) => U)) => parser<U>;
19
- };
20
- export declare type parserlike<T> = parserFn<T> | parser<T> | string;
21
- export declare function toParser<T extends string>(p: T): parser<T>;
22
- export declare function toParser<T>(p: parserlike<T>): parser<T>;
23
- export declare const str: <T extends string>(match: T) => parser<T>;
24
- export declare const lex: <T>(p: parserlike<T>) => parser<T>;
25
- export declare const keepWs: <T>(p: parserlike<T>) => parser<T>;
26
- export declare const ws: parser<{}>;
27
- export declare const fwd: <T>(thunk: () => parserlike<T>) => parser<T>;
1
+ import type { stream } from './stream';
2
+ export type result<T, E> = {
3
+ type: 'ok';
4
+ res: T;
5
+ } | {
6
+ type: 'err';
7
+ err: E;
8
+ };
9
+ export type parser_error = {
10
+ row: number;
11
+ col: number;
12
+ msg: string;
13
+ };
14
+ export declare const ok: <T>(res: T) => result<T, never>;
15
+ export declare const err: (row: number, col: number, msg: string) => result<never, parser_error>;
16
+ export type parserFn<T> = (source: stream) => result<T, parser_error>;
17
+ export type parser<T> = parserFn<T> & {
18
+ map: <U>(fn: ((value: T) => U)) => parser<U>;
19
+ };
20
+ export type parserlike<T> = parserFn<T> | parser<T> | string;
21
+ export declare function toParser<T extends string>(p: T): parser<T>;
22
+ export declare function toParser<T>(p: parserlike<T>): parser<T>;
23
+ export declare const str: <T extends string>(match: T) => parser<T>;
24
+ export declare const lex: <T>(p: parserlike<T>) => parser<T>;
25
+ export declare const keepWs: <T>(p: parserlike<T>) => parser<T>;
26
+ export declare const ws: parser<{}>;
27
+ export declare const fwd: <T>(thunk: (() => parserlike<T>)) => parser<T>;
28
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +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,cAWrC,CAAC;AAEH,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,cAOtC,CAAC;AAEL,eAAO,MAAM,EAAE,YAYb,CAAC;AAKH,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,CAAC,CACL,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export * from './base';
2
- export * from './lib';
3
- export * from './stream';
1
+ export * from './base';
2
+ export * from './lib';
3
+ export * from './stream';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,295 @@
1
-
2
- 'use strict'
3
-
4
- if (process.env.NODE_ENV === 'production') {
5
- module.exports = require('./ts-parsec.cjs.production.min.js')
6
- } else {
7
- module.exports = require('./ts-parsec.cjs.development.js')
1
+ // src/base.ts
2
+ var ok = (res) => ({ type: "ok", res });
3
+ var err = (row, col, msg) => ({ type: "err", err: { row, col, msg } });
4
+ function toParser(pl) {
5
+ if (typeof pl == "string") {
6
+ return str(pl);
7
+ }
8
+ if ("map" in pl) {
9
+ return pl;
10
+ }
11
+ const fn_ = pl;
12
+ fn_.map = (fnTransform) => {
13
+ return toParser((source) => {
14
+ const res = fn_(source);
15
+ if (res.type == "ok") {
16
+ return ok(fnTransform(res.res));
17
+ } else {
18
+ return res;
19
+ }
20
+ });
21
+ };
22
+ return fn_;
8
23
  }
24
+ var str = (match) => lex(toParser((source) => {
25
+ for (let i = 0;i < match.length; i++) {
26
+ if (source.next() != match[i]) {
27
+ return err(0, 0, "");
28
+ }
29
+ }
30
+ return ok(match);
31
+ }));
32
+ var lex = (p) => toParser((source) => {
33
+ if (!source.drop_ws) {
34
+ return toParser(p)(source);
35
+ } else {
36
+ return keepWs((source2) => {
37
+ ws(source2);
38
+ return toParser(p)(source2);
39
+ })(source);
40
+ }
41
+ });
42
+ var keepWs = (p) => toParser((source) => {
43
+ const prev_drop_ws = source.drop_ws;
44
+ source.drop_ws = false;
45
+ const res = toParser(p)(source);
46
+ source.drop_ws = prev_drop_ws;
47
+ return res;
48
+ });
49
+ var ws = toParser((source) => {
50
+ while (true) {
51
+ source.push();
52
+ const ch = source.next();
53
+ if (ch?.trim() === "") {
54
+ source.pop_continue();
55
+ } else {
56
+ source.pop_rollback();
57
+ break;
58
+ }
59
+ }
60
+ return ok({});
61
+ });
62
+ var fwd = (thunk) => toParser((source) => toParser(thunk())(source));
63
+ // src/lib.ts
64
+ var attempt = (parser) => toParser((source) => {
65
+ source.push();
66
+ const res = toParser(parser)(source);
67
+ if (res.type == "ok") {
68
+ source.pop_continue();
69
+ } else {
70
+ source.pop_rollback();
71
+ }
72
+ return res;
73
+ });
74
+ var range = (start, end) => toParser((source) => {
75
+ const next = source.next();
76
+ if (!next)
77
+ return err(0, 0, "");
78
+ if (next >= start[0] && next <= end[0])
79
+ return ok(next);
80
+ return err(0, 0, "");
81
+ });
82
+ var either = (...parsers) => toParser((source) => {
83
+ for (const parser of parsers) {
84
+ const res = attempt(parser)(source);
85
+ if (res.type == "ok") {
86
+ return res;
87
+ }
88
+ }
89
+ return err(0, 0, "");
90
+ });
91
+ var seq = (...parsers) => {
92
+ const p = toParser((source) => {
93
+ const res = [];
94
+ for (const parser of parsers) {
95
+ const res_ = toParser(parser)(source);
96
+ if (res_.type == "ok") {
97
+ res.push(res_.res);
98
+ } else {
99
+ return err(0, 0, "");
100
+ }
101
+ }
102
+ return ok(res);
103
+ });
104
+ p.map2 = (fn) => p.map((x) => fn(...x));
105
+ return p;
106
+ };
107
+ var many = (parser) => toParser((source) => {
108
+ const res = [];
109
+ while (true) {
110
+ const _res = attempt(parser)(source);
111
+ if (_res.type == "ok") {
112
+ res.push(_res.res);
113
+ } else {
114
+ break;
115
+ }
116
+ }
117
+ return ok(res);
118
+ });
119
+ var some = (parser) => seq(parser, many(parser)).map2((ft, rt) => [ft, ...rt]);
120
+ var digit = range("0", "9");
121
+ var nat = lex(some(digit)).map((val) => parseInt(val.join("")));
122
+ var maybe = (p) => toParser((source) => {
123
+ const res = attempt(p)(source);
124
+ return res.type == "ok" ? res : ok(null);
125
+ });
126
+ var int = seq(maybe(either("-", "+")), nat).map2((sign, val) => {
127
+ if (sign === "-") {
128
+ return -val;
129
+ } else {
130
+ return val;
131
+ }
132
+ });
133
+ var lower = range("a", "z");
134
+ var upper = range("A", "Z");
135
+ var alpha = either(lower, upper);
136
+ var alnum = either(alpha, digit);
137
+ var sepBy = (item, sep, trailingSep = "allow") => toParser((source) => {
138
+ const res = [];
139
+ const res_ = attempt(item)(source);
140
+ if (res_.type == "err") {
141
+ return ok(res);
142
+ } else {
143
+ res.push(res_.res);
144
+ }
145
+ while (true) {
146
+ const sepres_ = attempt(sep)(source);
147
+ if (sepres_.type == "err") {
148
+ return trailingSep === "require" ? err(0, 0, "") : ok(res);
149
+ }
150
+ const res_2 = attempt(item)(source);
151
+ if (res_2.type == "err") {
152
+ return trailingSep === "forbid" ? err(0, 0, "") : ok(res);
153
+ } else {
154
+ res.push(res_2.res);
155
+ }
156
+ }
157
+ });
158
+ var sepBy1 = (item, sep, trailingSep = "allow") => toParser((source) => {
159
+ const res = sepBy(item, sep, trailingSep)(source);
160
+ if (res.type == "err")
161
+ return res;
162
+ return res.res.length >= 1 ? res : err(0, 0, "");
163
+ });
164
+ function binop(operator, operand, makeNode) {
165
+ return toParser((source) => {
166
+ const p = seq(operand, many(seq(operator, operand))).map2((left, rights) => {
167
+ const acc = rights.reduce((acc2, [op, right]) => makeNode(op, acc2, right), left);
168
+ return acc;
169
+ });
170
+ return p(source);
171
+ });
172
+ }
173
+ function binopr(operator, operand, makeNode) {
174
+ return toParser((source) => {
175
+ const p = seq(operand, many(seq(operator, operand))).map2((left, rights) => {
176
+ if (rights.length === 0)
177
+ return left;
178
+ let acc = rights[rights.length - 1][1];
179
+ for (let i = rights.length - 2;i >= 0; i--) {
180
+ const [op, right] = rights[i];
181
+ acc = makeNode(op, right, acc);
182
+ }
183
+ return makeNode(rights[0][0], left, acc);
184
+ });
185
+ return p(source);
186
+ });
187
+ }
188
+ var noop = toParser((_) => ok(true));
189
+ var not = (p) => toParser((source) => {
190
+ const res = toParser(p)(source);
191
+ if (res.type == "ok") {
192
+ return err(0, 0, "");
193
+ } else {
194
+ return ok(null);
195
+ }
196
+ });
197
+ var peek = (p) => toParser((source) => {
198
+ source.push();
199
+ const res = toParser(p)(source);
200
+ source.pop_rollback();
201
+ return res;
202
+ });
203
+ var anych = (opts) => toParser((source) => {
204
+ if (opts?.but) {
205
+ const res2 = peek(opts.but)(source);
206
+ if (res2.type == "ok") {
207
+ return err(0, 0, "");
208
+ }
209
+ }
210
+ const res = source.next();
211
+ return res ? ok(res) : err(0, 0, "");
212
+ });
213
+ var eof = not(anych());
214
+ // src/stream.ts
215
+ class string_stream {
216
+ source;
217
+ drop_ws;
218
+ row = 1;
219
+ col = 1;
220
+ idx = 0;
221
+ stack = [];
222
+ constructor(source, drop_ws = true) {
223
+ this.source = source;
224
+ this.drop_ws = drop_ws;
225
+ }
226
+ next() {
227
+ if (this.idx == this.source.length) {
228
+ return null;
229
+ }
230
+ const ch = this.source[this.idx++];
231
+ this.col++;
232
+ if (ch == "\n") {
233
+ this.row++;
234
+ this.col = 1;
235
+ }
236
+ if (this.drop_ws && ch.trim() === "") {
237
+ return this.next();
238
+ } else {
239
+ return ch;
240
+ }
241
+ }
242
+ push() {
243
+ this.stack.push({
244
+ row: this.row,
245
+ col: this.col,
246
+ idx: this.idx
247
+ });
248
+ }
249
+ pop_continue() {
250
+ this.stack.pop();
251
+ }
252
+ pop_rollback() {
253
+ const x = this.stack.pop();
254
+ this.row = x.row;
255
+ this.col = x.col;
256
+ this.idx = x.idx;
257
+ }
258
+ }
259
+ var fromString = (source) => {
260
+ return new string_stream(source);
261
+ };
262
+ export {
263
+ ws,
264
+ upper,
265
+ toParser,
266
+ str,
267
+ some,
268
+ seq,
269
+ sepBy1,
270
+ sepBy,
271
+ range,
272
+ peek,
273
+ ok,
274
+ not,
275
+ noop,
276
+ nat,
277
+ maybe,
278
+ many,
279
+ lower,
280
+ lex,
281
+ keepWs,
282
+ int,
283
+ fwd,
284
+ fromString,
285
+ err,
286
+ eof,
287
+ either,
288
+ digit,
289
+ binopr,
290
+ binop,
291
+ attempt,
292
+ anych,
293
+ alpha,
294
+ alnum
295
+ };
package/dist/lib.d.ts CHANGED
@@ -1,25 +1,30 @@
1
- import type { parser, parserlike } from './base';
2
- export declare const attempt: <T>(parser: parserlike<T>) => parser<T>;
3
- export declare const range: (start: string, end: string) => parser<string>;
4
- export declare const either: <Ts extends any[]>(...parsers: { [K in keyof Ts]: parserlike<Ts[K]>; }) => parser<Ts[number]>;
5
- export declare type seq_parser<T extends any[]> = parser<T> & {
6
- map2: <U>(fn: ((...values: T) => U)) => parser<U>;
7
- };
8
- export declare const seq: <Ts extends any[]>(...parsers: { [K in keyof Ts]: parserlike<Ts[K]>; }) => seq_parser<Ts>;
9
- export declare const many: <T>(parser: parserlike<T>) => parser<T[]>;
10
- export declare const some: <T>(parser: parserlike<T>) => parser<T[]>;
11
- export declare const digit: parser<string>;
12
- export declare const nat: parser<number>;
13
- export declare const maybe: <T>(p: parserlike<T>) => parser<T | null>;
14
- export declare const int: parser<number>;
15
- export declare const lower: parser<string>;
16
- export declare const upper: parser<string>;
17
- export declare const alpha: parser<string>;
18
- export declare const alnum: parser<string>;
19
- export declare const sepBy: <T, U>(item: parserlike<T>, sep: parserlike<U>, allowTrailingSep?: boolean) => parser<T[]>;
20
- export declare function binop<O, D, N>(operator: parserlike<O>, operand: parserlike<D>, makeNode: (op: O, left: D | N, right: D) => N): parser<N | D>;
21
- export declare function binopr<O, D, N>(operator: parserlike<O>, operand: parserlike<D>, makeNode: (op: O, left: D, right: D | N) => N): parser<N | D>;
22
- export declare const noop: parser<boolean>;
23
- export declare const not: <T>(p: parserlike<T>) => parser<null>;
24
- export declare const peek: <T>(p: parserlike<T>) => parser<T>;
25
- export declare const anych: parser<string>;
1
+ import type { parser, parserlike } from './base';
2
+ export declare const attempt: <T>(parser: parserlike<T>) => parser<T>;
3
+ export declare const range: (start: string, end: string) => parser<string>;
4
+ export declare const either: <Ts extends any[]>(...parsers: { [K in keyof Ts]: parserlike<Ts[K]>; }) => parser<Ts[number]>;
5
+ export type seq_parser<T extends any[]> = parser<T> & {
6
+ map2: <U>(fn: ((...values: T) => U)) => parser<U>;
7
+ };
8
+ export declare const seq: <Ts extends any[]>(...parsers: { [K in keyof Ts]: parserlike<Ts[K]>; }) => seq_parser<Ts>;
9
+ export declare const many: <T>(parser: parserlike<T>) => parser<T[]>;
10
+ export declare const some: <T>(parser: parserlike<T>) => parser<T[]>;
11
+ export declare const digit: parser<string>;
12
+ export declare const nat: parser<number>;
13
+ export declare const maybe: <T>(p: parserlike<T>) => parser<T | null>;
14
+ export declare const int: parser<number>;
15
+ export declare const lower: parser<string>;
16
+ export declare const upper: parser<string>;
17
+ export declare const alpha: parser<string>;
18
+ export declare const alnum: parser<string>;
19
+ export declare const sepBy: <T, U>(item: parserlike<T>, sep: parserlike<U>, trailingSep?: "allow" | "forbid" | "require") => parser<T[]>;
20
+ export declare const sepBy1: <T, U>(item: parserlike<T>, sep: parserlike<U>, trailingSep?: "allow" | "forbid" | "require") => parser<T[]>;
21
+ export declare function binop<O, D, N>(operator: parserlike<O>, operand: parserlike<D>, makeNode: (op: O, left: D | N, right: D) => N): parser<N | D>;
22
+ export declare function binopr<O, D, N>(operator: parserlike<O>, operand: parserlike<D>, makeNode: (op: O, left: D, right: D | N) => N): parser<N | D>;
23
+ export declare const noop: parser<boolean>;
24
+ export declare const not: <T>(p: parserlike<T>) => parser<null>;
25
+ export declare const peek: <T>(p: parserlike<T>) => parser<T>;
26
+ export declare const anych: (opts?: {
27
+ but: parserlike<unknown>;
28
+ }) => parser<string>;
29
+ export declare const eof: parser<null>;
30
+ //# sourceMappingURL=lib.d.ts.map
@@ -0,0 +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,gBACS,CAAC;AAE1B,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,qBAIrC,CAAC;AAEL,eAAO,MAAM,GAAG,gBAMd,CAAC;AAEH,eAAO,MAAM,KAAK,gBAAkB,CAAC;AACrC,eAAO,MAAM,KAAK,gBAAkB,CAAC;AACrC,eAAO,MAAM,KAAK,gBAAuB,CAAC;AAC1C,eAAO,MAAM,KAAK,gBAAuB,CAAC;AAE1C,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,CAAC,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,cAAa,OAAO,GAAG,QAAQ,GAAG,SAAmB,KAAG,MAAM,CAAC,CAAC,EAAE,CAwBnI,CAAC;AAEL,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,CAAC,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,cAAa,OAAO,GAAG,QAAQ,GAAG,SAAmB,KAAG,MAAM,CAAC,CAAC,EAAE,CAKpI,CAAC;AAEL,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC3B,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,EACvB,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,EACtB,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,GAC5C,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CASf;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC5B,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,EACvB,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,EACtB,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAC5C,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAiBf;AAED,eAAO,MAAM,IAAI,iBAAoC,CAAC;AAEtD,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,iBAOrC,CAAC;AAEH,eAAO,MAAM,IAAI,GAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,cAKtC,CAAC;AAEH,eAAO,MAAM,KAAK,GAAI,OAAO;IAAE,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;CAAE,mBASvD,CAAC;AAEH,eAAO,MAAM,GAAG,cAAe,CAAC"}
package/dist/stream.d.ts CHANGED
@@ -1,10 +1,11 @@
1
- export declare type stream = {
2
- row: number;
3
- col: number;
4
- drop_ws: boolean;
5
- next: () => string | null;
6
- push: () => void;
7
- pop_continue: () => void;
8
- pop_rollback: () => void;
9
- };
10
- export declare const fromString: (source: string) => stream;
1
+ export type stream = {
2
+ row: number;
3
+ col: number;
4
+ drop_ws: boolean;
5
+ next: () => string | null;
6
+ push: () => void;
7
+ pop_continue: () => void;
8
+ pop_rollback: () => void;
9
+ };
10
+ export declare const fromString: (source: string) => stream;
11
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +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;AAmDF,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,KAAG,MAE3C,CAAA"}
package/package.json CHANGED
@@ -1 +1,27 @@
1
- {"version":"0.1.7","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","files":["dist","src"],"engines":{"node":">=10"},"scripts":{"start":"tsdx watch","build":"tsdx build","test":"tsdx test","lint":"tsdx lint","prepare":"tsdx build","size":"size-limit","analyze":"size-limit --why"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"prettier":{"printWidth":80,"semi":true,"singleQuote":true,"trailingComma":"es5"},"name":"@spakhm/ts-parsec","author":"Slava Akhmechet","module":"dist/ts-parsec.esm.js","size-limit":[{"path":"dist/ts-parsec.cjs.production.min.js","limit":"10 KB"},{"path":"dist/ts-parsec.esm.js","limit":"10 KB"}],"devDependencies":{"@size-limit/preset-small-lib":"^11.1.6","husky":"^9.1.6","size-limit":"^11.1.6","tsdx":"^0.14.1","tslib":"^2.7.0","typescript":"^3.9.10"}}
1
+ {
2
+ "name": "@spakhm/ts-parsec",
3
+ "version": "0.2.0",
4
+ "license": "MIT",
5
+ "author": "Slava Akhmechet",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "module": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "files": ["dist", "src"],
11
+ "scripts": {
12
+ "build": "bun build ./src/index.ts --outdir ./dist --target node && bun run build:types",
13
+ "build:types": "tsc --emitDeclarationOnly",
14
+ "test": "bun test",
15
+ "prepublishOnly": "bun run build"
16
+ },
17
+ "devDependencies": {
18
+ "@types/bun": "^1.1.14",
19
+ "typescript": "^5.7.2"
20
+ },
21
+ "prettier": {
22
+ "printWidth": 80,
23
+ "semi": true,
24
+ "singleQuote": true,
25
+ "trailingComma": "es5"
26
+ }
27
+ }
package/src/lib.ts CHANGED
@@ -97,7 +97,7 @@ export const upper = range('A', 'Z');
97
97
  export const alpha = either(lower, upper);
98
98
  export const alnum = either(alpha, digit);
99
99
 
100
- export const sepBy = <T, U>(item: parserlike<T>, sep: parserlike<U>, allowTrailingSep: boolean = true): parser<T[]> =>
100
+ export const sepBy = <T, U>(item: parserlike<T>, sep: parserlike<U>, trailingSep: 'allow' | 'forbid' | 'require' = 'allow'): parser<T[]> =>
101
101
  toParser((source: stream) => {
102
102
  const res: T[] = [];
103
103
 
@@ -111,18 +111,25 @@ export const sepBy = <T, U>(item: parserlike<T>, sep: parserlike<U>, allowTraili
111
111
  while (true) {
112
112
  const sepres_ = attempt(sep)(source);
113
113
  if (sepres_.type == 'err') {
114
- return ok(res);
114
+ return trailingSep === 'require' ? err(0, 0, '') : ok(res);
115
115
  }
116
-
116
+
117
117
  const res_ = attempt(item)(source);
118
118
  if (res_.type == 'err') {
119
- return allowTrailingSep ? ok(res) : err(0, 0, '');
119
+ return trailingSep === 'forbid' ? err(0, 0, '') : ok(res);
120
120
  } else {
121
121
  res.push(res_.res);
122
122
  }
123
123
  }
124
124
  });
125
125
 
126
+ export const sepBy1 = <T, U>(item: parserlike<T>, sep: parserlike<U>, trailingSep: 'allow' | 'forbid' | 'require' = 'allow'): parser<T[]> =>
127
+ toParser((source: stream) => {
128
+ const res = sepBy(item, sep, trailingSep)(source);
129
+ if (res.type == 'err') return res;
130
+ return res.res.length >= 1 ? res : err(0, 0, '');
131
+ });
132
+
126
133
  export function binop<O, D, N>(
127
134
  operator: parserlike<O>,
128
135
  operand: parserlike<D>,
@@ -179,7 +186,15 @@ export const peek = <T>(p: parserlike<T>) => toParser((source: stream) => {
179
186
  return res;
180
187
  });
181
188
 
182
- export const anych = toParser((source: stream) => {
189
+ export const anych = (opts?: { but: parserlike<unknown> }) => toParser((source: stream) => {
190
+ if (opts?.but) {
191
+ const res = peek(opts.but)(source);
192
+ if (res.type == 'ok') {
193
+ return err(0, 0, "");
194
+ }
195
+ }
183
196
  const res = source.next()
184
197
  return res ? ok(res) : err(0, 0, "");
185
198
  });
199
+
200
+ export const eof = not(anych());