jit-parser 1.0.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 (80) hide show
  1. package/README.md +632 -0
  2. package/lib/codegen/CodegenAstFactory.d.ts +14 -0
  3. package/lib/codegen/CodegenAstFactory.js +119 -0
  4. package/lib/codegen/CodegenAstFactory.js.map +1 -0
  5. package/lib/codegen/CodegenGrammar.d.ts +21 -0
  6. package/lib/codegen/CodegenGrammar.js +145 -0
  7. package/lib/codegen/CodegenGrammar.js.map +1 -0
  8. package/lib/codegen/CodegenList.d.ts +15 -0
  9. package/lib/codegen/CodegenList.js +63 -0
  10. package/lib/codegen/CodegenList.js.map +1 -0
  11. package/lib/codegen/CodegenProduction.d.ts +15 -0
  12. package/lib/codegen/CodegenProduction.js +72 -0
  13. package/lib/codegen/CodegenProduction.js.map +1 -0
  14. package/lib/codegen/CodegenTerminal.d.ts +14 -0
  15. package/lib/codegen/CodegenTerminal.js +133 -0
  16. package/lib/codegen/CodegenTerminal.js.map +1 -0
  17. package/lib/codegen/CodegenUnion.d.ts +15 -0
  18. package/lib/codegen/CodegenUnion.js +71 -0
  19. package/lib/codegen/CodegenUnion.js.map +1 -0
  20. package/lib/codegen/Pattern.d.ts +8 -0
  21. package/lib/codegen/Pattern.js +41 -0
  22. package/lib/codegen/Pattern.js.map +1 -0
  23. package/lib/context.d.ts +13 -0
  24. package/lib/context.js +20 -0
  25. package/lib/context.js.map +1 -0
  26. package/lib/generator.d.ts +20 -0
  27. package/lib/generator.js +100 -0
  28. package/lib/generator.js.map +1 -0
  29. package/lib/grammars/calculator.d.ts +2 -0
  30. package/lib/grammars/calculator.js +76 -0
  31. package/lib/grammars/calculator.js.map +1 -0
  32. package/lib/grammars/esql.d.ts +2 -0
  33. package/lib/grammars/esql.js +221 -0
  34. package/lib/grammars/esql.js.map +1 -0
  35. package/lib/grammars/javascript.d.ts +2 -0
  36. package/lib/grammars/javascript.js +251 -0
  37. package/lib/grammars/javascript.js.map +1 -0
  38. package/lib/grammars/json-expression.d.ts +2 -0
  39. package/lib/grammars/json-expression.js +101 -0
  40. package/lib/grammars/json-expression.js.map +1 -0
  41. package/lib/grammars/json.d.ts +2 -0
  42. package/lib/grammars/json.js +79 -0
  43. package/lib/grammars/json.js.map +1 -0
  44. package/lib/index.d.ts +0 -0
  45. package/lib/index.js +2 -0
  46. package/lib/index.js.map +1 -0
  47. package/lib/matches.d.ts +15 -0
  48. package/lib/matches.js +21 -0
  49. package/lib/matches.js.map +1 -0
  50. package/lib/print.d.ts +11 -0
  51. package/lib/print.js +97 -0
  52. package/lib/print.js.map +1 -0
  53. package/lib/testing/cli.d.ts +1 -0
  54. package/lib/testing/cli.js +84 -0
  55. package/lib/testing/cli.js.map +1 -0
  56. package/lib/testing/driver.d.ts +21 -0
  57. package/lib/testing/driver.js +73 -0
  58. package/lib/testing/driver.js.map +1 -0
  59. package/lib/testing/index.d.ts +5 -0
  60. package/lib/testing/index.js +9 -0
  61. package/lib/testing/index.js.map +1 -0
  62. package/lib/testing/jest.d.ts +4 -0
  63. package/lib/testing/jest.js +31 -0
  64. package/lib/testing/jest.js.map +1 -0
  65. package/lib/testing/report.d.ts +3 -0
  66. package/lib/testing/report.js +64 -0
  67. package/lib/testing/report.js.map +1 -0
  68. package/lib/testing/runner.d.ts +29 -0
  69. package/lib/testing/runner.js +93 -0
  70. package/lib/testing/runner.js.map +1 -0
  71. package/lib/testing/types.d.ts +34 -0
  72. package/lib/testing/types.js +3 -0
  73. package/lib/testing/types.js.map +1 -0
  74. package/lib/types.d.ts +70 -0
  75. package/lib/types.js +3 -0
  76. package/lib/types.js.map +1 -0
  77. package/lib/util.d.ts +10 -0
  78. package/lib/util.js +39 -0
  79. package/lib/util.js.map +1 -0
  80. package/package.json +103 -0
package/README.md ADDED
@@ -0,0 +1,632 @@
1
+ # JIT Parser
2
+
3
+ Top-down recursive descent backtracking PEG scanner-less JIT parser combinator generator.
4
+
5
+ A high-performance parser library that compiles grammar definitions into efficient JavaScript parsing functions at runtime. It generates both Concrete Syntax Trees (CST) and Abstract Syntax Trees (AST) from textual input.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Installation](#installation)
10
+ - [Quick Start](#quick-start)
11
+ - [Grammar Node Types](#grammar-node-types)
12
+ - [Tree Types](#tree-types)
13
+ - [Grammar Compilation](#grammar-compilation)
14
+ - [Debug Mode](#debug-mode)
15
+ - [Testing](#testing)
16
+ - [Examples](#examples)
17
+ - [API Reference](#api-reference)
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install jit-parser
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```typescript
28
+ import {CodegenGrammar} from 'jit-parser';
29
+ import {ParseContext} from 'jit-parser';
30
+
31
+ // Define a simple grammar
32
+ const grammar = {
33
+ start: 'Value',
34
+ cst: {
35
+ Value: 'hello'
36
+ }
37
+ };
38
+
39
+ // Compile the grammar to JavaScript
40
+ const parser = CodegenGrammar.compile(grammar);
41
+
42
+ // Parse input
43
+ const ctx = new ParseContext('hello', false);
44
+ const cst = parser(ctx, 0);
45
+ console.log(cst); // CST node representing the parse result
46
+ ```
47
+
48
+ ## Grammar Node Types
49
+
50
+ JIT Parser supports five main grammar node types for defining parsing rules. Grammar rules can be fully defined in JSON, making them language-agnostic and easy to serialize.
51
+
52
+ ### 1. RefNode (Reference Node)
53
+
54
+ References a named node defined elsewhere in the grammar.
55
+
56
+ **Interface:**
57
+ ```typescript
58
+ type RefNode<Name extends string = string> = {r: Name};
59
+ ```
60
+
61
+ **Syntax:**
62
+ ```typescript
63
+ {r: 'NodeName'}
64
+ ```
65
+
66
+ **Example:**
67
+ ```typescript
68
+ const grammar = {
69
+ start: 'Program',
70
+ cst: {
71
+ Program: {r: 'Statement'},
72
+ Statement: 'return;'
73
+ }
74
+ };
75
+ ```
76
+
77
+ ### 2. TerminalNode (Terminal Node)
78
+
79
+ Matches literal strings, regular expressions, or arrays of strings. Terminal nodes are leaf nodes in the parse tree.
80
+
81
+ **Interface:**
82
+ ```typescript
83
+ interface TerminalNode {
84
+ type?: string; // Type name (default: "Text")
85
+ t: RegExp | string | '' | string[]; // Pattern(s) to match
86
+ repeat?: '*' | '+'; // Repetition (only for string arrays)
87
+ sample?: string; // Sample text for generation
88
+ ast?: AstNodeExpression; // AST transformation
89
+ }
90
+
91
+ // Shorthand: string, RegExp, or empty string
92
+ type TerminalNodeShorthand = RegExp | string | '';
93
+ ```
94
+
95
+ **Syntax:**
96
+ ```typescript
97
+ // String literal
98
+ 'hello'
99
+
100
+ // Regular expression
101
+ /[a-z]+/
102
+
103
+ // Array of alternatives
104
+ {t: ['true', 'false']}
105
+
106
+ // With repetition
107
+ {t: [' ', '\t', '\n'], repeat: '*'}
108
+
109
+ // Full terminal node
110
+ {
111
+ t: /\d+/,
112
+ type: 'Number',
113
+ sample: '123'
114
+ }
115
+ ```
116
+
117
+ **Examples:**
118
+ ```typescript
119
+ // Simple string terminal
120
+ Value: 'null'
121
+
122
+ // RegExp terminal
123
+ Number: /\-?\d+(\.\d+)?/
124
+
125
+ // Alternative strings
126
+ Boolean: {t: ['true', 'false']}
127
+
128
+ // Repeating whitespace
129
+ WS: {t: [' ', '\t', '\n'], repeat: '*'}
130
+ ```
131
+
132
+ ### 3. ProductionNode (Production Node)
133
+
134
+ Matches a sequence of grammar nodes in order. All nodes in the sequence must match for the production to succeed.
135
+
136
+ **Interface:**
137
+ ```typescript
138
+ interface ProductionNode {
139
+ p: GrammarNode[]; // Sequence of nodes to match
140
+ type?: string; // Type name (default: "Production")
141
+ children?: Record<number, string>; // Child index to property mapping
142
+ ast?: AstNodeExpression; // AST transformation
143
+ }
144
+
145
+ // Shorthand: array of grammar nodes
146
+ type ProductionNodeShorthand = GrammarNode[];
147
+ ```
148
+
149
+ **Syntax:**
150
+ ```typescript
151
+ // Shorthand array
152
+ ['{', {r: 'Content'}, '}']
153
+
154
+ // Full production node
155
+ {
156
+ p: ['{', {r: 'Content'}, '}'],
157
+ type: 'Block',
158
+ children: {
159
+ 1: 'content' // Maps index 1 to 'content' property
160
+ }
161
+ }
162
+ ```
163
+
164
+ **Examples:**
165
+ ```typescript
166
+ // Function call: func()
167
+ FunctionCall: ['func', '(', ')']
168
+
169
+ // Object with named children
170
+ Object: {
171
+ p: ['{', {r: 'Members'}, '}'],
172
+ children: {
173
+ 1: 'members'
174
+ }
175
+ }
176
+ ```
177
+
178
+ ### 4. UnionNode (Union Node)
179
+
180
+ Matches one of several alternative patterns. The first matching alternative is selected (ordered choice).
181
+
182
+ **Interface:**
183
+ ```typescript
184
+ interface UnionNode {
185
+ u: GrammarNode[]; // Array of alternative nodes
186
+ type?: string; // Type name (default: "Union")
187
+ ast?: AstNodeExpression; // AST transformation
188
+ }
189
+ ```
190
+
191
+ **Syntax:**
192
+ ```typescript
193
+ {
194
+ u: [pattern1, pattern2, pattern3]
195
+ }
196
+ ```
197
+
198
+ **Examples:**
199
+ ```typescript
200
+ // Literal values
201
+ Literal: {
202
+ u: ['null', 'true', 'false', {r: 'Number'}, {r: 'String'}]
203
+ }
204
+
205
+ // Statement types
206
+ Statement: {
207
+ u: [
208
+ {r: 'IfStatement'},
209
+ {r: 'ReturnStatement'},
210
+ {r: 'ExpressionStatement'}
211
+ ]
212
+ }
213
+ ```
214
+
215
+ ### 5. ListNode (List Node)
216
+
217
+ Matches zero or more repetitions of a pattern.
218
+
219
+ **Interface:**
220
+ ```typescript
221
+ interface ListNode {
222
+ l: GrammarNode; // Node to repeat
223
+ type?: string; // Type name (default: "List")
224
+ ast?: AstNodeExpression; // AST transformation
225
+ }
226
+ ```
227
+
228
+ **Syntax:**
229
+ ```typescript
230
+ {
231
+ l: pattern
232
+ }
233
+ ```
234
+
235
+ **Examples:**
236
+ ```typescript
237
+ // Zero or more statements
238
+ Statements: {
239
+ l: {r: 'Statement'}
240
+ }
241
+
242
+ // Comma-separated list
243
+ Arguments: {
244
+ l: {
245
+ p: [',', {r: 'Expression'}],
246
+ ast: ['$', '/children/1'] // Extract the expression, ignore comma
247
+ }
248
+ }
249
+ ```
250
+
251
+ ## Tree Types
252
+
253
+ JIT Parser works with four types of tree structures:
254
+
255
+ ### 1. Grammar Nodes
256
+
257
+ The grammar definition that describes the parsing rules. These are the node types described above that define how to parse input text.
258
+
259
+ ### 2. CST (Concrete Syntax Tree)
260
+
261
+ The parse tree that contains every matched token and maintains the complete structure of the parsed input.
262
+
263
+ **Interface:**
264
+ ```typescript
265
+ interface CstNode {
266
+ ptr: Pattern; // Reference to grammar pattern
267
+ pos: number; // Start position in input
268
+ end: number; // End position in input
269
+ children?: CstNode[]; // Child nodes
270
+ }
271
+ ```
272
+
273
+ **Example CST:**
274
+ ```typescript
275
+ // For input: '{"foo": 123}'
276
+ {
277
+ ptr: ObjectPattern,
278
+ pos: 0,
279
+ end: 13,
280
+ children: [
281
+ {ptr: TextPattern, pos: 0, end: 1}, // '{'
282
+ {ptr: MembersPattern, pos: 1, end: 12, // '"foo": 123'
283
+ children: [...]
284
+ },
285
+ {ptr: TextPattern, pos: 12, end: 13} // '}'
286
+ ]
287
+ }
288
+ ```
289
+
290
+ ### 3. AST (Abstract Syntax Tree)
291
+
292
+ A simplified tree structure derived from the CST, typically containing only semantically meaningful nodes.
293
+
294
+ **Default AST Interface:**
295
+ ```typescript
296
+ interface CanonicalAstNode {
297
+ type: string; // Node type
298
+ pos: number; // Start position
299
+ end: number; // End position
300
+ raw?: string; // Raw matched text
301
+ children?: (CanonicalAstNode | unknown)[]; // Child nodes
302
+ }
303
+ ```
304
+
305
+ **Example AST:**
306
+ ```typescript
307
+ // For input: '{"foo": 123}'
308
+ {
309
+ type: 'Object',
310
+ pos: 0,
311
+ end: 13,
312
+ children: [
313
+ {
314
+ type: 'Entry',
315
+ key: {type: 'String', value: 'foo'},
316
+ value: {type: 'Number', value: 123}
317
+ }
318
+ ]
319
+ }
320
+ ```
321
+
322
+ ### CST to AST Conversion Rules
323
+
324
+ 1. **Default Conversion**: Each CST node becomes an AST node with `type`, `pos`, `end`, and `children` properties.
325
+
326
+ 2. **AST Expressions**: Use `ast` property in grammar nodes to customize AST generation:
327
+ - `ast: null` - Skip this node in AST
328
+ - `ast: ['$', '/children/0']` - Use first child's AST
329
+ - `ast: {...}` - Custom JSON expression for transformation
330
+
331
+ 3. **Children Mapping**: Use `children` property to map CST child indices to AST properties:
332
+ ```typescript
333
+ {
334
+ children: {
335
+ 0: 'key', // CST child 0 -> AST property 'key'
336
+ 2: 'value' // CST child 2 -> AST property 'value'
337
+ }
338
+ }
339
+ ```
340
+
341
+ 4. **Type Override**: Specify custom `type` property instead of default node type names.
342
+
343
+ ### 4. Debug Trace Tree
344
+
345
+ If debug mode is enabled during compilation, the parser captures all grammar node tree paths that were attempted during parsing. This debug trace tree is useful for debugging parser behavior and improving parser performance by understanding which rules were tried and failed.
346
+
347
+ **Interface:**
348
+ ```typescript
349
+ interface TraceNode {
350
+ type: string; // Grammar rule name that was attempted
351
+ pos: number; // Start position where rule was tried
352
+ end?: number; // End position if rule succeeded
353
+ children?: TraceNode[]; // Nested rule attempts
354
+ success: boolean; // Whether the rule matched successfully
355
+ }
356
+ ```
357
+
358
+ The debug trace captures the complete parsing process, including failed attempts, making it invaluable for understanding complex parsing scenarios and optimizing grammar rules.
359
+
360
+ ## Grammar Compilation
361
+
362
+ Grammars are compiled to efficient JavaScript functions that can parse input strings rapidly.
363
+
364
+ ### Basic Compilation
365
+
366
+ ```typescript
367
+ import {CodegenGrammar} from 'jit-parser';
368
+
369
+ const grammar = {
370
+ start: 'Value',
371
+ cst: {
372
+ Value: {r: 'Number'},
373
+ Number: /\d+/
374
+ }
375
+ };
376
+
377
+ // Compile to parser function
378
+ const parser = CodegenGrammar.compile(grammar);
379
+ ```
380
+
381
+ ### Compilation Options
382
+
383
+ ```typescript
384
+ import {CodegenContext} from 'jit-parser';
385
+
386
+ const ctx = new CodegenContext(
387
+ true, // positions: Include pos/end in AST
388
+ true, // astExpressions: Process AST transformations
389
+ false // debug: Generate debug trace code
390
+ );
391
+
392
+ const parser = CodegenGrammar.compile(grammar, ctx);
393
+ ```
394
+
395
+ ### Viewing Compiled Grammar
396
+
397
+ You can print the grammar structure by converting it to a string:
398
+
399
+ ```typescript
400
+ import {GrammarPrinter} from 'jit-parser';
401
+
402
+ const grammarString = GrammarPrinter.print(grammar);
403
+ console.log(grammarString);
404
+ ```
405
+
406
+ **Example output:**
407
+ ```
408
+ Value (reference)
409
+ └─ Number (terminal): /\d+/
410
+ ```
411
+
412
+ ### Complex Grammar Example
413
+
414
+ ```typescript
415
+ const jsonGrammar = {
416
+ start: 'Value',
417
+ cst: {
418
+ WOpt: {t: [' ', '\n', '\t', '\r'], repeat: '*', ast: null},
419
+ Value: [{r: 'WOpt'}, {r: 'TValue'}, {r: 'WOpt'}],
420
+ TValue: {
421
+ u: ['null', {r: 'Boolean'}, {r: 'Number'}, {r: 'String'}, {r: 'Object'}, {r: 'Array'}]
422
+ },
423
+ Boolean: {t: ['true', 'false']},
424
+ Number: /\-?\d+(\.\d+)?([eE][\+\-]?\d+)?/,
425
+ String: /"[^"\\]*(?:\\.[^"\\]*)*"/,
426
+ Object: ['{', {r: 'Members'}, '}'],
427
+ Members: {
428
+ u: [
429
+ {
430
+ p: [{r: 'Entry'}, {l: {p: [',', {r: 'Entry'}], ast: ['$', '/children/1']}}],
431
+ ast: ['concat', ['push', [[]], ['$', '/children/0']], ['$', '/children/1']]
432
+ },
433
+ {r: 'WOpt'}
434
+ ]
435
+ },
436
+ Entry: {
437
+ p: [{r: 'String'}, ':', {r: 'Value'}],
438
+ children: {0: 'key', 2: 'value'}
439
+ },
440
+ Array: ['[', {r: 'Elements'}, ']']
441
+ // ... more rules
442
+ },
443
+ ast: {
444
+ Value: ['$', '/children/1'], // Extract middle child (TValue)
445
+ Boolean: ['==', ['$', '/raw'], 'true'], // Convert to boolean
446
+ Number: ['num', ['$', '/raw']] // Convert to number
447
+ }
448
+ };
449
+
450
+ const parser = CodegenGrammar.compile(jsonGrammar);
451
+ console.log(GrammarPrinter.print(jsonGrammar));
452
+ ```
453
+
454
+ ## Debug Mode
455
+
456
+ Debug mode captures a trace of the parsing process, showing which grammar rules were attempted at each position.
457
+
458
+ ### Enabling Debug Mode
459
+
460
+ ```typescript
461
+ import {CodegenContext, ParseContext} from 'jit-parser';
462
+
463
+ // Enable debug during compilation
464
+ const debugCtx = new CodegenContext(true, true, true); // debug = true
465
+ const parser = CodegenGrammar.compile(grammar, debugCtx);
466
+
467
+ // Create trace collection
468
+ const rootTrace = {pos: 0, children: []};
469
+ const parseCtx = new ParseContext('input text', false, [rootTrace]);
470
+
471
+ // Parse with debug trace
472
+ const cst = parser(parseCtx, 0);
473
+
474
+ // Print debug trace
475
+ import {printTraceNode} from 'jit-parser';
476
+ console.log(printTraceNode(rootTrace, '', 'input text'));
477
+ ```
478
+
479
+ ### Debug Trace Output
480
+
481
+ The debug trace shows:
482
+ - Which grammar rules were attempted
483
+ - At what positions in the input
484
+ - Whether each attempt succeeded or failed
485
+ - The hierarchical structure of rule attempts
486
+
487
+ **Example trace output:**
488
+ ```
489
+ Root
490
+ └─ Value 0:22 → ' {"foo": ["bar", 123]}'
491
+ ├─ WOpt 0:1 → " "
492
+ ├─ TValue 1:22 → '{"foo": ["bar", 123]}'
493
+ │ ├─ Null
494
+ │ ├─ Boolean
495
+ │ ├─ String
496
+ │ └─ Object 1:22 → '{"foo": ["bar", 123]}'
497
+ │ ├─ Text 1:2 → "{"
498
+ │ ├─ Members 2:21 → '"foo": ["bar", 123]'
499
+ │ │ └─ Production 2:21 → '"foo": ["bar", 123]'
500
+ │ │ ├─ Entry 2:21 → '"foo": ["bar", 123]'
501
+ │ │ │ ├─ String 2:7 → '"foo"'
502
+ │ │ │ ├─ Text 7:8 → ":"
503
+ │ │ │ └─ Value 8:21 → ' ["bar", 123]'
504
+ │ │ │ └─ ...
505
+ │ │ └─ List 21:21 → ""
506
+ │ └─ Text 21:22 → "}"
507
+ └─ WOpt 22:22 → ""
508
+ ```
509
+
510
+ ## Testing
511
+
512
+ Because a JSON Grammar is portable data, its tests can be too. Grammars are
513
+ tested with a small, standardized schema where each test is written as JSON — an
514
+ input plus the expected output (AST, CST, trace, consumed length, and more). The
515
+ same test files work across programming languages and across test runners, so
516
+ you develop a grammar by editing just two things: the grammar and its tests.
517
+
518
+ See [docs/testing.md](docs/testing.md) for an introduction.
519
+
520
+ ## Examples
521
+
522
+ ### 1. Simple Expression Parser
523
+
524
+ ```typescript
525
+ const exprGrammar = {
526
+ start: 'Expression',
527
+ cst: {
528
+ Expression: {r: 'Number'},
529
+ Number: {
530
+ t: /\d+/,
531
+ type: 'Number'
532
+ }
533
+ }
534
+ };
535
+
536
+ const parser = CodegenGrammar.compile(exprGrammar);
537
+ const ctx = new ParseContext('42', true);
538
+ const cst = parser(ctx, 0);
539
+ const ast = cst.ptr.toAst(cst, '42');
540
+ console.log(ast); // {type: 'Number', pos: 0, end: 2, raw: '42'}
541
+ ```
542
+
543
+ ### 2. JSON Parser
544
+
545
+ ```typescript
546
+ import {grammar as jsonGrammar} from 'jit-parser/lib/grammars/json';
547
+
548
+ const parser = CodegenGrammar.compile(jsonGrammar);
549
+ const json = '{"name": "John", "age": 30}';
550
+ const ctx = new ParseContext(json, true);
551
+ const cst = parser(ctx, 0);
552
+ const ast = cst.ptr.toAst(cst, json);
553
+ console.log(ast);
554
+ ```
555
+
556
+ ### 3. Custom AST Transformation
557
+
558
+ ```typescript
559
+ const grammar = {
560
+ start: 'KeyValue',
561
+ cst: {
562
+ KeyValue: {
563
+ p: [{r: 'Key'}, '=', {r: 'Value'}],
564
+ children: {0: 'key', 2: 'value'},
565
+ type: 'Assignment'
566
+ },
567
+ Key: /[a-zA-Z]+/,
568
+ Value: /\d+/
569
+ },
570
+ ast: {
571
+ KeyValue: {
572
+ type: 'Assignment',
573
+ key: ['$', '/children/0/raw'],
574
+ value: ['num', ['$', '/children/2/raw']]
575
+ }
576
+ }
577
+ };
578
+ ```
579
+
580
+ ### 4. List Parsing
581
+
582
+ ```typescript
583
+ const listGrammar = {
584
+ start: 'List',
585
+ cst: {
586
+ List: ['[', {r: 'Items'}, ']'],
587
+ Items: {
588
+ u: [
589
+ {
590
+ p: [{r: 'Item'}, {l: {p: [',', {r: 'Item'}], ast: ['$', '/children/1']}}],
591
+ ast: ['concat', ['push', [[]], ['$', '/children/0']], ['$', '/children/1']]
592
+ },
593
+ '' // Empty list
594
+ ]
595
+ },
596
+ Item: /\w+/
597
+ }
598
+ };
599
+ ```
600
+
601
+ ## API Reference
602
+
603
+ ### Core Classes
604
+
605
+ #### `CodegenGrammar`
606
+ - `static compile(grammar: Grammar, ctx?: CodegenContext): Parser`
607
+ - `compileRule(ruleName: string): Pattern`
608
+
609
+ #### `ParseContext`
610
+ - `constructor(str: string, ast: boolean, trace?: RootTraceNode[])`
611
+
612
+ #### `CodegenContext`
613
+ - `constructor(positions: boolean, astExpressions: boolean, debug: boolean)`
614
+
615
+ #### `GrammarPrinter`
616
+ - `static print(grammar: Grammar, tab?: string): string`
617
+
618
+ ### Utility Functions
619
+
620
+ #### `printCst(cst: CstNode, tab: string, src: string): string`
621
+ Print a formatted CST tree
622
+
623
+ #### `printTraceNode(trace: RootTraceNode | ParseTraceNode, tab: string, src: string): string`
624
+ Print a formatted debug trace
625
+
626
+ ### Type Definitions
627
+
628
+ See the [Grammar Node Types](#grammar-node-types) section for complete interface definitions.
629
+
630
+ ---
631
+
632
+ This parser generator provides a powerful and efficient way to build custom parsers with minimal code while maintaining high performance through JIT compilation.
@@ -0,0 +1,14 @@
1
+ import { Codegen } from '@jsonjoy.com/util/lib/codegen';
2
+ import { CodegenContext } from '../context';
3
+ import { Pattern } from './Pattern';
4
+ import type { AstNodeFactory, ResolvedGrammarNode } from '../types';
5
+ export declare class CodegenAstFactory {
6
+ protected readonly node: ResolvedGrammarNode;
7
+ protected readonly ptr: Pattern;
8
+ protected readonly ctx: CodegenContext;
9
+ static readonly compile: (node: ResolvedGrammarNode, ptr: Pattern, ctx?: CodegenContext) => AstNodeFactory;
10
+ readonly codegen: Codegen<AstNodeFactory>;
11
+ constructor(node: ResolvedGrammarNode, ptr: Pattern, ctx: CodegenContext);
12
+ generate(): void;
13
+ compile(): AstNodeFactory;
14
+ }