effect-grammar 0.2.0 → 0.4.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 +75 -136
- package/dist/ast.d.ts +115 -0
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +253 -0
- package/dist/ast.js.map +1 -0
- package/dist/combinators.d.ts +66 -21
- package/dist/combinators.d.ts.map +1 -1
- package/dist/combinators.js +150 -47
- package/dist/combinators.js.map +1 -1
- package/dist/core.d.ts +111 -39
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +24 -20
- package/dist/core.js.map +1 -1
- package/dist/env.d.ts +20 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +63 -0
- package/dist/env.js.map +1 -0
- package/dist/errors.d.ts +34 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +37 -4
- package/dist/errors.js.map +1 -1
- package/dist/gen.d.ts +7 -0
- package/dist/gen.d.ts.map +1 -0
- package/dist/gen.js +200 -0
- package/dist/gen.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +152 -114
- package/dist/parse.js.map +1 -1
- package/dist/pattern.d.ts +5 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +46 -0
- package/dist/pattern.js.map +1 -0
- package/dist/print.d.ts +2 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +201 -89
- package/dist/print.js.map +1 -1
- package/dist/recovery.d.ts +10 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +296 -0
- package/dist/recovery.js.map +1 -0
- package/dist/render.d.ts +4 -4
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +133 -42
- package/dist/render.js.map +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +12 -5
- package/dist/schema.js.map +1 -1
- package/package.json +32 -16
package/README.md
CHANGED
|
@@ -1,167 +1,106 @@
|
|
|
1
1
|
# effect-grammar
|
|
2
2
|
|
|
3
|
-
Invertible grammar combinators and parser-printers for Effect.
|
|
4
|
-
|
|
5
|
-
Schema models your structured data. `effect-grammar` models the text formats
|
|
6
|
-
inside your strings: connection strings, duration strings (`1h30m`), cron
|
|
7
|
-
expressions, search queries, or DSLs.
|
|
8
|
-
|
|
9
|
-
You write the grammar definition once. You get four outputs:
|
|
10
|
-
|
|
11
|
-
- **A Parser**: Reads text and outputs structured data with line and column
|
|
12
|
-
error messages.
|
|
13
|
-
- **A Printer**: Converts structured data back to canonical text.
|
|
14
|
-
- **A `Schema.Codec<A, string>`**: Integrates directly with Effect Schema
|
|
15
|
-
(`decode` parses, `encode` prints, and Schema refinements compose).
|
|
16
|
-
- **A Text Renderer**: Formats the grammar as readable text for documentation
|
|
17
|
-
and schema descriptions.
|
|
18
|
-
|
|
19
|
-
## Why effect-grammar?
|
|
20
|
-
|
|
21
|
-
- **`Schema.transformOrFail`**: Requires you to write and maintain both `decode`
|
|
22
|
-
and `encode` functions manually.
|
|
23
|
-
- **`Schema.TemplateLiteralParser`**: Supports only flat `${a}-${b}` string
|
|
24
|
-
patterns.
|
|
25
|
-
- **`effect-grammar`**: Automatically derives the parser and printer for formats
|
|
26
|
-
with optional parts, repetition, alternation, and recursion.
|
|
27
|
-
|
|
28
|
-
This is for format strings, not documents. The parser backtracks with no
|
|
29
|
-
memoization and no left recursion. Printing is canonical, not pretty.
|
|
30
|
-
|
|
31
|
-
## Install
|
|
32
|
-
|
|
33
3
|
```bash
|
|
34
4
|
pnpm add effect-grammar
|
|
35
5
|
```
|
|
36
6
|
|
|
37
|
-
|
|
7
|
+
Invertible grammar combinators and parser-printers for Effect.
|
|
8
|
+
|
|
9
|
+
A `Grammar<A>` supports four operations:
|
|
38
10
|
|
|
39
|
-
|
|
11
|
+
- `parse`: read a string and return a `Result<A, ParseError>`
|
|
12
|
+
- `print`: write an `A` as canonical text and return a
|
|
13
|
+
`Result<string, PrintError>`
|
|
14
|
+
- `codec`: combine the grammar with an Effect Schema to make a string codec
|
|
15
|
+
- `render`: return a readable description of the grammar
|
|
40
16
|
|
|
41
17
|
```ts
|
|
42
18
|
import { Schema } from "effect"
|
|
43
|
-
import * as
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
yield*
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"port",
|
|
50
|
-
Grammar.optional(Grammar.prefix(":", Grammar.integer)),
|
|
19
|
+
import * as G from "effect-grammar"
|
|
20
|
+
|
|
21
|
+
const frame = G.gen(function* () {
|
|
22
|
+
const kind = yield* G.choice(
|
|
23
|
+
G.literal("text").pipe(G.as("text")),
|
|
24
|
+
G.literal("bits").pipe(G.as("bits")),
|
|
51
25
|
)
|
|
52
|
-
|
|
26
|
+
yield* G.literal("/")
|
|
27
|
+
const size = yield* G.integer
|
|
28
|
+
yield* G.literal(":")
|
|
29
|
+
const body = yield* G.match(kind, {
|
|
30
|
+
text: G.take(size),
|
|
31
|
+
bits: G.repeat(G.regex(/[01]/, "bit"), size),
|
|
32
|
+
})
|
|
33
|
+
return { kind, size, body }
|
|
53
34
|
})
|
|
54
35
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// Result.succeed("https://effect.website:443")
|
|
61
|
-
Grammar.render(endpoint)
|
|
62
|
-
// "https://" host:<host> port:(":" <integer>)?
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
A silent grammar (`literal`, `symbol`, `whitespace`, anything under `skip`)
|
|
66
|
-
carries no value and can be `yield*`-ed bare. A value grammar goes through
|
|
67
|
-
`field(name, g)`.
|
|
68
|
-
|
|
69
|
-
`print` replays the generator. It reads each field from `value[name]` and passes
|
|
70
|
-
that back as the `yield*` result. An `if` on a parsed value takes the same path
|
|
71
|
-
both ways. The generator's return must hold every field under its name, and the
|
|
72
|
-
types enforce it. Return nothing and you get the object of fields.
|
|
36
|
+
const FrameValue = Schema.Struct({
|
|
37
|
+
kind: Schema.Literals(["text", "bits"]),
|
|
38
|
+
size: Schema.Number,
|
|
39
|
+
body: Schema.Union([Schema.String, Schema.Array(Schema.String)]),
|
|
40
|
+
})
|
|
73
41
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
`undefined` takes, with no warning. Put the branch in `choice` instead, which
|
|
79
|
-
renders every option.
|
|
42
|
+
const Frame = G.codec(frame, FrameValue, { identifier: "Frame" })
|
|
43
|
+
const decode = Schema.decodeSync(Frame)
|
|
44
|
+
const encode = Schema.encodeSync(Frame)
|
|
45
|
+
```
|
|
80
46
|
|
|
81
|
-
|
|
82
|
-
part:
|
|
47
|
+
The grammar and its Schema codec use the same parser and printer:
|
|
83
48
|
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Grammar.symbol(":"),
|
|
88
|
-
Grammar.field("value", jsonValue),
|
|
89
|
-
)
|
|
90
|
-
// Grammar<{ key: string; value: Json }>
|
|
91
|
-
```
|
|
49
|
+
```text
|
|
50
|
+
decode("text/5:hello") → { kind: "text", size: 5, body: "hello" }
|
|
51
|
+
decode("bits/4:1010") → { kind: "bits", size: 4, body: ["1", "0", "1", "0"] }
|
|
92
52
|
|
|
93
|
-
|
|
53
|
+
encode({ kind: "text", size: 2, body: "hi" }) → "text/2:hi"
|
|
54
|
+
encode({ kind: "bits", size: 4, body: ["1", "0", "1", "0"] }) → "bits/4:1010"
|
|
94
55
|
|
|
95
|
-
|
|
96
|
-
|
|
56
|
+
parse("bits/4:1020") → line 1, column 10: expected bit, found "2"
|
|
57
|
+
print({ kind: "text", size: 2, body: "hello" }) → .body: expected 2 UTF-16 code units, got "hello"
|
|
97
58
|
|
|
98
|
-
|
|
99
|
-
const Endpoint = Grammar.toSchema(
|
|
100
|
-
endpoint,
|
|
101
|
-
Schema.Struct({
|
|
102
|
-
host: Schema.NonEmptyString,
|
|
103
|
-
port: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 65535 })),
|
|
104
|
-
}),
|
|
105
|
-
{ identifier: "Endpoint" },
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
Schema.decodeUnknownSync(Endpoint)("https://effect.website:443")
|
|
109
|
-
// { host: "effect.website", port: 443 }
|
|
110
|
-
Schema.encodeSync(Endpoint)({ host: "effect.website", port: 443 })
|
|
111
|
-
// "https://effect.website:443"
|
|
59
|
+
render(frame) → kind:("text" | "bits") "/" size:<integer> ":" body:match(kind){"text" => <char>{size} | "bits" => (<bit>){size}}
|
|
112
60
|
```
|
|
113
61
|
|
|
114
|
-
##
|
|
115
|
-
|
|
116
|
-
`transform` maps a value both ways. `decodeTo` takes a Schema that types
|
|
117
|
-
`decode` and `encode` and checks the value on parse and on print. A `choice` of
|
|
118
|
-
Schema-typed branches picks the matching Schema when printing.
|
|
62
|
+
## Schema integration
|
|
119
63
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
Grammar.decodeTo(Num)({
|
|
124
|
-
decode: (value) => ({ kind: "num", value }),
|
|
125
|
-
encode: (n) => n.value,
|
|
126
|
-
}),
|
|
127
|
-
)
|
|
128
|
-
```
|
|
64
|
+
`codec` combines a grammar with an Effect Schema. Decoding parses the text and
|
|
65
|
+
then checks the value. Encoding checks the value and then prints it. The example
|
|
66
|
+
above shows the full integration in one code block.
|
|
129
67
|
|
|
130
|
-
|
|
131
|
-
boolean:
|
|
68
|
+
See the [endpoint example](./examples/endpoint.ts) for a complete Schema.
|
|
132
69
|
|
|
133
|
-
|
|
134
|
-
const jsonNull = Grammar.symbol("null").pipe(Grammar.as(null))
|
|
135
|
-
const negate = Grammar.flag("-")
|
|
136
|
-
```
|
|
70
|
+
## Main building blocks
|
|
137
71
|
|
|
138
|
-
|
|
72
|
+
| Purpose | Combinators |
|
|
73
|
+
| --------------------------- | -------------------------------------------------------- |
|
|
74
|
+
| Text | `literal`, `regex`, `integer`, `take`, `repeat` |
|
|
75
|
+
| Sequences and products | `gen`, `seq`, `struct`, `tuple` |
|
|
76
|
+
| Delimiters | `prefix`, `suffix`, `between`, `wrap` |
|
|
77
|
+
| Repetition and options | `optional`, `many`, `sepBy` |
|
|
78
|
+
| Alternatives | `choice`, `taggedChoice`, `match`, `matchValue` |
|
|
79
|
+
| Value conversion | `transform`, `transformOrFail`, `decodeTo`, `as`, `flag` |
|
|
80
|
+
| Defaults and ignored values | `defaulted`, `skip` |
|
|
81
|
+
| Whitespace | `lexeme`, `symbol`, `space`, `spaces`, `trivia` |
|
|
82
|
+
| Recursion | `suspend` |
|
|
139
83
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
() =>
|
|
143
|
-
Grammar.choice(
|
|
144
|
-
jsonNull,
|
|
145
|
-
jsonBool,
|
|
146
|
-
jsonNumber,
|
|
147
|
-
jsonString,
|
|
148
|
-
jsonArray,
|
|
149
|
-
jsonObject,
|
|
150
|
-
),
|
|
151
|
-
"value",
|
|
152
|
-
)
|
|
153
|
-
```
|
|
84
|
+
Most delimiter and repetition combinators support data-first and data-last
|
|
85
|
+
calls, so they also work with `pipe`.
|
|
154
86
|
|
|
155
|
-
|
|
156
|
-
search syntax.
|
|
87
|
+
## Results, errors, and rendering
|
|
157
88
|
|
|
158
|
-
|
|
89
|
+
`parse` and `print` return `Result` values. Parse errors report the furthest
|
|
90
|
+
text position, the expected forms, and the line and column. Print errors contain
|
|
91
|
+
a `PrintIssue` tree with paths, missing fields, failed branches, and value
|
|
92
|
+
mismatches. `PrintError.format` converts that tree to text.
|
|
159
93
|
|
|
160
|
-
`
|
|
161
|
-
everything that could have matched there:
|
|
94
|
+
`render` describes a complete grammar. `describe` returns a short grammar name.
|
|
162
95
|
|
|
163
|
-
|
|
164
|
-
line 1, column 7: expected one of "null", "true", "false", number, string, "[", "{", found end of input
|
|
165
|
-
```
|
|
96
|
+
## More examples
|
|
166
97
|
|
|
167
|
-
|
|
98
|
+
- [Postgres connection string](./examples/connection-string.ts): optional parts,
|
|
99
|
+
query parameters, Schema checks, encoding, and round trips
|
|
100
|
+
- [JSON](./examples/json.ts): a recursive grammar and Schema codec
|
|
101
|
+
- [Scheme](./examples/scheme.ts): recursive expressions, tokens, and canonical
|
|
102
|
+
whitespace
|
|
103
|
+
- [GitHub search](./examples/github-search.ts): a larger search-query DSL
|
|
104
|
+
- [IP address](./examples/ip.ts): transforms and Schema refinements
|
|
105
|
+
- [Printing showcase](./examples/printing.ts): parsing, printing, rendering, and
|
|
106
|
+
print failures
|
package/dist/ast.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { type GrammarInternal, type Value } from "./core.ts";
|
|
2
|
+
/**
|
|
3
|
+
* A JSON-shaped mirror of a grammar, produced by `toAst`. Scopes become stable
|
|
4
|
+
* names (`scope0`, `scope1`, …), a recursive `Suspend` is defined once and
|
|
5
|
+
* referenced by id at every other occurrence, and functions are described by
|
|
6
|
+
* name instead of being embedded. Constant values are kept as given, so the
|
|
7
|
+
* result is serializable for every value a grammar can legally hold.
|
|
8
|
+
*/
|
|
9
|
+
export interface RefAst {
|
|
10
|
+
readonly _tag: "Ref";
|
|
11
|
+
readonly scope: string;
|
|
12
|
+
readonly slot: number;
|
|
13
|
+
readonly name?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
export type ExprAst = RefAst | {
|
|
16
|
+
readonly _tag: "Prop";
|
|
17
|
+
readonly object: ExprAst;
|
|
18
|
+
readonly key: string | number;
|
|
19
|
+
};
|
|
20
|
+
export type PatternAst = RefAst | {
|
|
21
|
+
readonly _tag: "Const";
|
|
22
|
+
readonly value: Value;
|
|
23
|
+
} | {
|
|
24
|
+
readonly _tag: "Object";
|
|
25
|
+
readonly fields: ReadonlyArray<readonly [string, PatternAst]>;
|
|
26
|
+
} | {
|
|
27
|
+
readonly _tag: "Array";
|
|
28
|
+
readonly items: ReadonlyArray<PatternAst>;
|
|
29
|
+
};
|
|
30
|
+
export interface MatchCaseAst {
|
|
31
|
+
readonly key: string | number | boolean;
|
|
32
|
+
readonly grammar: GrammarAst;
|
|
33
|
+
}
|
|
34
|
+
export type StepAst = {
|
|
35
|
+
readonly _tag: "Silent";
|
|
36
|
+
readonly grammar: GrammarAst;
|
|
37
|
+
} | {
|
|
38
|
+
readonly _tag: "Bind";
|
|
39
|
+
readonly slot: number;
|
|
40
|
+
readonly name?: string | undefined;
|
|
41
|
+
readonly grammar: GrammarAst;
|
|
42
|
+
};
|
|
43
|
+
export type GrammarAst = {
|
|
44
|
+
readonly _tag: "Literal";
|
|
45
|
+
readonly value: string;
|
|
46
|
+
} | {
|
|
47
|
+
readonly _tag: "Regex";
|
|
48
|
+
readonly name: string;
|
|
49
|
+
readonly source: string;
|
|
50
|
+
readonly flags: string;
|
|
51
|
+
} | {
|
|
52
|
+
readonly _tag: "Gen";
|
|
53
|
+
readonly scope: string;
|
|
54
|
+
readonly slotCount: number;
|
|
55
|
+
readonly steps: ReadonlyArray<StepAst>;
|
|
56
|
+
readonly result: PatternAst;
|
|
57
|
+
} | {
|
|
58
|
+
readonly _tag: "Wrap";
|
|
59
|
+
readonly open: GrammarAst;
|
|
60
|
+
readonly inner: GrammarAst;
|
|
61
|
+
readonly close: GrammarAst;
|
|
62
|
+
} | {
|
|
63
|
+
readonly _tag: "Choice";
|
|
64
|
+
readonly options: ReadonlyArray<GrammarAst>;
|
|
65
|
+
} | {
|
|
66
|
+
readonly _tag: "Many";
|
|
67
|
+
readonly inner: GrammarAst;
|
|
68
|
+
readonly sep: GrammarAst;
|
|
69
|
+
readonly min: number;
|
|
70
|
+
readonly max: number | "∞";
|
|
71
|
+
} | {
|
|
72
|
+
readonly _tag: "Optional";
|
|
73
|
+
readonly inner: GrammarAst;
|
|
74
|
+
} | {
|
|
75
|
+
readonly _tag: "Transform";
|
|
76
|
+
readonly inner: GrammarAst;
|
|
77
|
+
readonly decode: string;
|
|
78
|
+
readonly encode: string;
|
|
79
|
+
readonly is?: string | undefined;
|
|
80
|
+
readonly name?: string | undefined;
|
|
81
|
+
} | {
|
|
82
|
+
readonly _tag: "Skip";
|
|
83
|
+
readonly inner: GrammarAst;
|
|
84
|
+
readonly printAs: Value;
|
|
85
|
+
readonly show: boolean;
|
|
86
|
+
} | {
|
|
87
|
+
readonly _tag: "Label";
|
|
88
|
+
readonly name: string;
|
|
89
|
+
readonly inner: GrammarAst;
|
|
90
|
+
} | {
|
|
91
|
+
readonly _tag: "Suspend";
|
|
92
|
+
readonly id: number;
|
|
93
|
+
readonly name?: string | undefined;
|
|
94
|
+
readonly body: GrammarAst;
|
|
95
|
+
} | {
|
|
96
|
+
readonly _tag: "SuspendRef";
|
|
97
|
+
readonly id: number;
|
|
98
|
+
readonly name?: string | undefined;
|
|
99
|
+
} | {
|
|
100
|
+
readonly _tag: "Match";
|
|
101
|
+
readonly scrutinee: ExprAst;
|
|
102
|
+
readonly cases: ReadonlyArray<MatchCaseAst>;
|
|
103
|
+
} | {
|
|
104
|
+
readonly _tag: "Take";
|
|
105
|
+
readonly count: ExprAst;
|
|
106
|
+
} | {
|
|
107
|
+
readonly _tag: "RepeatExact";
|
|
108
|
+
readonly count: ExprAst;
|
|
109
|
+
readonly inner: GrammarAst;
|
|
110
|
+
};
|
|
111
|
+
/** Reflects a grammar into a plain, JSON-shaped tree. */
|
|
112
|
+
export declare const toAst: (grammar: GrammarInternal) => GrammarAst;
|
|
113
|
+
/** Renders a grammar as an indented node tree, one line per AST node. */
|
|
114
|
+
export declare const renderAst: (grammar: GrammarInternal) => string;
|
|
115
|
+
//# sourceMappingURL=ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
|
package/dist/ast.js
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { Predicate } from "effect";
|
|
2
|
+
import { nodeOf, resolve, } from "./core.js";
|
|
3
|
+
import { preview } from "./errors.js";
|
|
4
|
+
import { nameBindings, namesFor } from "./render.js";
|
|
5
|
+
const scopeName = (context, scope) => {
|
|
6
|
+
const existing = context.scopes.get(scope);
|
|
7
|
+
if (existing !== undefined)
|
|
8
|
+
return existing;
|
|
9
|
+
const name = `scope${context.scopes.size}`;
|
|
10
|
+
context.scopes.set(scope, name);
|
|
11
|
+
return name;
|
|
12
|
+
};
|
|
13
|
+
const refAst = (expr, context) => {
|
|
14
|
+
const scope = scopeName(context, expr.scope);
|
|
15
|
+
const name = context.names.get(expr.scope)?.get(expr.slot);
|
|
16
|
+
if (name === undefined)
|
|
17
|
+
return { _tag: "Ref", scope, slot: expr.slot };
|
|
18
|
+
return { _tag: "Ref", scope, slot: expr.slot, name };
|
|
19
|
+
};
|
|
20
|
+
const keyAst = (key) => Predicate.isString(key) || Predicate.isNumber(key) ? key : preview(key);
|
|
21
|
+
const exprAst = (expr, context) => expr._tag === "Ref"
|
|
22
|
+
? refAst(expr, context)
|
|
23
|
+
: { _tag: "Prop", object: exprAst(expr.object, context), key: keyAst(expr.key) };
|
|
24
|
+
const patternAst = (pattern, context) => {
|
|
25
|
+
switch (pattern._tag) {
|
|
26
|
+
case "Ref":
|
|
27
|
+
return refAst(pattern, context);
|
|
28
|
+
case "Const":
|
|
29
|
+
return { _tag: "Const", value: pattern.value };
|
|
30
|
+
case "Object":
|
|
31
|
+
return {
|
|
32
|
+
_tag: "Object",
|
|
33
|
+
fields: pattern.fields.map(([key, field]) => [key, patternAst(field, context)]),
|
|
34
|
+
};
|
|
35
|
+
case "Array":
|
|
36
|
+
return { _tag: "Array", items: pattern.items.map((item) => patternAst(item, context)) };
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const fnName = (f) => (f.name === "" ? "<anonymous>" : f.name);
|
|
40
|
+
const stepAst = (step, context, names) => step._tag === "Silent"
|
|
41
|
+
? { _tag: "Silent", grammar: walk(step.grammar, context) }
|
|
42
|
+
: {
|
|
43
|
+
_tag: "Bind",
|
|
44
|
+
slot: step.slot,
|
|
45
|
+
name: names.get(step.slot),
|
|
46
|
+
grammar: walk(step.grammar, context),
|
|
47
|
+
};
|
|
48
|
+
const walk = (grammar, context) => {
|
|
49
|
+
const node = nodeOf(grammar);
|
|
50
|
+
switch (node._tag) {
|
|
51
|
+
case "Literal":
|
|
52
|
+
return { _tag: "Literal", value: node.value };
|
|
53
|
+
case "Regex":
|
|
54
|
+
return { _tag: "Regex", name: node.name, source: node.re.source, flags: node.re.flags };
|
|
55
|
+
case "Gen": {
|
|
56
|
+
const names = namesFor(context.names, node.scope);
|
|
57
|
+
nameBindings(node.result, undefined, node.scope, names);
|
|
58
|
+
const scope = scopeName(context, node.scope);
|
|
59
|
+
return {
|
|
60
|
+
_tag: "Gen",
|
|
61
|
+
scope,
|
|
62
|
+
slotCount: node.slotCount,
|
|
63
|
+
steps: node.steps.map((step) => stepAst(step, context, names)),
|
|
64
|
+
result: patternAst(node.result, context),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
case "Wrap":
|
|
68
|
+
return {
|
|
69
|
+
_tag: "Wrap",
|
|
70
|
+
open: walk(node.open, context),
|
|
71
|
+
inner: walk(node.inner, context),
|
|
72
|
+
close: walk(node.close, context),
|
|
73
|
+
};
|
|
74
|
+
case "Choice":
|
|
75
|
+
return { _tag: "Choice", options: node.options.map((option) => walk(option, context)) };
|
|
76
|
+
case "Many":
|
|
77
|
+
return {
|
|
78
|
+
_tag: "Many",
|
|
79
|
+
inner: walk(node.inner, context),
|
|
80
|
+
sep: walk(node.sep, context),
|
|
81
|
+
min: node.min,
|
|
82
|
+
max: node.max === Number.POSITIVE_INFINITY ? "∞" : node.max,
|
|
83
|
+
};
|
|
84
|
+
case "Optional":
|
|
85
|
+
return { _tag: "Optional", inner: walk(node.inner, context) };
|
|
86
|
+
case "Transform": {
|
|
87
|
+
const inner = walk(node.inner, context);
|
|
88
|
+
if (node.is === undefined) {
|
|
89
|
+
return {
|
|
90
|
+
_tag: "Transform",
|
|
91
|
+
inner,
|
|
92
|
+
decode: fnName(node.decode),
|
|
93
|
+
encode: fnName(node.encode),
|
|
94
|
+
name: node.name,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
_tag: "Transform",
|
|
99
|
+
inner,
|
|
100
|
+
decode: fnName(node.decode),
|
|
101
|
+
encode: fnName(node.encode),
|
|
102
|
+
is: fnName(node.is),
|
|
103
|
+
name: node.name,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
case "Skip":
|
|
107
|
+
return {
|
|
108
|
+
_tag: "Skip",
|
|
109
|
+
inner: walk(node.inner, context),
|
|
110
|
+
printAs: node.printAs,
|
|
111
|
+
show: node.show,
|
|
112
|
+
};
|
|
113
|
+
case "Label":
|
|
114
|
+
return { _tag: "Label", name: node.name, inner: walk(node.inner, context) };
|
|
115
|
+
case "Suspend": {
|
|
116
|
+
const existing = context.suspends.get(node);
|
|
117
|
+
if (existing !== undefined)
|
|
118
|
+
return { _tag: "SuspendRef", id: existing, name: node.name };
|
|
119
|
+
const id = context.suspends.size;
|
|
120
|
+
context.suspends.set(node, id);
|
|
121
|
+
return { _tag: "Suspend", id, name: node.name, body: walk(resolve(node), context) };
|
|
122
|
+
}
|
|
123
|
+
case "Match":
|
|
124
|
+
return {
|
|
125
|
+
_tag: "Match",
|
|
126
|
+
scrutinee: exprAst(node.scrutinee, context),
|
|
127
|
+
cases: node.cases.map((matchCase) => ({
|
|
128
|
+
key: matchCase.key,
|
|
129
|
+
grammar: walk(matchCase.grammar, context),
|
|
130
|
+
})),
|
|
131
|
+
};
|
|
132
|
+
case "Take":
|
|
133
|
+
return { _tag: "Take", count: exprAst(node.count, context) };
|
|
134
|
+
case "RepeatExact":
|
|
135
|
+
return {
|
|
136
|
+
_tag: "RepeatExact",
|
|
137
|
+
count: exprAst(node.count, context),
|
|
138
|
+
inner: walk(node.inner, context),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
/** Reflects a grammar into a plain, JSON-shaped tree. */
|
|
143
|
+
export const toAst = (grammar) => walk(grammar, { scopes: new Map(), names: new Map(), suspends: new Map() });
|
|
144
|
+
const formatValue = (value) => Predicate.isString(value) ? JSON.stringify(value) : preview(value);
|
|
145
|
+
const refText = (ref) => ref.name ?? `$${ref.slot}`;
|
|
146
|
+
const exprText = (expr) => {
|
|
147
|
+
if (expr._tag === "Ref")
|
|
148
|
+
return refText(expr);
|
|
149
|
+
const object = exprText(expr.object);
|
|
150
|
+
return Predicate.isString(expr.key) && /^[A-Za-z_$][\w$]*$/.test(expr.key)
|
|
151
|
+
? `${object}.${expr.key}`
|
|
152
|
+
: `${object}[${preview(expr.key)}]`;
|
|
153
|
+
};
|
|
154
|
+
const patternText = (pattern) => {
|
|
155
|
+
switch (pattern._tag) {
|
|
156
|
+
case "Ref":
|
|
157
|
+
return refText(pattern);
|
|
158
|
+
case "Const":
|
|
159
|
+
return formatValue(pattern.value);
|
|
160
|
+
case "Object":
|
|
161
|
+
return `{ ${pattern.fields.map(([key, field]) => `${key}: ${patternText(field)}`).join(", ")} }`;
|
|
162
|
+
case "Array":
|
|
163
|
+
return `[${pattern.items.map(patternText).join(", ")}]`;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const boundsText = (min, max) => {
|
|
167
|
+
if (max === "∞")
|
|
168
|
+
return min === 0 ? "*" : min === 1 ? "+" : `{${min},}`;
|
|
169
|
+
return min === max ? `{${min}}` : `{${min},${max}}`;
|
|
170
|
+
};
|
|
171
|
+
const headerOf = (ast) => {
|
|
172
|
+
switch (ast._tag) {
|
|
173
|
+
case "Literal":
|
|
174
|
+
return `Literal ${formatValue(ast.value)}`;
|
|
175
|
+
case "Regex":
|
|
176
|
+
return `Regex ${ast.name} /${ast.source}/${ast.flags}`;
|
|
177
|
+
case "Gen":
|
|
178
|
+
return `Gen ${ast.scope} → ${patternText(ast.result)}`;
|
|
179
|
+
case "Wrap":
|
|
180
|
+
return "Wrap";
|
|
181
|
+
case "Choice":
|
|
182
|
+
return "Choice";
|
|
183
|
+
case "Many":
|
|
184
|
+
return `Many ${boundsText(ast.min, ast.max)}`;
|
|
185
|
+
case "Optional":
|
|
186
|
+
return "Optional";
|
|
187
|
+
case "Transform":
|
|
188
|
+
return ast.name === undefined ? "Transform" : `Transform ${ast.name}`;
|
|
189
|
+
case "Skip":
|
|
190
|
+
return ast.show ? "Skip" : "Skip (hidden)";
|
|
191
|
+
case "Label":
|
|
192
|
+
return `Label ${ast.name}`;
|
|
193
|
+
case "Suspend":
|
|
194
|
+
return ast.name === undefined ? `Suspend #${ast.id}` : `Suspend #${ast.id} ${ast.name}`;
|
|
195
|
+
case "SuspendRef":
|
|
196
|
+
return ast.name === undefined ? `SuspendRef #${ast.id}` : `SuspendRef #${ast.id} ${ast.name}`;
|
|
197
|
+
case "Match":
|
|
198
|
+
return `Match ${exprText(ast.scrutinee)}`;
|
|
199
|
+
case "Take":
|
|
200
|
+
return `Take ${exprText(ast.count)}`;
|
|
201
|
+
case "RepeatExact":
|
|
202
|
+
return `RepeatExact ${exprText(ast.count)}`;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
const childrenOf = (ast) => {
|
|
206
|
+
switch (ast._tag) {
|
|
207
|
+
case "Gen":
|
|
208
|
+
return ast.steps.map((step) => step._tag === "Bind"
|
|
209
|
+
? [step.name ?? `bind #${step.slot}`, step.grammar]
|
|
210
|
+
: [undefined, step.grammar]);
|
|
211
|
+
case "Wrap":
|
|
212
|
+
return [
|
|
213
|
+
[undefined, ast.open],
|
|
214
|
+
[undefined, ast.inner],
|
|
215
|
+
[undefined, ast.close],
|
|
216
|
+
];
|
|
217
|
+
case "Choice":
|
|
218
|
+
return ast.options.map((option) => [undefined, option]);
|
|
219
|
+
case "Many":
|
|
220
|
+
return [[undefined, ast.inner], ["sep", ast.sep]];
|
|
221
|
+
case "Optional":
|
|
222
|
+
case "Transform":
|
|
223
|
+
case "Skip":
|
|
224
|
+
case "Label":
|
|
225
|
+
case "RepeatExact":
|
|
226
|
+
return [[undefined, ast.inner]];
|
|
227
|
+
case "Suspend":
|
|
228
|
+
return [[undefined, ast.body]];
|
|
229
|
+
case "Match":
|
|
230
|
+
return ast.cases.map((matchCase) => [`${formatValue(matchCase.key)} =>`, matchCase.grammar]);
|
|
231
|
+
case "Literal":
|
|
232
|
+
case "Regex":
|
|
233
|
+
case "Take":
|
|
234
|
+
case "SuspendRef":
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
const renderTree = (ast) => {
|
|
239
|
+
const lines = [headerOf(ast)];
|
|
240
|
+
const visit = (node, padding) => {
|
|
241
|
+
const children = childrenOf(node);
|
|
242
|
+
children.forEach(([label, child], index) => {
|
|
243
|
+
const last = index === children.length - 1;
|
|
244
|
+
lines.push(`${padding}${last ? "└─ " : "├─ "}${label === undefined ? "" : `${label} `}${headerOf(child)}`);
|
|
245
|
+
visit(child, `${padding}${last ? " " : "│ "}`);
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
visit(ast, "");
|
|
249
|
+
return lines.join("\n");
|
|
250
|
+
};
|
|
251
|
+
/** Renders a grammar as an indented node tree, one line per AST node. */
|
|
252
|
+
export const renderAst = (grammar) => renderTree(toAst(grammar));
|
|
253
|
+
//# sourceMappingURL=ast.js.map
|
package/dist/ast.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
|