|
1 | 1 | // deno-fmt-ignore-file
|
2 | 2 |
|
3 | 3 | import { Static, Runtime, Compile } from '@sinclair/parsebox'
|
4 |
| -import { Syntax } from './typebox/compiled/index.ts' |
5 |
| -import { ParseJson } from './json/index.ts' |
6 |
| -import { ParseEbnf } from './ebnf/index.ts' |
7 | 4 |
|
8 |
| -// ------------------------------------------------------------------ |
9 |
| -// |
10 |
| -// Example: TypeBox | Compiled |
11 |
| -// |
12 |
| -// ParseBox is the working project for developing the TypeBox syntax |
13 |
| -// parsers. You can test TypeBox inference here. Check the TypeBox |
14 |
| -// directory for Compiled and Interpreted variants. |
15 |
| -// |
16 |
| -// ------------------------------------------------------------------ |
17 |
| -const Type = Syntax(`{ |
18 |
| - x: number, |
19 |
| - y: number, |
20 |
| - z: number |
21 |
| -}`) |
| 5 | +// |
22 | 6 |
|
23 |
| -console.dir(Type, { depth: 100 }) |
24 |
| - |
25 |
| -// ------------------------------------------------------------------ |
26 |
| -// |
27 |
| -// Example: Ebnf | Interpreted |
28 |
| -// |
29 |
| -// ------------------------------------------------------------------ |
30 |
| -const Ebnf = ParseEbnf(` |
31 |
| -
|
32 |
| - Operand ::= Ident ; |
33 |
| -
|
34 |
| - Factor ::= "(" Expr ")" |
35 |
| - | Operand ; |
36 |
| -
|
37 |
| - TermTail ::= ("*" Factor TermTail) |
38 |
| - | ("/" Factor TermTail) |
39 |
| - | e ; |
40 |
| -
|
41 |
| - ExprTail ::= ("+" Term ExprTail) |
42 |
| - | ("-" Term ExprTail) |
43 |
| - | e ; |
44 |
| -
|
45 |
| - Term ::= Factor TermTail ; |
46 |
| -
|
47 |
| - Expr ::= Term ExprTail ; |
48 |
| -
|
49 |
| -`) |
50 |
| - |
51 |
| -const Result = Ebnf.Parse('Expr', `X * (Y + Z)`) |
52 |
| - |
53 |
| -console.dir(Result, { depth: 100 }) |
54 |
| - |
55 |
| -// ------------------------------------------------------------------ |
56 |
| -// |
57 |
| -// Example: Json | Interpreted |
58 |
| -// |
59 |
| -// ------------------------------------------------------------------ |
60 |
| -const Json = ParseJson(`{ |
61 |
| - "x": 1, |
62 |
| - "y": 2, |
63 |
| - "z": 3 |
64 |
| -}`) |
65 |
| - |
66 |
| -console.log(Json) |
67 |
| - |
68 |
| -// ------------------------------------------------------------------ |
69 |
| -// |
70 |
| -// Example: Expression | Interpreted |
71 |
| -// |
72 |
| -// ------------------------------------------------------------------ |
73 |
| -{ |
74 |
| - type Result = Static.Parse<Expr, 'x * (y + z)'> // hover |
75 |
| - |
76 |
| - type BinaryReduce<Left extends unknown, Right extends unknown[]> = ( |
77 |
| - Right extends [infer Operator, infer Right, infer Rest extends unknown[]] |
78 |
| - ? { left: Left; operator: Operator; right: BinaryReduce<Right, Rest> } |
79 |
| - : Left |
80 |
| - ) |
81 |
| - interface BinaryMapping extends Static.IMapping { |
82 |
| - output: this['input'] extends [infer Left, infer Right extends unknown[]] |
83 |
| - ? BinaryReduce<Left, Right> |
84 |
| - : never |
85 |
| - } |
86 |
| - interface FactorMapping extends Static.IMapping { |
87 |
| - output: ( |
88 |
| - this['input'] extends ['(', infer Expr, ')'] ? Expr : |
89 |
| - this['input'] extends [infer Operand] ? Operand : |
90 |
| - never |
91 |
| - ) |
92 |
| - } |
93 |
| - type Operand = Static.Ident |
94 |
| - type Factor = Static.Union<[ |
95 |
| - Static.Tuple<[Static.Const<'('>, Expr, Static.Const<')'>]>, |
96 |
| - Static.Tuple<[Operand]> |
97 |
| - ], FactorMapping> |
98 |
| - |
99 |
| - type TermTail = Static.Union<[ |
100 |
| - Static.Tuple<[Static.Const<'*'>, Factor, TermTail]>, |
101 |
| - Static.Tuple<[Static.Const<'/'>, Factor, TermTail]>, |
102 |
| - Static.Tuple<[]> |
103 |
| - ]> |
104 |
| - type ExprTail = Static.Union<[ |
105 |
| - Static.Tuple<[Static.Const<'+'>, Term, ExprTail]>, |
106 |
| - Static.Tuple<[Static.Const<'-'>, Term, ExprTail]>, |
107 |
| - Static.Tuple<[]> |
108 |
| - ]> |
109 |
| - type Term = Static.Tuple<[Factor, TermTail], BinaryMapping> |
110 |
| - type Expr = Static.Tuple<[Term, ExprTail], BinaryMapping> |
111 |
| -} |
112 |
| -// ------------------------------------------------------------------ |
113 |
| -// |
114 |
| -// Example: Compiled Parser |
115 |
| -// |
116 |
| -// ParseBox supports module compilation, generating optimized parsers |
117 |
| -// for JavaScript and TypeScript. The compilation process produces |
118 |
| -// two files: |
119 |
| -// |
120 |
| -// 1. A parser file derived from the grammar. |
121 |
| -// 2. A semantic mapping file. |
122 |
| -// |
123 |
| -// While compilation ensures valid code and a functional parser, |
124 |
| -// semantic actions must be implemented manually. |
125 |
| -// |
126 |
| -// ------------------------------------------------------------------ |
127 |
| -{ |
128 |
| - const ListModule = new Runtime.Module({ |
129 |
| - List: Runtime.Union([ |
130 |
| - Runtime.Tuple([Runtime.Ident(), Runtime.Const(','), Runtime.Ref('List')]), |
131 |
| - Runtime.Tuple([Runtime.Ident(), Runtime.Const(',')]), |
132 |
| - Runtime.Tuple([Runtime.Ident()]), |
133 |
| - Runtime.Tuple([]), |
134 |
| - ]) |
135 |
| - }) |
136 |
| - const project = Compile.Project(ListModule, { |
137 |
| - contextDefault: '{}', |
138 |
| - contextType: 'unknown', |
139 |
| - mappingPath: './mapping', |
140 |
| - mappingImports: [], |
141 |
| - parserImports: [] |
142 |
| - }) |
143 |
| - console.log(project.parser) // parser file content |
144 |
| - console.log(project.mapping) // semantic mapping file content |
145 |
| -} |
0 commit comments