tarsec 0.0.20 → 0.0.22

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.
@@ -15,7 +15,7 @@ import { escape, findAncestorWithNextParser, popMany } from "./utils.js";
15
15
  * and returns the result as an array
16
16
  */
17
17
  export function many(parser) {
18
- return trace("many", (input) => {
18
+ const _parser = (input) => {
19
19
  let results = [];
20
20
  let captures = [];
21
21
  let rest = input;
@@ -44,7 +44,8 @@ export function many(parser) {
44
44
  }
45
45
  }
46
46
  }
47
- });
47
+ };
48
+ return trace("many", _parser);
48
49
  }
49
50
  /**
50
51
  * Same as `many`, but fails if the parser doesn't match at least once.
@@ -392,13 +393,14 @@ export function capture(parser, name) {
392
393
  * @returns - the parser's result set as the captures object
393
394
  */
394
395
  export function captureCaptures(parser) {
395
- return trace(`captureCaptures()`, (input) => {
396
+ const _parser = (input) => {
396
397
  let result = parser(input);
397
398
  if (result.success) {
398
399
  return Object.assign(Object.assign({}, result), { captures: result.result });
399
400
  }
400
401
  return result;
401
- });
402
+ };
403
+ return trace(`captureCaptures()`, _parser);
402
404
  }
403
405
  /**
404
406
  * Returns a parser that consumes input till the given parser succeeds.
@@ -545,7 +547,7 @@ export function search(parser) {
545
547
  .join(" ");
546
548
  return success(result, rest);
547
549
  }
548
- return success("", input);
550
+ return success([], input);
549
551
  });
550
552
  }
551
553
  /*
package/dist/parsers.d.ts CHANGED
@@ -43,7 +43,7 @@ export declare function noneOf(chars: string): Parser<string>;
43
43
  * @param input - input string
44
44
  * @returns - ParserResult
45
45
  */
46
- export declare const anyChar: any;
46
+ export declare const anyChar: Parser<string>;
47
47
  /** A parser that matches one of " \t\n\r". */
48
48
  export declare const space: Parser<string>;
49
49
  /** A parser that matches one or more spaces. */
package/dist/parsers.js CHANGED
@@ -175,7 +175,7 @@ export function captureRegex(str, options = "", ...captureNames) {
175
175
  else {
176
176
  re = str;
177
177
  }
178
- return trace(`captureRegex(${str})`, (input) => {
178
+ const _parser = (input) => {
179
179
  const match = input.match(re);
180
180
  if (match) {
181
181
  if (match.slice(1).length > captureNames.length) {
@@ -188,7 +188,8 @@ export function captureRegex(str, options = "", ...captureNames) {
188
188
  return success(captures, input.slice(match[0].length));
189
189
  }
190
190
  return failure(`expected ${str}, got ${input.slice(0, 10)}`, input);
191
- });
191
+ };
192
+ return trace(`captureRegex(${str})`, _parser);
192
193
  }
193
194
  /**
194
195
  * Return a parser that takes a key and a value.
package/dist/trace.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { ParserResult } from "./types.js";
1
+ import { ParserResult, Parser, PlainObject, CaptureParser } from "./types.js";
2
2
  /**
3
3
  * This function is used internally by the `trace` function to create the string for each step.
4
4
  * @param name - debug name for parser
5
5
  * @param result - parser result
6
6
  * @returns - A formatted string that describes the parser's result
7
- */
7
+ */
8
8
  export declare function resultToString<T>(name: string, result: ParserResult<T>): string;
9
9
  /**
10
10
  * This function is used internally with debug mode. Given a parser and a debug name for it,
@@ -61,7 +61,21 @@ export declare function resultToString<T>(name: string, result: ParserResult<T>)
61
61
  * @param parser - parser to run
62
62
  * @returns
63
63
  */
64
- export declare function trace(name: string, parser: any): any;
64
+ export declare function trace<T, C extends PlainObject>(name: string, parser: CaptureParser<T, C>): CaptureParser<T, C>;
65
+ export declare function trace<T>(name: string, parser: Parser<T>): Parser<T>;
66
+ /**
67
+ * Useful for adding debugging messages to your parsers.
68
+ * Use `getDebugMessages` to get all the messages,
69
+ * or `getDebugMessage` to get the last message,
70
+ * if your parser fails.
71
+ *
72
+ * @param parser - a parser
73
+ * @param message - the message to show if the parser fails
74
+ */
75
+ export declare function debug<T, C extends PlainObject>(parser: CaptureParser<T, C>, message: string): CaptureParser<T, C>;
76
+ export declare function debug<T>(parser: Parser<T>, message: string): Parser<T>;
77
+ export declare function getDebugMessages(): string[];
78
+ export declare function getDebugMessage(): string;
65
79
  /**
66
80
  * Utility timing function. Given a callback, it times the callback
67
81
  * and returns its runtime in milliseconds. It uses `performance.now()` to do this.
package/dist/trace.js CHANGED
@@ -4,79 +4,25 @@ const isNode = typeof process !== "undefined" &&
4
4
  process.versions != null &&
5
5
  process.versions.node != null;
6
6
  const STEP = 2;
7
+ let level = 0;
8
+ let counts = {};
9
+ let times = {};
10
+ let debugFlag = isNode ? !!process.env.DEBUG : false;
11
+ let stepCount = 0;
12
+ let stepLimit = -1;
13
+ let debugMessages = [];
7
14
  /**
8
15
  * This function is used internally by the `trace` function to create the string for each step.
9
16
  * @param name - debug name for parser
10
17
  * @param result - parser result
11
18
  * @returns - A formatted string that describes the parser's result
12
- */
19
+ */
13
20
  export function resultToString(name, result) {
14
21
  if (result.success) {
15
22
  return `✅ ${name} -- match: ${escape(result.result)}, rest: ${escape(result.rest)}`;
16
23
  }
17
24
  return `❌ ${name} -- message: ${escape(result.message)}, rest: ${escape(result.rest)}`;
18
25
  }
19
- let level = 0;
20
- let counts = {};
21
- let times = {};
22
- let debugFlag = isNode ? !!process.env.DEBUG : false;
23
- let stepCount = 0;
24
- let stepLimit = -1;
25
- /**
26
- * This function is used internally with debug mode. Given a parser and a debug name for it,
27
- * when the parser is called, `trace` will:
28
- * 1. Print a line when the parser starts
29
- * 2. print a line when the parser ends, indicating success or failure.
30
- * 3. If the parser returns any captures, print the captures.
31
- * 4. Count the number of times this parser has been run.
32
- * 5. Track the total time this parser has taken.
33
- * 6. Track the total number of steps your parser has taken (a step equals one parser invocation).
34
- * So, for example, you may find out that your parser to parse Markdown has taken 50 steps to parse that file.
35
- *
36
- * All this happens only if debug mode is on, which you can turn on by using `parserDebug`, or setting the env var `DEBUG` to `1`.
37
- *
38
- * Caveat: If you have debug mode on through an environment variable, `trace` will capture counts and times
39
- * for all parsers across your entire application. If you want to profile just a particular section of code, use `parserDebug` instead.
40
- * If you *do* want to track constant times for all parsers, don't use `parserDebug` as it will reset those.
41
- *
42
- *
43
- * `trace` works with tarsec's built-in parsers out of the box. You can easily set it up to work with your custom parser too.
44
- *
45
- * For example, if your parser looks like this:
46
- *
47
- * ```ts
48
- * const myParser = (input:string) => {
49
- * if (input === "hello") {
50
- * return { success: true, result: "hello", rest: "" };
51
- * }
52
- * return { success: false, message: "expected hello", rest: input };
53
- * }
54
- * ```
55
- *
56
- * You can wrap it in `trace` like this:
57
- *
58
- * ```ts
59
- * const myParser = trace("myParser", (input:string) => {
60
- * if (input === "hello") {
61
- * return { success: true, result: "hello", rest: "" };
62
- * }
63
- * return { success: false, message: "expected hello", rest: input };
64
- * });
65
- * ```
66
- *
67
- * Now, when you run `myParser("hello")` with debug mode on,
68
- * you will see the debug output.
69
- *
70
- * Some parsers, like `seq`, are very general. You might have a few parser that use `seq`.
71
- * So when you see `seq` debug output, you might not know which `seq` parser that means.
72
- * ou can pass `seq` a debug name as an optional third argument to be used in the debug output.
73
- * This name is used to track count and time, so using this name will also mean this `seq` parser's
74
- * count and time are tracked separately from the other `seq` parsers, which might be useful.
75
- *
76
- * @param name - debug name for parser
77
- * @param parser - parser to run
78
- * @returns
79
- */
80
26
  export function trace(name, parser) {
81
27
  if (stepLimit > 0 && stepCount > stepLimit) {
82
28
  throw new Error(`parser step limit of ${stepLimit} exceeded, parser may be in an infinite loop`);
@@ -107,6 +53,24 @@ export function trace(name, parser) {
107
53
  }
108
54
  };
109
55
  }
56
+ export function debug(parser, message) {
57
+ return (input) => {
58
+ const result = parser(input);
59
+ if (result.success) {
60
+ return result;
61
+ }
62
+ else {
63
+ debugMessages.push(`${message} -- ${resultToString("", result)}`);
64
+ return result;
65
+ }
66
+ };
67
+ }
68
+ export function getDebugMessages() {
69
+ return debugMessages;
70
+ }
71
+ export function getDebugMessage() {
72
+ return debugMessages[debugMessages.length - 1];
73
+ }
110
74
  /**
111
75
  * Utility timing function. Given a callback, it times the callback
112
76
  * and returns its runtime in milliseconds. It uses `performance.now()` to do this.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tarsec",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "description": "A parser combinator library for TypeScript, inspired by Parsec.",
5
5
  "homepage": "https://github.com/egonSchiele/tarsec",
6
6
  "scripts": {
@@ -38,4 +38,4 @@
38
38
  "typescript": "^5.4.2",
39
39
  "vitest": "^1.4.0"
40
40
  }
41
- }
41
+ }