parseman 0.46.0 → 0.47.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/README.md +8 -3
- package/dist/analysis/choice-cost-render.d.ts +12 -4
- package/dist/analysis/choice-cost-render.d.ts.map +1 -1
- package/dist/analysis/choice-cost.d.ts +2 -2
- package/dist/analysis/choice-cost.d.ts.map +1 -1
- package/dist/analysis/commitment.d.ts +131 -0
- package/dist/analysis/commitment.d.ts.map +1 -0
- package/dist/analysis/diagnostics.cjs +9929 -7465
- package/dist/analysis/diagnostics.cjs.map +3 -4
- package/dist/analysis/diagnostics.d.ts +2 -2
- package/dist/analysis/diagnostics.js +9929 -7465
- package/dist/analysis/diagnostics.js.map +3 -4
- package/dist/analysis/duplication.d.ts.map +1 -1
- package/dist/analysis/fix.d.ts +3 -3
- package/dist/analysis/fix.d.ts.map +1 -1
- package/dist/analysis/format-number.d.ts +23 -0
- package/dist/analysis/format-number.d.ts.map +1 -0
- package/dist/analysis/gating.d.ts +39 -2
- package/dist/analysis/gating.d.ts.map +1 -1
- package/dist/analysis/rebuild.d.ts.map +1 -1
- package/dist/analysis/terminal.d.ts +5 -2
- package/dist/analysis/terminal.d.ts.map +1 -1
- package/dist/cli/index.cjs +10865 -8535
- package/dist/cli/index.cjs.map +3 -4
- package/dist/cli/index.js +10865 -8535
- package/dist/cli/index.js.map +3 -4
- package/dist/combinators/adjacency.d.ts +100 -0
- package/dist/combinators/adjacency.d.ts.map +1 -0
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/completions.d.ts.map +1 -1
- package/dist/combinators/dispatch.d.ts +8 -1
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/gate.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts +22 -0
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts +8 -0
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/map.d.ts +0 -1
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/node.d.ts +13 -3
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +1 -1
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/ref.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts +1 -16
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts +30 -2
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/combinators/scanTo.d.ts +71 -1
- package/dist/combinators/scanTo.d.ts.map +1 -1
- package/dist/combinators/sequence.d.ts.map +1 -1
- package/dist/combinators/token.d.ts.map +1 -1
- package/dist/combinators/trivia-boundary.d.ts +26 -0
- package/dist/combinators/trivia-boundary.d.ts.map +1 -0
- package/dist/combinators/trivia-skip.d.ts +40 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/combinators/withCtx.d.ts.map +1 -1
- package/dist/compiler/compile-linkable-table.d.ts +104 -0
- package/dist/compiler/compile-linkable-table.d.ts.map +1 -0
- package/dist/compiler/degradation.d.ts +0 -2
- package/dist/compiler/degradation.d.ts.map +1 -1
- package/dist/compiler/fields.d.ts +13 -0
- package/dist/compiler/fields.d.ts.map +1 -1
- package/dist/compiler/grammar-coverage-ids.d.ts +5 -5
- package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +47 -53
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +81 -0
- package/dist/compiler/token-alphabet.d.ts.map +1 -0
- package/dist/compiler/token-dispatch.d.ts +95 -0
- package/dist/compiler/token-dispatch.d.ts.map +1 -0
- package/dist/compiler/token-scanner.d.ts +53 -0
- package/dist/compiler/token-scanner.d.ts.map +1 -0
- package/dist/compiler/value-usage.d.ts.map +1 -1
- package/dist/coverage.d.ts +1 -1
- package/dist/coverage.d.ts.map +1 -1
- package/dist/cst/capture-buffer.d.ts +35 -0
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/cst/reflection-attach.d.ts +8 -0
- package/dist/cst/reflection-attach.d.ts.map +1 -0
- package/dist/cst/reflection-symbols.d.ts +10 -0
- package/dist/cst/reflection-symbols.d.ts.map +1 -0
- package/dist/cst/reflection.d.ts +2 -4
- package/dist/cst/reflection.d.ts.map +1 -1
- package/dist/cst/root-trivia-scope.d.ts +26 -0
- package/dist/cst/root-trivia-scope.d.ts.map +1 -0
- package/dist/cst/trivia-charscan.d.ts +18 -0
- package/dist/cst/trivia-charscan.d.ts.map +1 -0
- package/dist/cst/trivia-kinds.d.ts +19 -0
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/functional/doc.d.ts.map +1 -1
- package/dist/functional/run-tabled.d.ts +12 -0
- package/dist/functional/run-tabled.d.ts.map +1 -0
- package/dist/functional/run.d.ts +25 -42
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/grammar-metadata.d.ts +3 -0
- package/dist/grammar-metadata.d.ts.map +1 -0
- package/dist/index.cjs +9224 -7203
- package/dist/index.cjs.map +3 -4
- package/dist/index.d.ts +18 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9219 -7198
- package/dist/index.js.map +3 -4
- package/dist/language-service/index.cjs +311 -121
- package/dist/language-service/index.cjs.map +3 -4
- package/dist/language-service/index.js +311 -121
- package/dist/language-service/index.js.map +3 -4
- package/dist/oracle/index.cjs.map +0 -1
- package/dist/oracle/index.js.map +0 -1
- package/dist/parse-context.d.ts +49 -0
- package/dist/parse-context.d.ts.map +1 -0
- package/dist/plugin/evaluator.d.ts +40 -1
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +11146 -9593
- package/dist/plugin/index.cjs.map +3 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +11146 -9593
- package/dist/plugin/index.js.map +3 -4
- package/dist/regex/classes.d.ts +28 -0
- package/dist/regex/classes.d.ts.map +1 -1
- package/dist/regex/first-set.d.ts +14 -0
- package/dist/regex/first-set.d.ts.map +1 -1
- package/dist/run/index.cjs +136 -51
- package/dist/run/index.cjs.map +2 -3
- package/dist/run/index.js +136 -51
- package/dist/run/index.js.map +2 -3
- package/dist/spec/index.cjs +2898 -1623
- package/dist/spec/index.cjs.map +3 -4
- package/dist/spec/index.js +2898 -1623
- package/dist/spec/index.js.map +3 -4
- package/dist/spec/model.d.ts +8 -0
- package/dist/spec/model.d.ts.map +1 -1
- package/dist/table/assemble.d.ts +307 -0
- package/dist/table/assemble.d.ts.map +1 -0
- package/dist/table/cell.d.ts +42 -0
- package/dist/table/cell.d.ts.map +1 -0
- package/dist/table/child-slots.d.ts +30 -0
- package/dist/table/child-slots.d.ts.map +1 -0
- package/dist/table/compile-rule-map.d.ts +136 -0
- package/dist/table/compile-rule-map.d.ts.map +1 -0
- package/dist/table/compile.d.ts +56 -0
- package/dist/table/compile.d.ts.map +1 -0
- package/dist/table/duplication-hook.d.ts +32 -0
- package/dist/table/duplication-hook.d.ts.map +1 -0
- package/dist/table/emit-assembly.d.ts +139 -0
- package/dist/table/emit-assembly.d.ts.map +1 -0
- package/dist/table/emit.d.ts +113 -0
- package/dist/table/emit.d.ts.map +1 -0
- package/dist/table/encode-baseline.d.ts +16 -0
- package/dist/table/encode-baseline.d.ts.map +1 -0
- package/dist/table/encode.d.ts +71 -0
- package/dist/table/encode.d.ts.map +1 -0
- package/dist/table/exec-baseline.d.ts +9 -0
- package/dist/table/exec-baseline.d.ts.map +1 -0
- package/dist/table/exec.d.ts +72 -0
- package/dist/table/exec.d.ts.map +1 -0
- package/dist/table/fold.d.ts +25 -0
- package/dist/table/fold.d.ts.map +1 -0
- package/dist/table/index.cjs +11375 -0
- package/dist/table/index.cjs.map +6 -0
- package/dist/table/index.d.ts +100 -0
- package/dist/table/index.d.ts.map +1 -0
- package/dist/table/index.js +11352 -0
- package/dist/table/index.js.map +6 -0
- package/dist/table/inspect.d.ts +17 -0
- package/dist/table/inspect.d.ts.map +1 -0
- package/dist/table/ops.d.ts +446 -0
- package/dist/table/ops.d.ts.map +1 -0
- package/dist/table/program.d.ts +493 -0
- package/dist/table/program.d.ts.map +1 -0
- package/dist/table/run-support.d.ts +38 -0
- package/dist/table/run-support.d.ts.map +1 -0
- package/dist/{compiler/scannable-run.d.ts → table/scan-shapes.d.ts} +14 -13
- package/dist/table/scan-shapes.d.ts.map +1 -0
- package/dist/table/site-labels.d.ts +58 -0
- package/dist/table/site-labels.d.ts.map +1 -0
- package/dist/table/stamp.d.ts +70 -0
- package/dist/table/stamp.d.ts.map +1 -0
- package/dist/types.d.ts +80 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +25 -2
- package/src/analysis/choice-cost-gate.ts +359 -0
- package/src/analysis/choice-cost-render.ts +293 -0
- package/src/analysis/choice-cost.ts +1008 -0
- package/src/analysis/commitment.ts +557 -0
- package/src/analysis/corpus.ts +130 -0
- package/src/analysis/diagnose-render.ts +625 -0
- package/src/analysis/diagnose.ts +317 -0
- package/src/analysis/diagnostics.ts +33 -0
- package/src/analysis/duplication.ts +1955 -0
- package/src/analysis/fix-render.ts +217 -0
- package/src/analysis/fix.ts +669 -0
- package/src/analysis/format-number.ts +31 -0
- package/src/analysis/gating.ts +792 -0
- package/src/analysis/grammar.ts +72 -0
- package/src/analysis/rebuild.ts +287 -0
- package/src/analysis/terminal.ts +336 -0
- package/src/cli/index.ts +413 -0
- package/src/combinators/adjacency.ts +171 -0
- package/src/combinators/attempt.ts +41 -0
- package/src/combinators/case-fold.ts +90 -0
- package/src/combinators/choice.ts +466 -0
- package/src/combinators/completions.ts +64 -0
- package/src/combinators/dispatch.ts +358 -0
- package/src/combinators/expect.ts +159 -0
- package/src/combinators/first-set.ts +322 -0
- package/src/combinators/gate.ts +50 -0
- package/src/combinators/grammar.ts +272 -0
- package/src/combinators/keywords.ts +145 -0
- package/src/combinators/literal.ts +102 -0
- package/src/combinators/map.ts +106 -0
- package/src/combinators/node.ts +345 -0
- package/src/combinators/not.ts +55 -0
- package/src/combinators/parser.ts +266 -0
- package/src/combinators/peek.ts +63 -0
- package/src/combinators/probe.ts +25 -0
- package/src/combinators/ref.ts +109 -0
- package/src/combinators/regex.ts +170 -0
- package/src/combinators/repeat.ts +561 -0
- package/src/combinators/scanTo.ts +393 -0
- package/src/combinators/sequence.ts +221 -0
- package/src/combinators/token.ts +120 -0
- package/src/combinators/trivia-boundary.ts +48 -0
- package/src/combinators/trivia-skip.ts +821 -0
- package/src/combinators/withCtx.ts +45 -0
- package/src/compiler/build-arity.ts +330 -0
- package/src/compiler/compile-linkable-table.ts +209 -0
- package/src/compiler/degradation.ts +266 -0
- package/src/compiler/fields.ts +191 -0
- package/src/compiler/grammar-coverage-ids.ts +129 -0
- package/src/compiler/ir-serialize.ts +615 -0
- package/src/compiler/linker.ts +954 -0
- package/src/compiler/token-alphabet.ts +209 -0
- package/src/compiler/token-dispatch.ts +353 -0
- package/src/compiler/token-scanner.ts +318 -0
- package/src/compiler/value-usage.ts +147 -0
- package/src/coverage.ts +383 -0
- package/src/cst/capture-buffer.ts +297 -0
- package/src/cst/host-mode.ts +69 -0
- package/src/cst/reflection-attach.ts +11 -0
- package/src/cst/reflection-symbols.ts +9 -0
- package/src/cst/reflection.ts +149 -0
- package/src/cst/relative-spans.ts +207 -0
- package/src/cst/root-trivia-scope.ts +30 -0
- package/src/cst/trivia-charscan.ts +312 -0
- package/src/cst/trivia-entries.ts +285 -0
- package/src/cst/trivia-index.ts +131 -0
- package/src/cst/trivia-kinds.ts +358 -0
- package/src/cst/types.ts +76 -0
- package/src/cst/walk.ts +101 -0
- package/src/functional/doc.ts +959 -0
- package/src/functional/run-tabled.ts +153 -0
- package/src/functional/run.ts +558 -0
- package/src/grammar-metadata.ts +2 -0
- package/src/index.ts +189 -0
- package/src/language-service/index.ts +221 -0
- package/src/line-index.ts +131 -0
- package/src/oracle/digest.ts +620 -0
- package/src/oracle/index.ts +55 -0
- package/src/parse-context.ts +91 -0
- package/src/plugin/direct-builder-static.ts +102 -0
- package/src/plugin/evaluator.ts +1505 -0
- package/src/plugin/free-identifiers.ts +338 -0
- package/src/plugin/index.ts +2281 -0
- package/src/plugin/reducer-resolver.ts +606 -0
- package/src/recovery/scan.ts +155 -0
- package/src/regex/classes.ts +183 -0
- package/src/regex/first-set.ts +316 -0
- package/src/run/index.ts +31 -0
- package/src/spec/ebnf.ts +128 -0
- package/src/spec/index.ts +54 -0
- package/src/spec/model.ts +636 -0
- package/src/spec/railroad-lib.ts +559 -0
- package/src/spec/railroad.ts +256 -0
- package/src/table/assemble.ts +2994 -0
- package/src/table/cell.ts +42 -0
- package/src/table/child-slots.ts +113 -0
- package/src/table/compile-rule-map.ts +336 -0
- package/src/table/compile.ts +244 -0
- package/src/table/duplication-hook.ts +89 -0
- package/src/table/emit-assembly.ts +1766 -0
- package/src/table/emit.ts +418 -0
- package/src/table/encode-baseline.ts +340 -0
- package/src/table/encode.ts +1569 -0
- package/src/table/exec-baseline.ts +537 -0
- package/src/table/exec.ts +1672 -0
- package/src/table/fold.ts +38 -0
- package/src/table/index.ts +108 -0
- package/src/table/inspect.ts +52 -0
- package/src/table/ops.ts +459 -0
- package/src/table/program.ts +855 -0
- package/src/table/run-support.ts +66 -0
- package/src/table/scan-shapes.ts +1578 -0
- package/src/table/site-labels.ts +228 -0
- package/src/table/stamp.ts +229 -0
- package/src/types.ts +563 -0
- package/src/version.ts +16 -0
- package/dist/compiler/codegen.d.ts +0 -334
- package/dist/compiler/codegen.d.ts.map +0 -1
- package/dist/compiler/inline-build.d.ts +0 -11
- package/dist/compiler/inline-build.d.ts.map +0 -1
- package/dist/compiler/inline-callback.d.ts +0 -21
- package/dist/compiler/inline-callback.d.ts.map +0 -1
- package/dist/compiler/line-index.d.ts +0 -2
- package/dist/compiler/line-index.d.ts.map +0 -1
- package/dist/compiler/module-hoist.d.ts +0 -106
- package/dist/compiler/module-hoist.d.ts.map +0 -1
- package/dist/compiler/scannable-run.d.ts.map +0 -1
- package/dist/compiler/scannable-terminal.d.ts +0 -23
- package/dist/compiler/scannable-terminal.d.ts.map +0 -1
- package/dist/compiler/trivia-fast-path.d.ts +0 -38
- package/dist/compiler/trivia-fast-path.d.ts.map +0 -1
package/src/spec/ebnf.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EBNF (W3C-style) text emitter for the grammar spec model.
|
|
3
|
+
*
|
|
4
|
+
* Precedence, lowest → highest: alternation (`|`) < concatenation (space) <
|
|
5
|
+
* postfix (`* + ?`) < atom. The renderer parenthesizes only where a lower-
|
|
6
|
+
* precedence construct sits inside a higher-precedence one.
|
|
7
|
+
*/
|
|
8
|
+
import type { Production, SpecModel, SpecNode } from './model.ts'
|
|
9
|
+
|
|
10
|
+
const ALT = 1 // choice
|
|
11
|
+
const CAT = 2 // sequence
|
|
12
|
+
const ATOM = 3 // terminal, ref, postfix, parenthesized
|
|
13
|
+
|
|
14
|
+
function quote(s: string): string {
|
|
15
|
+
// W3C EBNF uses quoted string terminals; prefer double quotes, fall back to
|
|
16
|
+
// single quotes when the literal itself contains a double quote.
|
|
17
|
+
if (s.includes('"') && !s.includes("'")) return `'${s}'`
|
|
18
|
+
return `"${s.replace(/"/g, '\\"')}"`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function wrap(inner: string, innerLevel: number, minLevel: number): string {
|
|
22
|
+
return innerLevel < minLevel ? `(${inner})` : inner
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Postfix repetition operator for an item count of `min..max`. The unbounded
|
|
27
|
+
* counts keep their familiar `* + ?` spelling; a genuinely bounded repeat gets
|
|
28
|
+
* the regex-style `{n,m}` form, since plain W3C EBNF has no way to say it and
|
|
29
|
+
* silently rendering `x{3,8}` as `x+` understates the grammar.
|
|
30
|
+
*/
|
|
31
|
+
function repeatOp(min: number, max: number | undefined): string {
|
|
32
|
+
if (max === undefined) {
|
|
33
|
+
if (min === 0) return '*'
|
|
34
|
+
if (min === 1) return '+'
|
|
35
|
+
return `{${min},}`
|
|
36
|
+
}
|
|
37
|
+
if (max === min) return min === 1 ? '' : `{${min}}`
|
|
38
|
+
if (min === 0 && max === 1) return '?'
|
|
39
|
+
return `{${min},${max}}`
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Render a node, returning its text and precedence level. */
|
|
43
|
+
function render(node: SpecNode): { text: string; level: number } {
|
|
44
|
+
switch (node.kind) {
|
|
45
|
+
case 'terminal':
|
|
46
|
+
return { text: node.literal ? quote(node.text) : node.text, level: ATOM }
|
|
47
|
+
case 'ref':
|
|
48
|
+
return { text: node.name, level: ATOM }
|
|
49
|
+
case 'empty':
|
|
50
|
+
return { text: '', level: ATOM }
|
|
51
|
+
case 'annotation':
|
|
52
|
+
return { text: `/* ${node.text} */`, level: ATOM }
|
|
53
|
+
|
|
54
|
+
case 'seq': {
|
|
55
|
+
const text = node.items
|
|
56
|
+
.map(it => {
|
|
57
|
+
const r = render(it)
|
|
58
|
+
return wrap(r.text, r.level, CAT)
|
|
59
|
+
})
|
|
60
|
+
.filter(t => t.length > 0)
|
|
61
|
+
.join(' ')
|
|
62
|
+
return { text, level: CAT }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
case 'choice': {
|
|
66
|
+
const text = node.items
|
|
67
|
+
.map(it => {
|
|
68
|
+
const r = render(it)
|
|
69
|
+
return r.text.length === 0 ? '/* empty */' : wrap(r.text, r.level, ALT)
|
|
70
|
+
})
|
|
71
|
+
.join(' | ')
|
|
72
|
+
return { text, level: ALT }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
case 'star':
|
|
76
|
+
case 'plus':
|
|
77
|
+
case 'opt': {
|
|
78
|
+
const r = render(node.item)
|
|
79
|
+
const op = node.kind === 'opt'
|
|
80
|
+
? '?'
|
|
81
|
+
: node.kind === 'star'
|
|
82
|
+
? repeatOp(0, node.max)
|
|
83
|
+
: repeatOp(node.min ?? 1, node.max)
|
|
84
|
+
return { text: `${wrap(r.text, r.level, ATOM)}${op}`, level: ATOM }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case 'sepBy': {
|
|
88
|
+
const item = render(node.item)
|
|
89
|
+
const sep = render(node.sep)
|
|
90
|
+
const itemA = wrap(item.text, item.level, ATOM)
|
|
91
|
+
const sepA = wrap(sep.text, sep.level, CAT)
|
|
92
|
+
// The tail repeats `(sep item)` ONE FEWER time than there are items, so the
|
|
93
|
+
// item bounds shift down by one to become the tail's bounds.
|
|
94
|
+
const tail = `(${sepA} ${itemA})${repeatOp(Math.max(node.min - 1, 0), node.max === undefined ? undefined : node.max - 1)}`
|
|
95
|
+
const trail = node.trailing === 'allow' ? ` ${sepA}?` : ''
|
|
96
|
+
const body = `${itemA} ${tail}${trail}`
|
|
97
|
+
// Only a min-0 list is OPTIONAL. Any `min >= 1` requires that many items and
|
|
98
|
+
// can never match empty — rendering it `( … )?` claimed the opposite.
|
|
99
|
+
return node.min === 0 ? { text: `(${body})?`, level: ATOM } : { text: body, level: CAT }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
case 'not': {
|
|
103
|
+
const r = render(node.item)
|
|
104
|
+
return { text: `!${wrap(r.text, r.level, ATOM)}`, level: ATOM }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// PEG notation: `&` positive lookahead, `!` negative.
|
|
108
|
+
case 'peek': {
|
|
109
|
+
const r = render(node.item)
|
|
110
|
+
return { text: `&${wrap(r.text, r.level, ATOM)}`, level: ATOM }
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function renderProduction(p: Production): string {
|
|
116
|
+
const { text } = render(p.expr)
|
|
117
|
+
return `${p.name} ::= ${text || '/* empty */'}`
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Render the whole spec model as EBNF text (one production per line). */
|
|
121
|
+
export function renderEBNF(model: SpecModel): string {
|
|
122
|
+
return model.productions.map(renderProduction).join('\n') + '\n'
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Render a single production's right-hand side (no `name ::=`). */
|
|
126
|
+
export function renderExpr(node: SpecNode): string {
|
|
127
|
+
return render(node).text
|
|
128
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `parseman/spec` — generate a formal grammar specification directly from a
|
|
3
|
+
* Parséman `rules()` grammar.
|
|
4
|
+
*
|
|
5
|
+
* Because the emitter walks the SAME `_def` combinator tree the interpreter and
|
|
6
|
+
* macro compiler consume, a generated spec is a single source of truth: it
|
|
7
|
+
* cannot disagree with what actually parses.
|
|
8
|
+
*
|
|
9
|
+
* import { toEBNF, toRailroadHtml } from 'parseman/spec'
|
|
10
|
+
*
|
|
11
|
+
* const grammar = rules(g => ({ ... })) // your grammar
|
|
12
|
+
* const ebnf = toEBNF(grammar) // EBNF text
|
|
13
|
+
* const html = toRailroadHtml(grammar) // self-contained syntax diagrams
|
|
14
|
+
*
|
|
15
|
+
* Scope: syntax only, not semantics. See docs/proposals/grammar-spec-generation.md.
|
|
16
|
+
*/
|
|
17
|
+
import { buildSpecModel } from './model.ts'
|
|
18
|
+
import type { GrammarInput, SpecModel, SpecOptions } from './model.ts'
|
|
19
|
+
import { renderEBNF } from './ebnf.ts'
|
|
20
|
+
import { renderRailroadHtml, renderRailroadSvg } from './railroad.ts'
|
|
21
|
+
import type { RailroadHtmlOptions } from './railroad.ts'
|
|
22
|
+
|
|
23
|
+
export { buildSpecModel } from './model.ts'
|
|
24
|
+
export type { GrammarInput, SpecModel, SpecOptions, SpecNode, Production } from './model.ts'
|
|
25
|
+
export { renderEBNF, renderExpr } from './ebnf.ts'
|
|
26
|
+
export { renderRailroadHtml, renderRailroadSvg } from './railroad.ts'
|
|
27
|
+
export type { RailroadHtmlOptions, RailroadSvg } from './railroad.ts'
|
|
28
|
+
export { RAILROAD_CSS } from './railroad-lib.ts'
|
|
29
|
+
|
|
30
|
+
/** Generate W3C-style EBNF text (one production per named rule). */
|
|
31
|
+
export function toEBNF(grammar: GrammarInput, options?: SpecOptions): string {
|
|
32
|
+
return renderEBNF(buildSpecModel(grammar, options))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Generate a self-contained HTML page of SVG railroad (syntax) diagrams — one
|
|
37
|
+
* per production — with an EBNF caption under each. No external dependencies.
|
|
38
|
+
*/
|
|
39
|
+
export function toRailroadHtml(
|
|
40
|
+
grammar: GrammarInput,
|
|
41
|
+
options?: SpecOptions & RailroadHtmlOptions,
|
|
42
|
+
): string {
|
|
43
|
+
const model: SpecModel = buildSpecModel(grammar, options)
|
|
44
|
+
return renderRailroadHtml(model, options)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Render each production to a static, self-contained SVG string — one per named
|
|
49
|
+
* rule — ready to inline in a docs page, README, or any HTML (no client script).
|
|
50
|
+
* Style with the exported `RAILROAD_CSS`, scoped to whatever wraps the SVGs.
|
|
51
|
+
*/
|
|
52
|
+
export function toRailroadSvg(grammar: GrammarInput, options?: SpecOptions): ReturnType<typeof renderRailroadSvg> {
|
|
53
|
+
return renderRailroadSvg(buildSpecModel(grammar, options))
|
|
54
|
+
}
|