@thi.ng/parse 2.4.9 → 2.4.11

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +1 -1
  3. package/api.js +0 -1
  4. package/combinators/alt.js +15 -21
  5. package/combinators/boundary.js +10 -4
  6. package/combinators/check.js +7 -4
  7. package/combinators/dynamic.js +8 -18
  8. package/combinators/expect.js +4 -1
  9. package/combinators/lookahead.js +17 -77
  10. package/combinators/maybe.js +4 -1
  11. package/combinators/not.js +10 -17
  12. package/combinators/repeat.js +26 -18
  13. package/combinators/seq.js +14 -10
  14. package/combinators/wrap.js +4 -1
  15. package/combinators/xform.js +16 -14
  16. package/context.js +134 -137
  17. package/error.js +6 -3
  18. package/grammar.js +241 -185
  19. package/package.json +12 -9
  20. package/presets/alpha.js +14 -17
  21. package/presets/bits.js +6 -2
  22. package/presets/digits.js +6 -8
  23. package/presets/escape.js +14 -11
  24. package/presets/hex.js +8 -13
  25. package/presets/numbers.js +12 -23
  26. package/presets/string.js +6 -1
  27. package/presets/whitespace.js +18 -32
  28. package/prims/always.js +6 -2
  29. package/prims/anchor.js +24 -21
  30. package/prims/fail.js +4 -1
  31. package/prims/lit.js +8 -19
  32. package/prims/none-of.js +10 -15
  33. package/prims/one-of.js +10 -14
  34. package/prims/pass.js +6 -12
  35. package/prims/range.js +18 -37
  36. package/prims/satisfy.js +17 -19
  37. package/prims/skip.js +13 -30
  38. package/prims/string.js +48 -43
  39. package/readers/array-reader.js +22 -20
  40. package/readers/string-reader.js +27 -26
  41. package/utils.js +4 -9
  42. package/xform/collect.js +9 -16
  43. package/xform/comp.js +19 -22
  44. package/xform/count.js +9 -16
  45. package/xform/discard.js +6 -10
  46. package/xform/hoist.js +15 -30
  47. package/xform/join.js +17 -24
  48. package/xform/json.js +8 -15
  49. package/xform/nest.js +21 -32
  50. package/xform/number.js +16 -36
  51. package/xform/print.js +21 -47
  52. package/xform/replace.js +9 -17
  53. package/xform/trim.js +8 -17
  54. package/xform/with-id.js +6 -8
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-12-09T19:12:03Z
3
+ - **Last updated**: 2023-12-18T13:41:20Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
package/README.md CHANGED
@@ -90,7 +90,7 @@ For Node.js REPL:
90
90
  const parse = await import("@thi.ng/parse");
91
91
  ```
92
92
 
93
- Package sizes (brotli'd, pre-treeshake): ESM: 5.23 KB
93
+ Package sizes (brotli'd, pre-treeshake): ESM: 5.21 KB
94
94
 
95
95
  ## Dependencies
96
96
 
package/api.js CHANGED
@@ -1 +0,0 @@
1
- export {};
@@ -1,25 +1,19 @@
1
1
  import { string } from "../prims/string.js";
2
2
  import { discard } from "../xform/discard.js";
3
- export const alt = (parsers) => (ctx) => {
4
- if (ctx.done)
5
- return false;
6
- for (let i = 0, n = parsers.length; i < n; i++) {
7
- if (parsers[i](ctx)) {
8
- return true;
9
- }
10
- }
3
+ const alt = (parsers) => (ctx) => {
4
+ if (ctx.done)
11
5
  return false;
6
+ for (let i = 0, n = parsers.length; i < n; i++) {
7
+ if (parsers[i](ctx)) {
8
+ return true;
9
+ }
10
+ }
11
+ return false;
12
+ };
13
+ const altS = (strings) => alt(strings.map((x) => string(x)));
14
+ const altD = (parsers) => discard(alt(parsers));
15
+ export {
16
+ alt,
17
+ altD,
18
+ altS
12
19
  };
13
- /**
14
- * Syntax sugar for {@link alt}. Takes an array of strings to match and creates
15
- * parsers for each before passing them to `alt()`.
16
- *
17
- * @param strings
18
- */
19
- export const altS = (strings) => alt(strings.map((x) => string(x)));
20
- /**
21
- * Wrapped version of {@link alt} which discards results if successful match.
22
- *
23
- * @param parsers
24
- */
25
- export const altD = (parsers) => discard(alt(parsers));
@@ -1,6 +1,12 @@
1
1
  import { inputEnd, inputStart, lineEnd, lineStart } from "../prims/anchor.js";
2
2
  import { seq } from "./seq.js";
3
- export const startsWith = (parser) => seq([inputStart, parser]);
4
- export const endsWith = (parser) => seq([parser, inputEnd]);
5
- export const entireLine = (parser) => seq([lineStart, parser, lineEnd]);
6
- export const entirely = (parser) => seq([inputStart, parser, inputEnd]);
3
+ const startsWith = (parser) => seq([inputStart, parser]);
4
+ const endsWith = (parser) => seq([parser, inputEnd]);
5
+ const entireLine = (parser) => seq([lineStart, parser, lineEnd]);
6
+ const entirely = (parser) => seq([inputStart, parser, inputEnd]);
7
+ export {
8
+ endsWith,
9
+ entireLine,
10
+ entirely,
11
+ startsWith
12
+ };
@@ -1,7 +1,10 @@
1
1
  import { parseError } from "../error.js";
2
2
  import { xform } from "./xform.js";
3
- export const check = (parser, pred, msg = "check failed") => xform(parser, (scope, ctx) => {
4
- if (!pred(scope))
5
- parseError(ctx, msg);
6
- return scope;
3
+ const check = (parser, pred, msg = "check failed") => xform(parser, (scope, ctx) => {
4
+ if (!pred(scope))
5
+ parseError(ctx, msg);
6
+ return scope;
7
7
  });
8
+ export {
9
+ check
10
+ };
@@ -1,19 +1,9 @@
1
- /**
2
- * Returns a parser function placeholder, whose implementation can be
3
- * set at a later stage via calling `.set()`.
4
- *
5
- * @examples
6
- * ```ts
7
- * const parser = dynamic<string>();
8
- * parser.set(lit("a"));
9
- *
10
- * parser(defContext("a"));
11
- * // true
12
- * ```
13
- */
14
- export const dynamic = () => {
15
- let impl;
16
- const wrapper = (ctx) => (impl ? impl(ctx) : false);
17
- wrapper.set = (p) => (impl = p);
18
- return wrapper;
1
+ const dynamic = () => {
2
+ let impl;
3
+ const wrapper = (ctx) => impl ? impl(ctx) : false;
4
+ wrapper.set = (p) => impl = p;
5
+ return wrapper;
6
+ };
7
+ export {
8
+ dynamic
19
9
  };
@@ -1,2 +1,5 @@
1
1
  import { parseError } from "../error.js";
2
- export const expect = (parser, err) => (ctx) => parser(ctx) || parseError(ctx, err);
2
+ const expect = (parser, err) => (ctx) => parser(ctx) || parseError(ctx, err);
3
+ export {
4
+ expect
5
+ };
@@ -1,79 +1,19 @@
1
- /**
2
- * Repeatedly runs `main` and look-`ahead` parsers for as long as the
3
- * former succeeds and UNTIL the latter passes or end of input is
4
- * reached. If the `ahead` parser never passes, the entire parser fails
5
- * and any partial matches are discarded.
6
- *
7
- * @remarks
8
- * Depending on `capture` (default: false), the result of the `ahead`
9
- * parser is captured or omitted and the final read position is adjusted
10
- * accordingly.
11
- *
12
- * Currently, iff `capture` is disabled, the `ahead` parser MUST discard
13
- * its own result (e.g. via {@link discard}). On successful match the
14
- * final read position will then be restored to the beginning of `ahead`
15
- * pattern.
16
- *
17
- * Iff `capture` is enabled, the `ahead` parser MAY discard its own
18
- * result, but the final read position will not be re-adjusted as in the
19
- * non-capturing version.
20
- *
21
- * **Important:** Since the main term will be repeated automatically, DO
22
- * NOT use repetition modifiers `?` or `*`, since both of these will
23
- * cause the parser to go into an infinite loop. This is expected
24
- * behavior and not a bug.
25
- *
26
- * @example
27
- * ```ts
28
- * const ctx = defContext("ababaaabbabba");
29
- *
30
- * // consume while 'a' or `b` and until 1st occurrence of "abba"...
31
- * // note the use of `stringD()` to discard lookahead result
32
- *
33
- * // non-capturing lookahead
34
- * join(lookahead(oneOf("ab"), stringD("abba")))(ctx)
35
- * // true
36
- *
37
- * ctx.result
38
- * // "ababaa"
39
- *
40
- * ctx.state
41
- * // { p: 6, l: 1, c: 7, done: false, last: 'a' }
42
- * ```
43
- *
44
- * @example
45
- * ```ts
46
- * const ctx = defContext("ababaaabbabba");
47
- *
48
- * // capturing lookahead
49
- * join(lookahead(oneOf("ab"), string("abba"), true))(ctx)
50
- * // true
51
- *
52
- * ctx.result
53
- * // "ababaaabba"
54
- *
55
- * ctx.state
56
- * // { p: 10, l: 1, c: 11, done: false, last: 'a' }
57
- * ```
58
- *
59
- * @param parser -
60
- * @param ahead -
61
- * @param capture -
62
- * @param id -
63
- */
64
- export const lookahead = (parser, ahead, capture = false, id = "lookahead") => (ctx) => {
65
- if (ctx.done)
66
- return false;
67
- ctx.start(id);
68
- let pass = false;
69
- while (true) {
70
- const state = capture ? null : { ...ctx.state };
71
- if (ahead(ctx)) {
72
- !capture && (ctx.state = state);
73
- return pass ? ctx.end() : ctx.discard();
74
- }
75
- if (!parser(ctx))
76
- return ctx.discard();
77
- pass = true;
1
+ const lookahead = (parser, ahead, capture = false, id = "lookahead") => (ctx) => {
2
+ if (ctx.done)
3
+ return false;
4
+ ctx.start(id);
5
+ let pass = false;
6
+ while (true) {
7
+ const state = capture ? null : { ...ctx.state };
8
+ if (ahead(ctx)) {
9
+ !capture && (ctx.state = state);
10
+ return pass ? ctx.end() : ctx.discard();
78
11
  }
12
+ if (!parser(ctx))
13
+ return ctx.discard();
14
+ pass = true;
15
+ }
16
+ };
17
+ export {
18
+ lookahead
79
19
  };
@@ -1,2 +1,5 @@
1
1
  import { pass } from "../prims/pass.js";
2
- export const maybe = (parser, result, id = "maybe") => (ctx) => parser(ctx) || pass(result, id)(ctx);
2
+ const maybe = (parser, result, id = "maybe") => (ctx) => parser(ctx) || pass(result, id)(ctx);
3
+ export {
4
+ maybe
5
+ };
@@ -1,19 +1,12 @@
1
1
  import { always } from "../prims/always.js";
2
- /**
3
- * Runs `parser`, discards its result and if it passed returns false,
4
- * else runs `fail` parser and returns its result. By default `fail` is
5
- * using {@link always}, which consumes a single character and always
6
- * succeeds. To avoid consuming a character on first `parser`'s failure,
7
- * use {@link pass} or {@link passD} instead.
8
- *
9
- * @param parser -
10
- * @param fail -
11
- */
12
- export const not = (parser, fail = always()) => (ctx) => {
13
- if (ctx.done)
14
- return false;
15
- ctx.start("");
16
- const res = parser(ctx);
17
- ctx.discard();
18
- return res ? false : fail(ctx);
2
+ const not = (parser, fail = always()) => (ctx) => {
3
+ if (ctx.done)
4
+ return false;
5
+ ctx.start("");
6
+ const res = parser(ctx);
7
+ ctx.discard();
8
+ return res ? false : fail(ctx);
9
+ };
10
+ export {
11
+ not
19
12
  };
@@ -1,21 +1,29 @@
1
1
  import { discard } from "../xform/discard.js";
2
- export const repeat = (parser, min, max, id = "repeat") => (ctx) => {
3
- if (ctx.done) {
4
- return min < 1 ? ctx.addChild(id) : false;
2
+ const repeat = (parser, min, max, id = "repeat") => (ctx) => {
3
+ if (ctx.done) {
4
+ return min < 1 ? ctx.addChild(id) : false;
5
+ }
6
+ ctx.start(id);
7
+ for (let i = 0; i < max; i++) {
8
+ if (!parser(ctx)) {
9
+ if (i < min) {
10
+ return ctx.discard();
11
+ }
12
+ break;
5
13
  }
6
- ctx.start(id);
7
- for (let i = 0; i < max; i++) {
8
- if (!parser(ctx)) {
9
- if (i < min) {
10
- return ctx.discard();
11
- }
12
- break;
13
- }
14
- }
15
- return ctx.end();
14
+ }
15
+ return ctx.end();
16
+ };
17
+ const zeroOrMore = (parser, id = "repeat0", max = Infinity) => repeat(parser, 0, max, id);
18
+ const oneOrMore = (parser, id = "repeat1", max = Infinity) => repeat(parser, 1, max, id);
19
+ const repeatD = (parser, min, max) => discard(repeat(parser, min, max));
20
+ const zeroOrMoreD = (parser, max = Infinity) => repeatD(parser, 0, max);
21
+ const oneOrMoreD = (parser, max = Infinity) => repeatD(parser, 1, max);
22
+ export {
23
+ oneOrMore,
24
+ oneOrMoreD,
25
+ repeat,
26
+ repeatD,
27
+ zeroOrMore,
28
+ zeroOrMoreD
16
29
  };
17
- export const zeroOrMore = (parser, id = "repeat0", max = Infinity) => repeat(parser, 0, max, id);
18
- export const oneOrMore = (parser, id = "repeat1", max = Infinity) => repeat(parser, 1, max, id);
19
- export const repeatD = (parser, min, max) => discard(repeat(parser, min, max));
20
- export const zeroOrMoreD = (parser, max = Infinity) => repeatD(parser, 0, max);
21
- export const oneOrMoreD = (parser, max = Infinity) => repeatD(parser, 1, max);
@@ -1,13 +1,17 @@
1
1
  import { discard } from "../xform/discard.js";
2
- export const seq = (parsers, id = "seq") => (ctx) => {
3
- if (ctx.done)
4
- return false;
5
- ctx.start(id);
6
- for (let i = 0, n = parsers.length; i < n; i++) {
7
- if (!parsers[i](ctx)) {
8
- return ctx.discard();
9
- }
2
+ const seq = (parsers, id = "seq") => (ctx) => {
3
+ if (ctx.done)
4
+ return false;
5
+ ctx.start(id);
6
+ for (let i = 0, n = parsers.length; i < n; i++) {
7
+ if (!parsers[i](ctx)) {
8
+ return ctx.discard();
10
9
  }
11
- return ctx.end();
10
+ }
11
+ return ctx.end();
12
+ };
13
+ const seqD = (parsers) => discard(seq(parsers));
14
+ export {
15
+ seq,
16
+ seqD
12
17
  };
13
- export const seqD = (parsers) => discard(seq(parsers));
@@ -1,4 +1,7 @@
1
1
  import { litD } from "../prims/lit.js";
2
2
  import { hoist } from "../xform/hoist.js";
3
3
  import { seq } from "./seq.js";
4
- export const wrap = (parser, pre, post = pre) => hoist(seq([litD(pre), parser, litD(post)]));
4
+ const wrap = (parser, pre, post = pre) => hoist(seq([litD(pre), parser, litD(post)]));
5
+ export {
6
+ wrap
7
+ };
@@ -1,16 +1,18 @@
1
- export const xform = (parser, xf, user) => (ctx) => {
2
- if (parser(ctx)) {
3
- const children = ctx.scope.children;
4
- const scope = children[children.length - 1];
5
- if (xf(scope, ctx, user)) {
6
- if (scope.children && !scope.children.length) {
7
- scope.children = null;
8
- }
9
- }
10
- else {
11
- children.pop();
12
- }
13
- return true;
1
+ const xform = (parser, xf, user) => (ctx) => {
2
+ if (parser(ctx)) {
3
+ const children = ctx.scope.children;
4
+ const scope = children[children.length - 1];
5
+ if (xf(scope, ctx, user)) {
6
+ if (scope.children && !scope.children.length) {
7
+ scope.children = null;
8
+ }
9
+ } else {
10
+ children.pop();
14
11
  }
15
- return false;
12
+ return true;
13
+ }
14
+ return false;
15
+ };
16
+ export {
17
+ xform
16
18
  };
package/context.js CHANGED
@@ -4,144 +4,141 @@ import { parseError } from "./error.js";
4
4
  import { defArrayReader } from "./readers/array-reader.js";
5
5
  import { defStringReader } from "./readers/string-reader.js";
6
6
  import { indent } from "./utils.js";
7
- export class ParseContext {
8
- reader;
9
- opts;
10
- _scopes;
11
- _curr;
12
- _maxDepth;
13
- _peakDepth;
14
- _debug;
15
- _retain;
16
- constructor(reader, opts) {
17
- this.reader = reader;
18
- this.opts = { maxDepth: 64, debug: false, retain: false, ...opts };
19
- this._maxDepth = this.opts.maxDepth;
20
- this._debug = this.opts.debug;
21
- this._retain = this.opts.retain;
22
- this.reset();
7
+ class ParseContext {
8
+ constructor(reader, opts) {
9
+ this.reader = reader;
10
+ this.opts = { maxDepth: 64, debug: false, retain: false, ...opts };
11
+ this._maxDepth = this.opts.maxDepth;
12
+ this._debug = this.opts.debug;
13
+ this._retain = this.opts.retain;
14
+ this.reset();
15
+ }
16
+ opts;
17
+ _scopes;
18
+ _curr;
19
+ _maxDepth;
20
+ _peakDepth;
21
+ _debug;
22
+ _retain;
23
+ reset() {
24
+ this._curr = {
25
+ id: "root",
26
+ state: { p: 0, l: 1, c: 1 },
27
+ children: null,
28
+ result: null
29
+ };
30
+ this._scopes = [this._curr];
31
+ this._peakDepth = 1;
32
+ this.reader.isDone(this._curr.state);
33
+ return this;
34
+ }
35
+ start(id) {
36
+ if (this._scopes.length >= this._maxDepth) {
37
+ parseError(this, `recursion limit reached ${this._maxDepth}`);
23
38
  }
24
- reset() {
25
- this._curr = {
26
- id: "root",
27
- state: { p: 0, l: 1, c: 1 },
28
- children: null,
29
- result: null,
30
- };
31
- this._scopes = [this._curr];
32
- this._peakDepth = 1;
33
- this.reader.isDone(this._curr.state);
34
- return this;
35
- }
36
- start(id) {
37
- if (this._scopes.length >= this._maxDepth) {
38
- parseError(this, `recursion limit reached ${this._maxDepth}`);
39
- }
40
- const scopes = this._scopes;
41
- const scope = {
42
- id,
43
- state: { ...scopes[scopes.length - 1].state },
44
- children: null,
45
- result: null,
46
- };
47
- scopes.push(scope);
48
- this._peakDepth = Math.max(this._peakDepth, scopes.length);
49
- this._debug &&
50
- console.log(`${indent(scopes.length)}start: ${id} (${scope.state.p})`);
51
- return (this._curr = scope);
52
- }
53
- discard() {
54
- const scopes = this._scopes;
55
- const child = scopes.pop();
56
- this._curr = scopes[scopes.length - 1];
57
- this._debug &&
58
- console.log(`${indent(scopes.length + 1)}discard: ${child.id}`);
59
- return false;
60
- }
61
- end() {
62
- const scopes = this._scopes;
63
- const child = scopes.pop();
64
- const parent = scopes[scopes.length - 1];
65
- const cstate = child.state;
66
- let pstate;
67
- this._debug &&
68
- console.log(`${indent(scopes.length + 1)}end: ${child.id} (${cstate.p})`);
69
- child.state = this._retain
70
- ? ((pstate = parent.state),
71
- { p: pstate.p, l: pstate.l, c: pstate.c })
72
- : null;
73
- parent.state = cstate;
74
- const children = parent.children;
75
- children ? children.push(child) : (parent.children = [child]);
76
- this._curr = parent;
77
- return true;
78
- }
79
- addChild(id, result = null, newState = false) {
80
- const curr = this._curr;
81
- const cstate = curr.state;
82
- const child = {
83
- id,
84
- state: this._retain
85
- ? { p: cstate.p, l: cstate.l, c: cstate.c }
86
- : null,
87
- children: null,
88
- result,
89
- };
90
- this._debug &&
91
- console.log(`${indent(this._scopes.length + 1)}addChild: ${id} (${cstate.p})`);
92
- const children = curr.children;
93
- children ? children.push(child) : (curr.children = [child]);
94
- if (newState !== false) {
95
- newState === true
96
- ? this.reader.next(cstate)
97
- : (this._curr.state = newState);
98
- }
99
- return true;
100
- }
101
- get scope() {
102
- return this._curr;
103
- }
104
- get state() {
105
- return this._curr.state;
106
- }
107
- set state(state) {
108
- this._curr.state = state;
109
- }
110
- get done() {
111
- return this._curr.state.done;
112
- }
113
- /**
114
- * Returns root node.
115
- */
116
- get root() {
117
- return this._scopes[0];
118
- }
119
- /**
120
- * Returns root node's `result` or `undefined`.
121
- */
122
- get result() {
123
- const children = this.root.children;
124
- return children ? children[0].result : undefined;
125
- }
126
- /**
127
- * Returns root node's children or `undefined`.
128
- */
129
- get children() {
130
- const children = this.root.children;
131
- return children ? children[0].children : undefined;
132
- }
133
- /**
134
- * Returns max. recursion depth which was actually reached. Will always be
135
- * less or equal configured {@link ContextOpts.maxDepth}.
136
- */
137
- get peakDepth() {
138
- return this._peakDepth;
39
+ const scopes = this._scopes;
40
+ const scope = {
41
+ id,
42
+ state: { ...scopes[scopes.length - 1].state },
43
+ children: null,
44
+ result: null
45
+ };
46
+ scopes.push(scope);
47
+ this._peakDepth = Math.max(this._peakDepth, scopes.length);
48
+ this._debug && console.log(
49
+ `${indent(scopes.length)}start: ${id} (${scope.state.p})`
50
+ );
51
+ return this._curr = scope;
52
+ }
53
+ discard() {
54
+ const scopes = this._scopes;
55
+ const child = scopes.pop();
56
+ this._curr = scopes[scopes.length - 1];
57
+ this._debug && console.log(`${indent(scopes.length + 1)}discard: ${child.id}`);
58
+ return false;
59
+ }
60
+ end() {
61
+ const scopes = this._scopes;
62
+ const child = scopes.pop();
63
+ const parent = scopes[scopes.length - 1];
64
+ const cstate = child.state;
65
+ let pstate;
66
+ this._debug && console.log(
67
+ `${indent(scopes.length + 1)}end: ${child.id} (${cstate.p})`
68
+ );
69
+ child.state = this._retain ? (pstate = parent.state, { p: pstate.p, l: pstate.l, c: pstate.c }) : null;
70
+ parent.state = cstate;
71
+ const children = parent.children;
72
+ children ? children.push(child) : parent.children = [child];
73
+ this._curr = parent;
74
+ return true;
75
+ }
76
+ addChild(id, result = null, newState = false) {
77
+ const curr = this._curr;
78
+ const cstate = curr.state;
79
+ const child = {
80
+ id,
81
+ state: this._retain ? { p: cstate.p, l: cstate.l, c: cstate.c } : null,
82
+ children: null,
83
+ result
84
+ };
85
+ this._debug && console.log(
86
+ `${indent(this._scopes.length + 1)}addChild: ${id} (${cstate.p})`
87
+ );
88
+ const children = curr.children;
89
+ children ? children.push(child) : curr.children = [child];
90
+ if (newState !== false) {
91
+ newState === true ? this.reader.next(cstate) : this._curr.state = newState;
139
92
  }
93
+ return true;
94
+ }
95
+ get scope() {
96
+ return this._curr;
97
+ }
98
+ get state() {
99
+ return this._curr.state;
100
+ }
101
+ set state(state) {
102
+ this._curr.state = state;
103
+ }
104
+ get done() {
105
+ return this._curr.state.done;
106
+ }
107
+ /**
108
+ * Returns root node.
109
+ */
110
+ get root() {
111
+ return this._scopes[0];
112
+ }
113
+ /**
114
+ * Returns root node's `result` or `undefined`.
115
+ */
116
+ get result() {
117
+ const children = this.root.children;
118
+ return children ? children[0].result : void 0;
119
+ }
120
+ /**
121
+ * Returns root node's children or `undefined`.
122
+ */
123
+ get children() {
124
+ const children = this.root.children;
125
+ return children ? children[0].children : void 0;
126
+ }
127
+ /**
128
+ * Returns max. recursion depth which was actually reached. Will always be
129
+ * less or equal configured {@link ContextOpts.maxDepth}.
130
+ */
131
+ get peakDepth() {
132
+ return this._peakDepth;
133
+ }
140
134
  }
141
- export function defContext(input, opts) {
142
- return new ParseContext(isString(input)
143
- ? defStringReader(input)
144
- : isArrayLike(input)
145
- ? defArrayReader(input)
146
- : input, opts);
135
+ function defContext(input, opts) {
136
+ return new ParseContext(
137
+ isString(input) ? defStringReader(input) : isArrayLike(input) ? defArrayReader(input) : input,
138
+ opts
139
+ );
147
140
  }
141
+ export {
142
+ ParseContext,
143
+ defContext
144
+ };