parseman 0.9.0 → 0.10.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/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export { rules } from './combinators/parser.ts';
11
11
  export { ref } from './combinators/ref.ts';
12
12
  export { not } from './combinators/not.ts';
13
13
  export { node } from './combinators/node.ts';
14
- export type { BuildNode } from './combinators/node.ts';
14
+ export type { BuildNode, NodeOptions } from './combinators/node.ts';
15
15
  export { transform, skip, trivia, label } from './combinators/map.ts';
16
16
  export { parse, parser, noTrivia } from './combinators/grammar.ts';
17
17
  export type { ParseOptions, ParserOptions, ParsemanParser } from './combinators/grammar.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEjM,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpE,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAEtD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAClE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE3F,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACxF,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAC1D,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAE5D,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE5G,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAChG,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEjM,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpE,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEnE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAClE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE3F,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACxF,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAC1D,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAE5D,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE5G,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAChG,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA"}
package/dist/index.js CHANGED
@@ -1127,24 +1127,70 @@ function not(combinator) {
1127
1127
  };
1128
1128
  }
1129
1129
 
1130
+ // src/compiler/build-arity.ts
1131
+ var PARAM_LIST_RE = (
1132
+ // (params) => ... | function name?(params) ... | single-ident arrow `x => ...`
1133
+ /^(?:function\b[^(]*\(([^)]*)\)|\(([^)]*)\)\s*=>|([A-Za-z_$][\w$]*)\s*=>)/
1134
+ );
1135
+ var CONFIRMABLE_PARAM_RE = /^[A-Za-z_$][\w$]*\s*\??\s*(?::[^,=]+)?$/;
1136
+ function confirmedBuildArity(src) {
1137
+ const s = src.trim();
1138
+ const m = PARAM_LIST_RE.exec(s);
1139
+ if (!m) return null;
1140
+ if (m[3] !== void 0) return 1;
1141
+ const inner = (m[1] ?? m[2] ?? "").trim();
1142
+ if (inner === "") return 0;
1143
+ const parts = inner.split(",");
1144
+ for (const part of parts) {
1145
+ if (!CONFIRMABLE_PARAM_RE.test(part.trim())) return null;
1146
+ }
1147
+ if (/\barguments\b/.test(s)) return null;
1148
+ return parts.length;
1149
+ }
1150
+ function buildReadsTrivia(def) {
1151
+ const src = def.buildSrc ?? def.build.toString();
1152
+ const arity = confirmedBuildArity(src);
1153
+ if (arity === null) return true;
1154
+ return arity >= 4;
1155
+ }
1156
+ function buildReadsState(def) {
1157
+ const src = def.buildSrc ?? def.build.toString();
1158
+ const arity = confirmedBuildArity(src);
1159
+ if (arity === null) return true;
1160
+ return arity >= 5;
1161
+ }
1162
+
1130
1163
  // src/combinators/node.ts
1131
- function node(type, combinator, build) {
1164
+ function collapseChild(child) {
1165
+ return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
1166
+ }
1167
+ function node(type, combinator, build, opts) {
1132
1168
  const meta = {
1133
1169
  firstSet: combinator._meta.firstSet,
1134
1170
  canMatchNewline: combinator._meta.canMatchNewline,
1135
1171
  isTrivia: false
1136
1172
  };
1173
+ const collapse = opts?.collapse === true;
1174
+ const def = collapse ? { tag: "node", type, parser: combinator, build, collapse: true } : { tag: "node", type, parser: combinator, build };
1175
+ const capturesTrivia = buildReadsTrivia(def);
1176
+ const clonesState = buildReadsState(def);
1137
1177
  return {
1138
1178
  _tag: "node",
1139
1179
  _meta: meta,
1140
- _def: { tag: "node", type, parser: combinator, build },
1180
+ _def: def,
1141
1181
  parse(input, pos, ctx) {
1142
1182
  const saved = beginCstNodeCapture(ctx);
1183
+ if (!capturesTrivia) ctx.captureTrivia = false;
1143
1184
  const r = combinator.parse(input, pos, ctx);
1144
1185
  const { children, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
1145
1186
  if (!r.ok) return r;
1146
- const state = ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
1147
- const built = build(children, rawChildren, r.span, triviaLog, state);
1187
+ const built = collapse && children.length === 1 ? collapseChild(children[0]) : build(
1188
+ children,
1189
+ rawChildren,
1190
+ r.span,
1191
+ triviaLog,
1192
+ clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0
1193
+ );
1148
1194
  const isNodeLike = typeof built === "object" && built !== null && built._tag === "node";
1149
1195
  const rawEntry = isNodeLike ? built : { _tag: "leaf", value: typeof built === "string" ? built : "", span: r.span };
1150
1196
  if (saved.buf !== void 0 || saved.ch !== void 0) {
@@ -2579,25 +2625,34 @@ function emitNode(def, ctx, pos) {
2579
2625
  ctx.buildSrcs.push(def.buildSrc ?? null);
2580
2626
  }
2581
2627
  const i = ind(ctx);
2628
+ const capturesTrivia = mkType !== null || buildReadsTrivia(def);
2629
+ const clonesState = buildReadsState(def);
2582
2630
  const chV = v(ctx, "_ch");
2583
2631
  const rawV = v(ctx, "_raw");
2584
- const tlV = v(ctx, "_tl");
2632
+ const tlV = capturesTrivia ? v(ctx, "_tl") : "_EMPTY_TL";
2633
+ if (!capturesTrivia) ctx.needsEmptyTl = true;
2585
2634
  const sc = v(ctx, "_sc"), sl = v(ctx, "_sl"), sr = v(ctx, "_sr"), st = v(ctx, "_st"), stl = v(ctx, "_stl");
2635
+ const allocStmt = capturesTrivia ? `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []` : `${i}const ${chV} = [], ${rawV} = []`;
2636
+ const innerTl = capturesTrivia ? tlV : "undefined";
2586
2637
  const stmts = [
2587
- `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []`,
2638
+ allocStmt,
2588
2639
  `${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog`,
2589
- `${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${tlV}`
2640
+ `${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}`
2590
2641
  ];
2591
2642
  const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
2592
2643
  stmts.push(...innerStmts);
2593
2644
  stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}`);
2594
2645
  stmts.push(...emitIfFail(ctx, `!${okVar}`, failBody(ctx, '"node"', pos)));
2595
- const stV = v(ctx, "_nst");
2596
- stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
2646
+ let stV = "undefined";
2647
+ if (clonesState) {
2648
+ stV = v(ctx, "_nst");
2649
+ stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
2650
+ }
2597
2651
  const ndV = v(ctx, "_nd");
2598
2652
  const ndExpr = mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, pos, endVar, tlV) : `_build[${buildIdx}](${chV}, ${rawV}, { start: ${pos}, end: ${endVar} }, ${tlV}, ${stV})`;
2653
+ const finalExpr = def.collapse ? `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})` : ndExpr;
2599
2654
  stmts.push(
2600
- `${i}const ${ndV} = ${ndExpr}`,
2655
+ `${i}const ${ndV} = ${finalExpr}`,
2601
2656
  `${i}if (${sc}) ${sc}.push(${ndV})`,
2602
2657
  `${i}if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && ${ndV}._tag === 'node') ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : '', span: { start: ${pos}, end: ${endVar} } })`
2603
2658
  );
@@ -2989,7 +3044,9 @@ function compile(combinator, mapFnSources) {
2989
3044
  const collatorDecl = ctx.needsCollator ? `const _collator = new Intl.Collator(undefined, { sensitivity: 'accent' })
2990
3045
  ` : "";
2991
3046
  const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
3047
+ const emptyTlDecls = ctx.needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [];
2992
3048
  const source = [
3049
+ ...emptyTlDecls,
2993
3050
  ...ctx.regexDecls,
2994
3051
  "",
2995
3052
  ...namedPrelude,
@@ -3001,6 +3058,7 @@ function compile(combinator, mapFnSources) {
3001
3058
  `}`
3002
3059
  ].join("\n");
3003
3060
  const fn = new Function("input", "_pos", "_rp", "_mf", "_build", "_ctx", [
3061
+ ...emptyTlDecls,
3004
3062
  ...ctx.regexDecls,
3005
3063
  collatorDecl,
3006
3064
  ...namedPrelude,
@@ -3054,10 +3112,12 @@ function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources)
3054
3112
  ].join("\n");
3055
3113
  const mfDecl = mapFnSources?.length ? ` const _mf = [${mapFnSources.join(", ")}]` : "";
3056
3114
  const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
3057
- const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl;
3115
+ const emptyTlDecl = ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "";
3116
+ const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl || !!emptyTlDecl;
3058
3117
  if (!needsWrapper) return innerFn;
3059
3118
  const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
3060
3119
  const hoistedDecls = [
3120
+ emptyTlDecl,
3061
3121
  ...ctx.regexDecls.map((d) => ` ${d}`),
3062
3122
  collatorDecl ? ` ${collatorDecl.trim()}` : "",
3063
3123
  mfDecl,
@@ -3342,6 +3402,31 @@ function replaceAtPath(rebuild, root, path, newNode) {
3342
3402
  function defaultRebuild(node2, children) {
3343
3403
  return { ...node2, children };
3344
3404
  }
3405
+ function shiftSpans(child, delta) {
3406
+ const c = child;
3407
+ const span = { start: c.span.start + delta, end: c.span.end + delta };
3408
+ if (Array.isArray(c.children)) {
3409
+ return { ...c, span, children: c.children.map((g) => shiftSpans(g, delta)) };
3410
+ }
3411
+ return { ...c, span };
3412
+ }
3413
+ function graftAndShift(root, path, newNode, delta) {
3414
+ if (path.length === 0) return newNode;
3415
+ const [idx, ...rest] = path;
3416
+ const oldChildren = root.children;
3417
+ const newChildren = oldChildren.map((child, i) => {
3418
+ if (i < idx) return child;
3419
+ if (i === idx) {
3420
+ return rest.length === 0 ? newNode : graftAndShift(child, rest, newNode, delta);
3421
+ }
3422
+ return shiftSpans(child, delta);
3423
+ });
3424
+ return {
3425
+ ...root,
3426
+ span: { start: root.span.start, end: root.span.end + delta },
3427
+ children: newChildren
3428
+ };
3429
+ }
3345
3430
  var FunctionalDocImpl = class _FunctionalDocImpl {
3346
3431
  _registry;
3347
3432
  _rootRule;
@@ -3379,7 +3464,12 @@ var FunctionalDocImpl = class _FunctionalDocImpl {
3379
3464
  const r = ruleFn(newInput, node2.span.start, ctx);
3380
3465
  if (!r.ok) continue;
3381
3466
  if (r.span.end === node2.span.end + delta) {
3382
- const newTree = replaceAtPath(rebuild, this.tree, path, r.value);
3467
+ if (delta === 0) {
3468
+ const newTree2 = replaceAtPath(rebuild, this.tree, path, r.value);
3469
+ return new _FunctionalDocImpl(this._registry, this._rootRule, this._opts, newTree2, [], newInput);
3470
+ }
3471
+ if (this._opts.rebuild) return reparse();
3472
+ const newTree = graftAndShift(this.tree, path, r.value, delta);
3383
3473
  return new _FunctionalDocImpl(this._registry, this._rootRule, this._opts, newTree, [], newInput);
3384
3474
  }
3385
3475
  }