tarsec 0.0.18 → 0.0.20

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 CHANGED
@@ -19,14 +19,14 @@ npm install tarsec
19
19
  ## Hello world
20
20
 
21
21
  ```ts
22
- import { getResults, str, seq, space } from "tarsec";
22
+ import { str, seqR, space } from "tarsec";
23
23
 
24
24
  // define a parser
25
- const parser = seq([
25
+ const parser = seqR(
26
26
  str("hello"),
27
27
  space,
28
28
  str("world")
29
- ], getResults);
29
+ );
30
30
 
31
31
  // then use it
32
32
  parser("hello world"); // success
@@ -140,6 +140,87 @@ export declare function getCaptures<R, C>(results: R, captures: C): C;
140
140
  * @returns - the results of the parser, with the captures object attached.
141
141
  */
142
142
  export declare function capture<T, const S extends string>(parser: Parser<T>, name: S): CaptureParser<T, Record<S, T>>;
143
+ /**
144
+ * `captureCaptures` lifts your captures up a level. Suppose you have a parser like this:
145
+ *
146
+ * ```ts
147
+ * const greeting = seqC(
148
+ * str("hello"),
149
+ * spaces,
150
+ * capture(word, "name"),
151
+ * str("!"),
152
+ * spaces,
153
+ * capture(manynTillStr("?"), "secondPart")
154
+ * )
155
+ *
156
+ * This parses a greeting like "hello Adit! How was your day?" into:
157
+ *
158
+ * ```ts
159
+ * {
160
+ * name: "Adit",
161
+ * secondPart: "How was your day?"
162
+ * }
163
+ * ```
164
+ *
165
+ * Now, suppose you decide to refactor this parser into two parsers:
166
+ *
167
+ * ```ts
168
+ * const firstPart = seqC(
169
+ * str("hello"),
170
+ * spaces,
171
+ * capture(word, "name"),
172
+ * str("!")
173
+ * )
174
+ *
175
+ * const secondPart = seqC(
176
+ * spaces,
177
+ * capture(manyTillStr("?"), "secondPart")
178
+ * )
179
+ * ```
180
+ *
181
+ * And put them together:
182
+ *
183
+ * ```ts
184
+ * const greeting = seqC(
185
+ * firstPart,
186
+ * secondPart
187
+ * )
188
+ * ```
189
+ *
190
+ * Unfortunately, this will no longer return an object in that shape,
191
+ * because it's not actually capturing anything. Captures in `firstPart`
192
+ * and `secondPart` won't get propagated up. Suppose you try to use `capture` like this:
193
+ * ```ts
194
+ * const greeting = seqC(
195
+ * capture(firstPart, "firstPart"),
196
+ * capture(secondPart, "secondPart")
197
+ * )
198
+ * ```
199
+ * Now you'll get an object that looks like this instead:
200
+ *
201
+ * ```ts
202
+ * {
203
+ * firstPart: {
204
+ * name: "Adit"
205
+ * },
206
+ * secondPart: {
207
+ * secondPart: "How was your day?"
208
+ * }
209
+ * }
210
+ * ```
211
+ *
212
+ * What you want is for the captures in the child parsers to get merged up to the parent parser. For that, use `captureCaptures`:
213
+ *
214
+ * ```ts
215
+ * const greeting = seqC(
216
+ * captureCaptures(firstPart),
217
+ * captureCaptures(secondPart)
218
+ * )
219
+ * ```
220
+ * @param parser - parser to capture captures from
221
+ * @returns - the parser's result set as the captures object
222
+ */
223
+ export declare function captureCaptures<T extends PlainObject>(parser: Parser<T>): CaptureParser<T, T>;
143
224
  /**
144
225
  * Returns a parser that consumes input till the given parser succeeds.
145
226
  * @param parser - the stop parser
@@ -311,6 +311,95 @@ export function capture(parser, name) {
311
311
  return result;
312
312
  });
313
313
  }
314
+ /**
315
+ * `captureCaptures` lifts your captures up a level. Suppose you have a parser like this:
316
+ *
317
+ * ```ts
318
+ * const greeting = seqC(
319
+ * str("hello"),
320
+ * spaces,
321
+ * capture(word, "name"),
322
+ * str("!"),
323
+ * spaces,
324
+ * capture(manynTillStr("?"), "secondPart")
325
+ * )
326
+ *
327
+ * This parses a greeting like "hello Adit! How was your day?" into:
328
+ *
329
+ * ```ts
330
+ * {
331
+ * name: "Adit",
332
+ * secondPart: "How was your day?"
333
+ * }
334
+ * ```
335
+ *
336
+ * Now, suppose you decide to refactor this parser into two parsers:
337
+ *
338
+ * ```ts
339
+ * const firstPart = seqC(
340
+ * str("hello"),
341
+ * spaces,
342
+ * capture(word, "name"),
343
+ * str("!")
344
+ * )
345
+ *
346
+ * const secondPart = seqC(
347
+ * spaces,
348
+ * capture(manyTillStr("?"), "secondPart")
349
+ * )
350
+ * ```
351
+ *
352
+ * And put them together:
353
+ *
354
+ * ```ts
355
+ * const greeting = seqC(
356
+ * firstPart,
357
+ * secondPart
358
+ * )
359
+ * ```
360
+ *
361
+ * Unfortunately, this will no longer return an object in that shape,
362
+ * because it's not actually capturing anything. Captures in `firstPart`
363
+ * and `secondPart` won't get propagated up. Suppose you try to use `capture` like this:
364
+ * ```ts
365
+ * const greeting = seqC(
366
+ * capture(firstPart, "firstPart"),
367
+ * capture(secondPart, "secondPart")
368
+ * )
369
+ * ```
370
+ * Now you'll get an object that looks like this instead:
371
+ *
372
+ * ```ts
373
+ * {
374
+ * firstPart: {
375
+ * name: "Adit"
376
+ * },
377
+ * secondPart: {
378
+ * secondPart: "How was your day?"
379
+ * }
380
+ * }
381
+ * ```
382
+ *
383
+ * What you want is for the captures in the child parsers to get merged up to the parent parser. For that, use `captureCaptures`:
384
+ *
385
+ * ```ts
386
+ * const greeting = seqC(
387
+ * captureCaptures(firstPart),
388
+ * captureCaptures(secondPart)
389
+ * )
390
+ * ```
391
+ * @param parser - parser to capture captures from
392
+ * @returns - the parser's result set as the captures object
393
+ */
394
+ export function captureCaptures(parser) {
395
+ return trace(`captureCaptures()`, (input) => {
396
+ let result = parser(input);
397
+ if (result.success) {
398
+ return Object.assign(Object.assign({}, result), { captures: result.result });
399
+ }
400
+ return result;
401
+ });
402
+ }
314
403
  /**
315
404
  * Returns a parser that consumes input till the given parser succeeds.
316
405
  * @param parser - the stop parser
package/dist/trace.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import { escape, round, shorten } from "./utils.js";
2
2
  import process from "process";
3
+ const isNode = typeof process !== "undefined" &&
4
+ process.versions != null &&
5
+ process.versions.node != null;
3
6
  const STEP = 2;
4
7
  /**
5
8
  * This function is used internally by the `trace` function to create the string for each step.
@@ -16,7 +19,7 @@ export function resultToString(name, result) {
16
19
  let level = 0;
17
20
  let counts = {};
18
21
  let times = {};
19
- let debugFlag = !!process.env.DEBUG;
22
+ let debugFlag = isNode ? !!process.env.DEBUG : false;
20
23
  let stepCount = 0;
21
24
  let stepLimit = -1;
22
25
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tarsec",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "A parser combinator library for TypeScript, inspired by Parsec.",
5
5
  "homepage": "https://github.com/egonSchiele/tarsec",
6
6
  "scripts": {
@@ -23,7 +23,11 @@
23
23
  },
24
24
  "type": "module",
25
25
  "types": "./dist/index.d.ts",
26
- "keywords": ["parser", "parser combinator", "parsec"],
26
+ "keywords": [
27
+ "parser",
28
+ "parser combinator",
29
+ "parsec"
30
+ ],
27
31
  "author": "",
28
32
  "license": "ISC",
29
33
  "devDependencies": {