parseman 0.47.0 → 0.48.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.
Files changed (124) hide show
  1. package/README.md +27 -21
  2. package/dist/analysis/diagnostics.js +2955 -357
  3. package/dist/analysis/diagnostics.js.map +3 -3
  4. package/dist/cli/index.js +2946 -348
  5. package/dist/cli/index.js.map +3 -3
  6. package/dist/combinators/expect.d.ts +1 -0
  7. package/dist/combinators/expect.d.ts.map +1 -1
  8. package/dist/combinators/expected.d.ts +8 -0
  9. package/dist/combinators/expected.d.ts.map +1 -0
  10. package/dist/combinators/first-set.d.ts +8 -0
  11. package/dist/combinators/first-set.d.ts.map +1 -1
  12. package/dist/combinators/grammar.d.ts.map +1 -1
  13. package/dist/combinators/keywords.d.ts +4 -0
  14. package/dist/combinators/keywords.d.ts.map +1 -1
  15. package/dist/combinators/literal.d.ts.map +1 -1
  16. package/dist/combinators/not.d.ts.map +1 -1
  17. package/dist/combinators/peek.d.ts.map +1 -1
  18. package/dist/combinators/regex.d.ts.map +1 -1
  19. package/dist/combinators/repeat.d.ts.map +1 -1
  20. package/dist/combinators/sequence.d.ts.map +1 -1
  21. package/dist/combinators/trivia-skip.d.ts +19 -1
  22. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  23. package/dist/compiler/direct-projection.d.ts +12 -0
  24. package/dist/compiler/direct-projection.d.ts.map +1 -0
  25. package/dist/compiler/token-alphabet.d.ts +845 -5
  26. package/dist/compiler/token-alphabet.d.ts.map +1 -1
  27. package/dist/compiler/token-capability.d.ts +3 -0
  28. package/dist/compiler/token-capability.d.ts.map +1 -0
  29. package/dist/compiler/token-capability.js +3192 -0
  30. package/dist/compiler/token-capability.js.map +6 -0
  31. package/dist/cst/trivia-charscan.d.ts +3 -0
  32. package/dist/cst/trivia-charscan.d.ts.map +1 -1
  33. package/dist/cst/trivia-css-scanner.d.ts +5 -0
  34. package/dist/cst/trivia-css-scanner.d.ts.map +1 -0
  35. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  36. package/dist/index.js +2959 -348
  37. package/dist/index.js.map +3 -3
  38. package/dist/language-service/index.js +7 -1
  39. package/dist/language-service/index.js.map +1 -1
  40. package/dist/plugin/index.js +2969 -358
  41. package/dist/plugin/index.js.map +3 -3
  42. package/dist/spec/index.js +366 -49
  43. package/dist/spec/index.js.map +2 -2
  44. package/dist/table/assemble.d.ts.map +1 -1
  45. package/dist/table/child-slots.d.ts.map +1 -1
  46. package/dist/table/compile-rule-map.d.ts +3 -1
  47. package/dist/table/compile-rule-map.d.ts.map +1 -1
  48. package/dist/table/emit-assembly.d.ts +13 -14
  49. package/dist/table/emit-assembly.d.ts.map +1 -1
  50. package/dist/table/emit.d.ts.map +1 -1
  51. package/dist/table/encode.d.ts.map +1 -1
  52. package/dist/table/exec-baseline.d.ts.map +1 -1
  53. package/dist/table/exec.d.ts.map +1 -1
  54. package/dist/table/index.js +4839 -2232
  55. package/dist/table/index.js.map +3 -3
  56. package/dist/table/lex-body.d.ts +9 -0
  57. package/dist/table/lex-body.d.ts.map +1 -0
  58. package/dist/table/lex-program.d.ts +25 -0
  59. package/dist/table/lex-program.d.ts.map +1 -0
  60. package/dist/table/ops.d.ts +47 -4
  61. package/dist/table/ops.d.ts.map +1 -1
  62. package/dist/table/program.d.ts +53 -2
  63. package/dist/table/program.d.ts.map +1 -1
  64. package/dist/table/scalar-terminal.d.ts +13 -0
  65. package/dist/table/scalar-terminal.d.ts.map +1 -0
  66. package/dist/table/site-labels.d.ts.map +1 -1
  67. package/dist/types.d.ts +2 -0
  68. package/dist/types.d.ts.map +1 -1
  69. package/dist/version.d.ts +1 -1
  70. package/package.json +12 -11
  71. package/src/combinators/expect.ts +1 -0
  72. package/src/combinators/expected.ts +17 -0
  73. package/src/combinators/first-set.ts +82 -3
  74. package/src/combinators/grammar.ts +8 -3
  75. package/src/combinators/keywords.ts +22 -6
  76. package/src/combinators/literal.ts +2 -1
  77. package/src/combinators/not.ts +5 -1
  78. package/src/combinators/peek.ts +5 -1
  79. package/src/combinators/regex.ts +5 -3
  80. package/src/combinators/repeat.ts +4 -10
  81. package/src/combinators/sequence.ts +35 -16
  82. package/src/combinators/trivia-skip.ts +75 -11
  83. package/src/compiler/direct-projection.ts +43 -0
  84. package/src/compiler/token-alphabet.ts +4316 -12
  85. package/src/compiler/token-capability.ts +6 -0
  86. package/src/cst/trivia-charscan.ts +34 -0
  87. package/src/cst/trivia-css-scanner.ts +142 -0
  88. package/src/cst/trivia-kinds.ts +3 -1
  89. package/src/plugin/index.ts +4 -4
  90. package/src/table/assemble.ts +1224 -222
  91. package/src/table/child-slots.ts +4 -3
  92. package/src/table/compile-rule-map.ts +21 -3
  93. package/src/table/emit-assembly.ts +363 -109
  94. package/src/table/emit.ts +26 -1
  95. package/src/table/encode.ts +246 -54
  96. package/src/table/exec-baseline.ts +3 -7
  97. package/src/table/exec.ts +140 -18
  98. package/src/table/lex-body.ts +30 -0
  99. package/src/table/lex-program.ts +422 -0
  100. package/src/table/ops.ts +50 -4
  101. package/src/table/program.ts +67 -2
  102. package/src/table/scalar-terminal.ts +51 -0
  103. package/src/table/site-labels.ts +13 -3
  104. package/src/table/stamp.ts +3 -3
  105. package/src/types.ts +1 -1
  106. package/src/version.ts +1 -1
  107. package/dist/analysis/diagnostics.cjs +0 -13736
  108. package/dist/analysis/diagnostics.cjs.map +0 -6
  109. package/dist/cli/index.cjs +0 -14837
  110. package/dist/cli/index.cjs.map +0 -6
  111. package/dist/index.cjs +0 -16303
  112. package/dist/index.cjs.map +0 -6
  113. package/dist/language-service/index.cjs +0 -1302
  114. package/dist/language-service/index.cjs.map +0 -6
  115. package/dist/oracle/index.cjs +0 -254
  116. package/dist/oracle/index.cjs.map +0 -6
  117. package/dist/plugin/index.cjs +0 -16009
  118. package/dist/plugin/index.cjs.map +0 -6
  119. package/dist/run/index.cjs +0 -577
  120. package/dist/run/index.cjs.map +0 -6
  121. package/dist/spec/index.cjs +0 -6188
  122. package/dist/spec/index.cjs.map +0 -6
  123. package/dist/table/index.cjs +0 -11375
  124. package/dist/table/index.cjs.map +0 -6
@@ -0,0 +1,51 @@
1
+ import { OP_LIT, OP_NOT, OP_RX } from './ops.ts'
2
+
3
+ /** Pure recognition only. Consumption owns value, CST, line, failure and cursor effects. */
4
+ export type ScalarRecognizer = (input: string, pos: number, seed?: number) => number
5
+
6
+ /**
7
+ * One recognizer per existing terminal constant. This is the common raw/pending
8
+ * seam: a later token cursor may provide a cached end for the same (pos, spec)
9
+ * without changing either consumer's materialization protocol.
10
+ */
11
+ export function makeScalarRecognizer(op: number, spec: unknown): ScalarRecognizer | undefined {
12
+ if (op === OP_RX && spec instanceof RegExp) {
13
+ return (input, pos) => {
14
+ spec.lastIndex = pos
15
+ return spec.test(input) ? spec.lastIndex : -1
16
+ }
17
+ }
18
+ if (op !== OP_LIT || typeof spec !== 'string') return undefined
19
+ const len = spec.length
20
+ if (len === 1) {
21
+ const c0 = spec.charCodeAt(0)
22
+ return (input, pos) => input.charCodeAt(pos) === c0 ? pos + 1 : -1
23
+ }
24
+ if (len === 2) {
25
+ const c0 = spec.charCodeAt(0), c1 = spec.charCodeAt(1)
26
+ return (input, pos) => input.charCodeAt(pos) === c0 && input.charCodeAt(pos + 1) === c1 ? pos + 2 : -1
27
+ }
28
+ if (len === 3) {
29
+ const c0 = spec.charCodeAt(0), c1 = spec.charCodeAt(1), c2 = spec.charCodeAt(2)
30
+ return (input, pos) => input.charCodeAt(pos) === c0
31
+ && input.charCodeAt(pos + 1) === c1
32
+ && input.charCodeAt(pos + 2) === c2 ? pos + 3 : -1
33
+ }
34
+ return (input, pos) => input.startsWith(spec, pos) ? pos + len : -1
35
+ }
36
+
37
+ /** Exact bounded shape whose terminal value can be materialized without a node capture frame. */
38
+ export function scalarTerminalNodeChild(code: ArrayLike<number>, ip: number): number {
39
+ if (code[ip + 1]! < 0 || code[ip + 3] !== 0 || code[ip + 4] !== -1) return -1
40
+ const child = code[ip + 2]!
41
+ const op = code[child]
42
+ return op === OP_RX || op === OP_LIT ? child : -1
43
+ }
44
+
45
+ /** Direct untracked terminal whose recognition `not()` can inspect without materializing it. */
46
+ export function scalarTerminalNotChild(code: ArrayLike<number>, ip: number): number {
47
+ if (code[ip] !== OP_NOT) return -1
48
+ const child = code[ip + 1]!
49
+ const op = code[child]
50
+ return op === OP_RX || op === OP_LIT ? child : -1
51
+ }
@@ -62,7 +62,7 @@
62
62
  import {
63
63
  OP_ATTEMPT, OP_CHOICE, OP_DISPATCH, OP_EXPECT, OP_FIELD, OP_GATE, OP_LABEL, OP_LEAF,
64
64
  OP_NODE, OP_NODE_TRACK, OP_NOT, OP_OPT, OP_PEEK, OP_REP, OP_REPV, OP_ROUTED, OP_RULE,
65
- OP_SCOPE, OP_SCOPE_CAP, OP_SEQ, OP_SEQV, OP_SEQX, OP_TOKEN, OP_XFORM,
65
+ OP_SCOPE, OP_SCOPE_CAP, OP_SCOPE_PLAIN, OP_SEQ, OP_SEQV, OP_SEQX, OP_TOKEN, OP_XFORM,
66
66
  } from './ops.ts'
67
67
  import { childSlots } from './child-slots.ts'
68
68
 
@@ -138,7 +138,7 @@ export function reachableSites(code: Int32Array, roots: Iterable<number>): Set<n
138
138
  */
139
139
  function transfer(code: Int32Array, ip: number, at: SiteLabel, hostCst: boolean): SiteLabel {
140
140
  const op = code[ip]
141
- if (op === OP_SCOPE || op === OP_SCOPE_CAP) {
141
+ if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
142
142
  const ki = code[ip + 1]!
143
143
  const tri = ki < 0 ? TRI_NONE : ki
144
144
  // `OP_SCOPE_CAP` is an OR with the inherited context, never a switch-off
@@ -148,10 +148,20 @@ function transfer(code: Int32Array, ip: number, at: SiteLabel, hostCst: boolean)
148
148
  return { tri, buf: at.buf, cap }
149
149
  }
150
150
  if (op === OP_NODE || op === OP_NODE_TRACK) {
151
+ const flags = code[ip + 3]!
152
+ const directChildren = !hostCst && op === OP_NODE && code[ip + 1]! >= 0 && code[ip + 4]! < 0
153
+ && (flags === 2 || flags === 18 || flags === 34)
154
+ if (directChildren) {
155
+ // The confirmed low-arity builder projection installs split child/leaf
156
+ // arrays instead of a CstCaptureBuf. Descendants still capture, but they
157
+ // must take the generic collector branch rather than dereference `_cstBuf`.
158
+ // False means UNKNOWN in this lattice, which is exactly the safe answer.
159
+ return { tri: at.tri, buf: false, cap: CAP_OFF }
160
+ }
151
161
  // `ctx._cstBuf = buf` and `ctx.captureTrivia = <literal>`, both unconditional
152
162
  // — `emit-assembly.ts`'s `OP_NODE` body opens the buffer before it descends
153
163
  // and closes it after, whatever the host mode is.
154
- const cap = ((code[ip + 3]! & 4) !== 0 || hostCst) ? CAP_ON : CAP_OFF
164
+ const cap = ((flags & 4) !== 0 || hostCst) ? CAP_ON : CAP_OFF
155
165
  if (at.buf && cap === at.cap) return at
156
166
  return { tri: at.tri, buf: true, cap }
157
167
  }
@@ -14,7 +14,7 @@ import type { Combinator, ParseContext, ParseResult } from '../types.ts'
14
14
  import { FUSED_HOST_ELIDED, FUSED_HOST_MODE } from '../cst/host-mode.ts'
15
15
  import { GRAMMAR_COVERAGE_DEFINITIONS } from '../grammar-metadata.ts'
16
16
  import { reachableIps } from './inspect.ts'
17
- import { OP_NODE, OP_NODE_TRACK, OP_SCOPE } from './ops.ts'
17
+ import { OP_NODE, OP_NODE_TRACK, OP_SCOPE, OP_SCOPE_PLAIN } from './ops.ts'
18
18
  import { covDefinitions, resolveTable, type ResolvedTable, type TableProgram, type TableRule } from './program.ts'
19
19
 
20
20
  const EMPTY_FX: string[] = []
@@ -98,12 +98,12 @@ export function stampRuleMap(
98
98
  // up as `ok: true` with bytes missing, never as an error.
99
99
  //
100
100
  // Read from the ENTRY ROW, not from one program-wide slot: `encodeRule` wraps each
101
- // rule's entry in `OP_SCOPE <triviaSlot> <body>` iff THAT rule has ambient trivia,
101
+ // rule's entry in `OP_SCOPE_PLAIN <triviaSlot> <body>` iff THAT rule has ambient trivia,
102
102
  // and a `composeLeaf` grammar's pieces do not agree (the same disagreement
103
103
  // `scanSkipOf` exists for). The owning driver passes its resolved table, so
104
104
  // this is the exact trivia array it already built.
105
105
  const triviaOfRule = (ip: number): Combinator<unknown> | undefined => {
106
- if (prog.code[ip] !== OP_SCOPE) return undefined
106
+ if (prog.code[ip] !== OP_SCOPE_PLAIN && prog.code[ip] !== OP_SCOPE) return undefined
107
107
  const slot = prog.code[ip + 1]!
108
108
  return slot < 0 ? undefined : resolved.trivia[slot]
109
109
  }
package/src/types.ts CHANGED
@@ -82,7 +82,7 @@ export type ParserDef =
82
82
  | { tag: 'leaf'; parser: Combinator<unknown>; fn: (v: unknown, span: { start: number; end: number }) => unknown; fnSrc?: string }
83
83
  | { tag: 'label'; label: string; parser: Combinator<unknown> }
84
84
  | { tag: 'field'; name: string; parser: Combinator<unknown> }
85
- | { tag: 'grammar'; parser: Combinator<unknown>; triviaParser: Combinator<unknown> | undefined; clearTrivia?: boolean; captureTrivia?: boolean; rootCapture?: 'opaque'; trackLines: boolean }
85
+ | { tag: 'grammar'; parser: Combinator<unknown>; triviaParser: Combinator<unknown> | undefined; clearTrivia?: boolean; captureTrivia?: boolean; rootCapture?: 'opaque'; trackLines: boolean; constructionTrackLines?: 'on' | 'off' | 'inherit'; constructionCaptureTriviaKinds?: readonly string[] }
86
86
  | { tag: 'lazy'; thunk: () => Combinator<unknown> }
87
87
  | { tag: 'not'; parser: Combinator<unknown> }
88
88
  // Positive lookahead. Zero-width like `not`, but — unlike `not` — it KNOWS what
package/src/version.ts CHANGED
@@ -13,4 +13,4 @@
13
13
  * Kept in sync with `package.json` by `test/unit/version-sync.test.ts`, which fails
14
14
  * the build if this constant drifts from the published version.
15
15
  */
16
- export const PARSEMAN_VERSION = '0.47.0'
16
+ export const PARSEMAN_VERSION = '0.48.0'