astn 0.110.15 → 1.20.5
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/.eslintignore +5 -0
- package/.eslintrc.js +20 -0
- package/.vscode/extensions.json +9 -0
- package/.vscode/launch.json +39 -0
- package/.vscode/settings.json +8 -0
- package/.vscode/tasks.json +33 -0
- package/.vscodeignore +15 -0
- package/LICENSE.md +204 -0
- package/README.md +3 -410
- package/backend/package-lock.json +123 -0
- package/backend/package.json +6 -0
- package/backend/src/index.ts +133 -0
- package/backend/tsconfig.json +16 -0
- package/client/package-lock.json +581 -0
- package/client/package.json +23 -0
- package/client/src/extension.ts +249 -0
- package/client/src/test/completion.test.ts +43 -0
- package/client/src/test/diagnostics.test.ts +41 -0
- package/client/src/test/helper.ts +47 -0
- package/client/src/test/index.ts +43 -0
- package/client/src/test/runTest.ts +27 -0
- package/client/testFixture/diagnostics.txt +1 -0
- package/client/tsconfig.json +12 -0
- package/client/tsconfig.tsbuildinfo +1 -0
- package/development.md +12 -0
- package/images/icon.png +0 -0
- package/language-configuration.json +36 -0
- package/package.json +102 -58
- package/scripts/e2e.sh +6 -0
- package/server/package-lock.json +127 -0
- package/server/package.json +22 -0
- package/server/src/backend.ts +53 -0
- package/server/src/backendapi.ts +66 -0
- package/server/src/server.ts +296 -0
- package/server/tsconfig.json +14 -0
- package/server/tsconfig.tsbuildinfo +1 -0
- package/syntaxes/astn.tmLanguage.json +320 -0
- package/tsconfig.json +21 -0
- package/LICENSE +0 -17
- package/dist/bin/convert_to_json.d.ts +0 -2
- package/dist/bin/convert_to_json.js +0 -63
- package/dist/bin/validate_astn.d.ts +0 -2
- package/dist/bin/validate_astn.js +0 -58
- package/dist/generated/generic/resolve.d.ts +0 -90
- package/dist/generated/generic/resolve.js +0 -259
- package/dist/generated/implementation/schemas/ast/migration_boilerplate.d.ts +0 -13
- package/dist/generated/implementation/schemas/ast/migration_boilerplate.js +0 -174
- package/dist/generated/implementation/schemas/ide/migration_boilerplate.d.ts +0 -2
- package/dist/generated/implementation/schemas/ide/migration_boilerplate.js +0 -56
- package/dist/generated/implementation/schemas/parse_result/migration_boilerplate.d.ts +0 -6
- package/dist/generated/implementation/schemas/parse_result/migration_boilerplate.js +0 -136
- package/dist/generated/implementation/schemas/target/migration_boilerplate.d.ts +0 -3
- package/dist/generated/implementation/schemas/target/migration_boilerplate.js +0 -73
- package/dist/generated/implementation/schemas/target_json/migration_boilerplate.d.ts +0 -3
- package/dist/generated/implementation/schemas/target_json/migration_boilerplate.js +0 -67
- package/dist/generated/interface/core/poormans_parser.d.ts +0 -184
- package/dist/generated/interface/core/poormans_parser.js +0 -3
- package/dist/generated/interface/core/resolved.d.ts +0 -100
- package/dist/generated/interface/core/resolved.js +0 -3
- package/dist/generated/interface/core/unresolved.d.ts +0 -35
- package/dist/generated/interface/core/unresolved.js +0 -3
- package/dist/generated/interface/schemas/ast/migration_boilerplate.d.ts +0 -266
- package/dist/generated/interface/schemas/ast/migration_boilerplate.js +0 -3
- package/dist/generated/interface/schemas/ast/poormans_parser.d.ts +0 -1087
- package/dist/generated/interface/schemas/ast/poormans_parser.js +0 -3
- package/dist/generated/interface/schemas/ast/resolved.d.ts +0 -1087
- package/dist/generated/interface/schemas/ast/resolved.js +0 -3
- package/dist/generated/interface/schemas/ast/unresolved.d.ts +0 -1087
- package/dist/generated/interface/schemas/ast/unresolved.js +0 -3
- package/dist/generated/interface/schemas/ide/migration_boilerplate.d.ts +0 -24
- package/dist/generated/interface/schemas/ide/migration_boilerplate.js +0 -3
- package/dist/generated/interface/schemas/ide/poormans_parser.d.ts +0 -161
- package/dist/generated/interface/schemas/ide/poormans_parser.js +0 -3
- package/dist/generated/interface/schemas/ide/resolved.d.ts +0 -161
- package/dist/generated/interface/schemas/ide/resolved.js +0 -3
- package/dist/generated/interface/schemas/ide/unresolved.d.ts +0 -161
- package/dist/generated/interface/schemas/ide/unresolved.js +0 -3
- package/dist/generated/interface/schemas/parse_result/migration_boilerplate.d.ts +0 -112
- package/dist/generated/interface/schemas/parse_result/migration_boilerplate.js +0 -3
- package/dist/generated/interface/schemas/parse_result/poormans_parser.d.ts +0 -416
- package/dist/generated/interface/schemas/parse_result/poormans_parser.js +0 -3
- package/dist/generated/interface/schemas/parse_result/resolved.d.ts +0 -416
- package/dist/generated/interface/schemas/parse_result/resolved.js +0 -3
- package/dist/generated/interface/schemas/parse_result/unresolved.d.ts +0 -416
- package/dist/generated/interface/schemas/parse_result/unresolved.js +0 -3
- package/dist/generated/interface/schemas/target/migration_boilerplate.d.ts +0 -46
- package/dist/generated/interface/schemas/target/migration_boilerplate.js +0 -3
- package/dist/generated/interface/schemas/target/poormans_parser.d.ts +0 -186
- package/dist/generated/interface/schemas/target/poormans_parser.js +0 -3
- package/dist/generated/interface/schemas/target/resolved.d.ts +0 -186
- package/dist/generated/interface/schemas/target/resolved.js +0 -3
- package/dist/generated/interface/schemas/target/unresolved.d.ts +0 -186
- package/dist/generated/interface/schemas/target/unresolved.js +0 -3
- package/dist/generated/interface/schemas/target_json/migration_boilerplate.d.ts +0 -46
- package/dist/generated/interface/schemas/target_json/migration_boilerplate.js +0 -3
- package/dist/generated/interface/schemas/target_json/poormans_parser.d.ts +0 -169
- package/dist/generated/interface/schemas/target_json/poormans_parser.js +0 -3
- package/dist/generated/interface/schemas/target_json/resolved.d.ts +0 -169
- package/dist/generated/interface/schemas/target_json/resolved.js +0 -3
- package/dist/generated/interface/schemas/target_json/unresolved.d.ts +0 -169
- package/dist/generated/interface/schemas/target_json/unresolved.js +0 -3
- package/dist/globals.d.ts +0 -24
- package/dist/globals.js +0 -2
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -43
- package/dist/lib/globals.d.ts +0 -24
- package/dist/lib/globals.js +0 -2
- package/dist/lib/transformations/create_error_message.d.ts +0 -5
- package/dist/lib/transformations/create_error_message.js +0 -89
- package/dist/lib/transformations/format.d.ts +0 -42
- package/dist/lib/transformations/format.js +0 -166
- package/dist/lib/transformations/fountain_pen/astn.d.ts +0 -11
- package/dist/lib/transformations/fountain_pen/astn.js +0 -156
- package/dist/lib/transformations/fountain_pen/json.d.ts +0 -4
- package/dist/lib/transformations/fountain_pen/json.js +0 -113
- package/dist/lib/transformations/parse.d.ts +0 -11
- package/dist/lib/transformations/parse.js +0 -257
- package/dist/lib/transformations/parse_generic.d.ts +0 -43
- package/dist/lib/transformations/parse_generic.js +0 -644
- package/dist/parse/parse.d.ts +0 -11
- package/dist/parse/parse.js +0 -267
- package/dist/parse/parse_generic.d.ts +0 -43
- package/dist/parse/parse_generic.js +0 -656
- package/dist/serializers/astn.js +0 -28
- package/dist/serializers/json.d.ts +0 -5
- package/dist/serializers/json.js +0 -46
- package/dist/serializers/parse_result.d.ts +0 -5
- package/dist/serializers/parse_result.js +0 -99
- package/dist/transformations/ast/ide.d.ts +0 -42
- package/dist/transformations/ast/ide.js +0 -176
- package/dist/transformations/ast/json_target.d.ts +0 -6
- package/dist/transformations/ast/json_target.js +0 -88
- package/dist/transformations/create_error_message.d.ts +0 -5
- package/dist/transformations/create_error_message.js +0 -89
- package/dist/transformations/format.d.ts +0 -42
- package/dist/transformations/format.js +0 -166
- package/dist/transformations/fountain_pen/astn.d.ts +0 -11
- package/dist/transformations/fountain_pen/astn.js +0 -166
- package/dist/transformations/fountain_pen/json.d.ts +0 -4
- package/dist/transformations/fountain_pen/json.js +0 -123
- package/dist/transformations/parse.d.ts +0 -11
- package/dist/transformations/parse.js +0 -257
- package/dist/transformations/parse_generic.d.ts +0 -43
- package/dist/transformations/parse_generic.js +0 -644
- package/dist/transformations/target/fountain_pen/astn.d.ts +0 -11
- package/dist/transformations/target/fountain_pen/astn.js +0 -156
- package/dist/transformations/target/fountain_pen/json.d.ts +0 -4
- package/dist/transformations/target/fountain_pen/json.js +0 -113
- package/dist/transformations/target/fountain_pen_block.d.ts +0 -11
- package/dist/transformations/target/fountain_pen_block.js +0 -166
- package/dist/transformations/target_json/fountain_pen_block.d.ts +0 -4
- package/dist/transformations/target_json/fountain_pen_block.js +0 -101
- package/documentation/railroad_diagram/diagram/apostrophed_string.png +0 -0
- package/documentation/railroad_diagram/diagram/astn_document.png +0 -0
- package/documentation/railroad_diagram/diagram/backticked_string.png +0 -0
- package/documentation/railroad_diagram/diagram/comment.png +0 -0
- package/documentation/railroad_diagram/diagram/concise_group.png +0 -0
- package/documentation/railroad_diagram/diagram/content.png +0 -0
- package/documentation/railroad_diagram/diagram/dictionary.png +0 -0
- package/documentation/railroad_diagram/diagram/elements.png +0 -0
- package/documentation/railroad_diagram/diagram/escaped_character.png +0 -0
- package/documentation/railroad_diagram/diagram/four_hexadecimal_digits.png +0 -0
- package/documentation/railroad_diagram/diagram/header.png +0 -0
- package/documentation/railroad_diagram/diagram/hexadecimal_digit.png +0 -0
- package/documentation/railroad_diagram/diagram/ignorable.png +0 -0
- package/documentation/railroad_diagram/diagram/include.png +0 -0
- package/documentation/railroad_diagram/diagram/key_value_pairs.png +0 -0
- package/documentation/railroad_diagram/diagram/line_comment.png +0 -0
- package/documentation/railroad_diagram/diagram/list.png +0 -0
- package/documentation/railroad_diagram/diagram/newline_character.png +0 -0
- package/documentation/railroad_diagram/diagram/normal_character.png +0 -0
- package/documentation/railroad_diagram/diagram/normal_or_newline_character.png +0 -0
- package/documentation/railroad_diagram/diagram/quoted_string.png +0 -0
- package/documentation/railroad_diagram/diagram/rr-2.5.png +0 -0
- package/documentation/railroad_diagram/diagram/set_optional_value.png +0 -0
- package/documentation/railroad_diagram/diagram/string.png +0 -0
- package/documentation/railroad_diagram/diagram/string_content_character.png +0 -0
- package/documentation/railroad_diagram/diagram/tagged_value.png +0 -0
- package/documentation/railroad_diagram/diagram/traditional_comment.png +0 -0
- package/documentation/railroad_diagram/diagram/undelimited_string.png +0 -0
- package/documentation/railroad_diagram/diagram/value.png +0 -0
- package/documentation/railroad_diagram/diagram/verbose_group.png +0 -0
- package/documentation/railroad_diagram/diagram/whitespace.png +0 -0
- package/documentation/railroad_diagram/index.md +0 -425
- /package/{dist/serializers/astn.d.ts → client/testFixture/completion.txt} +0 -0
package/README.md
CHANGED
|
@@ -1,414 +1,7 @@
|
|
|
1
1
|
# ASTN (Abstract Syntax Tree Notation)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
ASTN is a **human-editable data format** designed to represent abstract syntax trees in a clear, concise, and structured way. It extends JSON’s capabilities by introducing additional notation features to better express complex data structures. ASTN is a superset of JSON, meaning that every JSON file is a valid ASTN file.
|
|
4
|
+
ASTN files can easily be converted back to JSON files
|
|
4
5
|
|
|
5
|
-
**ASTN is a superset of JSON** - any valid JSON document is also valid ASTN, but ASTN provides a number additional features for enhanced readability and functionality.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- 📋 **Multiple string types** - Support for quoted, backticked, apostrophed, and undelimited strings
|
|
10
|
-
- 💬 **Comments** - Line and block comment support
|
|
11
|
-
- 🏗️ **Rich data structures** - dictionaries, lists, groups, tagged values, include, set, not set
|
|
12
|
-
- 📄 **Document headers** - Optional header metadata for documents
|
|
13
|
-
- 🔗 **File inclusion** - Import other ASTN files with `@` syntax
|
|
14
|
-
- ✨ **Flexible punctuation** - Commas are optional, trailing commas are allowed
|
|
15
|
-
|
|
16
|
-
## Features of this tool
|
|
17
|
-
|
|
18
|
-
- 🚀 **Fast parsing** - Efficient lexer and parser implementation
|
|
19
|
-
- 📝 **Format validation** - Comprehensive error reporting with location information
|
|
20
|
-
- 🎨 **Code formatting** - Built-in formatter for consistent code style
|
|
21
|
-
|
|
22
|
-
## Installation
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
npm install astn
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Quick Start
|
|
29
|
-
|
|
30
|
-
### Parsing ASTN
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
import { Parser } from 'astn';
|
|
34
|
-
|
|
35
|
-
const source = `
|
|
36
|
-
! header "example"
|
|
37
|
-
{
|
|
38
|
-
\`name\`: "John Doe"
|
|
39
|
-
\`age\`: | 'number' "30"
|
|
40
|
-
\`hobbies\`: [
|
|
41
|
-
"reading"
|
|
42
|
-
"coding"
|
|
43
|
-
]
|
|
44
|
-
}
|
|
45
|
-
`;
|
|
46
|
-
|
|
47
|
-
const result = Parser.parse(source, { 'tab size': 4 });
|
|
48
|
-
|
|
49
|
-
if (result[0] === 'success') {
|
|
50
|
-
console.log('Parsed successfully:', result[1]);
|
|
51
|
-
} else {
|
|
52
|
-
console.error('Parse error:', result[1]);
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Formatting ASTN
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
import * as format from 'astn/format';
|
|
60
|
-
import * as types from 'astn';
|
|
61
|
-
|
|
62
|
-
// Format a parsed document
|
|
63
|
-
const edits = format.Document(document, {
|
|
64
|
-
'remove commas': false,
|
|
65
|
-
'indentation string': ' ',
|
|
66
|
-
'current indentation': ''
|
|
67
|
-
});
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Error Handling
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
import * as create_error_message from 'astn/create_error_message';
|
|
74
|
-
|
|
75
|
-
const result = Parser.parse(invalidSource, { 'tab size': 4 });
|
|
76
|
-
|
|
77
|
-
if (result[0] === 'failure') {
|
|
78
|
-
const errorMessage = create_error_message.Parse_Error(result[1], {
|
|
79
|
-
'position info': ['one based', null]
|
|
80
|
-
});
|
|
81
|
-
console.error('Parse Error:', errorMessage);
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## ASTN Syntax Overview
|
|
86
|
-
|
|
87
|
-
ASTN supports various data types and structures:
|
|
88
|
-
|
|
89
|
-
### JSON Compatibility
|
|
90
|
-
|
|
91
|
-
Since ASTN is a superset of JSON, any valid JSON works as-is:
|
|
92
|
-
|
|
93
|
-
```json
|
|
94
|
-
{
|
|
95
|
-
"name": "John Doe",
|
|
96
|
-
"age": 30,
|
|
97
|
-
"hobbies": ["reading", "coding"],
|
|
98
|
-
"active": true,
|
|
99
|
-
"metadata": null
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
But ASTN extends JSON with additional features for better readability and functionality.
|
|
104
|
-
|
|
105
|
-
### JSON vs ASTN Comparison
|
|
106
|
-
|
|
107
|
-
Here's the same data structure in JSON vs ASTN, showing ASTN's enhanced features:
|
|
108
|
-
|
|
109
|
-
<table>
|
|
110
|
-
<tr>
|
|
111
|
-
<th>JSON</th>
|
|
112
|
-
<th>ASTN</th>
|
|
113
|
-
</tr>
|
|
114
|
-
<tr>
|
|
115
|
-
<td>
|
|
116
|
-
|
|
117
|
-
```json
|
|
118
|
-
{
|
|
119
|
-
"config": {
|
|
120
|
-
"name": "MyApp",
|
|
121
|
-
"version": "1.2.3",
|
|
122
|
-
"enabled": true,
|
|
123
|
-
"created": "2025-07-21T10:30:00Z",
|
|
124
|
-
"tags": ["web", "typescript"],
|
|
125
|
-
"databases": {
|
|
126
|
-
"local": {
|
|
127
|
-
"host": "localhost",
|
|
128
|
-
"port": 5432,
|
|
129
|
-
"ssl": null
|
|
130
|
-
},
|
|
131
|
-
"remote": {
|
|
132
|
-
"host": "localhost",
|
|
133
|
-
"port": 1234,
|
|
134
|
-
"ssl": null
|
|
135
|
-
},
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
</td>
|
|
142
|
-
<td>
|
|
143
|
-
|
|
144
|
-
```astn
|
|
145
|
-
! "Application Configuration"
|
|
146
|
-
(
|
|
147
|
-
'config': {
|
|
148
|
-
'name': "MyApp"
|
|
149
|
-
'version': "1.2.3"
|
|
150
|
-
'enabled': true
|
|
151
|
-
'created': 2025-07-21 // undelimited date
|
|
152
|
-
'tags': ["web", "typescript"]
|
|
153
|
-
'databases': (
|
|
154
|
-
`local`: {
|
|
155
|
-
'host': "localhost"
|
|
156
|
-
'port': | 'number' "5432" // tagged value
|
|
157
|
-
'ssl': ~ // not set
|
|
158
|
-
},
|
|
159
|
-
`remote": <"localhost" 'number' 1234 ~>
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
)
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
</td>
|
|
166
|
-
</tr>
|
|
167
|
-
</table>
|
|
168
|
-
|
|
169
|
-
**ASTN advantages shown above:**
|
|
170
|
-
- 📄 **Headers** - `! header "..."` for document metadata
|
|
171
|
-
- 💬 **Comments** - `//` and `/* */` supported throughout
|
|
172
|
-
- 🏷️ **Tagged values** - `| 'number' "5432"` for type information
|
|
173
|
-
- ✨ **Flexible literals** - `2025-07-21` without quotes
|
|
174
|
-
- 🚫 **Explicit "not set"** - `~` instead of `null`
|
|
175
|
-
- **Instance keys** - `` `key` `` for data identifiers
|
|
176
|
-
- ✨ **Optional commas** - cleaner syntax without mandatory commas
|
|
177
|
-
|
|
178
|
-
### Schema vs Instance Data Distinction
|
|
179
|
-
|
|
180
|
-
One of ASTN's key improvements over JSON is the clear distinction between **schema keys** (fixed structure) and **instance keys** (dynamic data):
|
|
181
|
-
|
|
182
|
-
**JSON Problem:** In JSON, it's difficult to distinguish between:
|
|
183
|
-
```json
|
|
184
|
-
{
|
|
185
|
-
"config": { // Is this a schema key or instance data?
|
|
186
|
-
"host": "localhost" // Are these fixed fields or dynamic entries?
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
**ASTN Solution:** Uses different structures for different purposes:
|
|
192
|
-
|
|
193
|
-
```astn
|
|
194
|
-
// Verbose Group - for schema/structure ( () and apostrophe keys)
|
|
195
|
-
('config': (
|
|
196
|
-
'host': "localhost" // Fixed schema fields
|
|
197
|
-
'port': 5432
|
|
198
|
-
))
|
|
199
|
-
|
|
200
|
-
// Dictionary - for instance/dynamic data ( {} and backtick keys)
|
|
201
|
-
{
|
|
202
|
-
`user_123`: "John" // Dynamic user IDs
|
|
203
|
-
`user_456`: "Jane" // Runtime-determined keys
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
This makes the data's intent much clearer to both humans and tools!
|
|
208
|
-
|
|
209
|
-
### Lists vs Concise Groups Distinction
|
|
210
|
-
|
|
211
|
-
ASTN also distinguishes between **lists** (ordered instance data) and **groups** (ordered schema data):
|
|
212
|
-
|
|
213
|
-
**JSON Problem:** Arrays in JSON are ambiguous about their purpose:
|
|
214
|
-
```json
|
|
215
|
-
{
|
|
216
|
-
"coordinates": [10, 20, 30], // Is this a list or structured data?
|
|
217
|
-
"users": ["John", "Jane"] // Dynamic list or fixed schema fields?
|
|
218
|
-
}
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
**ASTN Solution:** Four different structures for different purposes:
|
|
222
|
-
|
|
223
|
-
```astn
|
|
224
|
-
// 1. List - for dynamic/instance data (square brackets)
|
|
225
|
-
{
|
|
226
|
-
`users`: [ // Dynamic list of users
|
|
227
|
-
"John"
|
|
228
|
-
"Jane"
|
|
229
|
-
"Bob" // Can add/remove items
|
|
230
|
-
]
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// 2. Dictionary - for key-value instance data (curly braces + backticks)
|
|
234
|
-
{
|
|
235
|
-
`user_data`: {
|
|
236
|
-
`user_123`: "John" // Dynamic user IDs as keys
|
|
237
|
-
`user_456`: "Jane" // Runtime-determined keys
|
|
238
|
-
`user_789`: "Bob"
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// 3. Concise Group - for schema/structure (angle brackets)
|
|
243
|
-
{
|
|
244
|
-
`coordinates`: <10 20 30> // Fixed x, y, z coordinates
|
|
245
|
-
`rgb_color`: <255 128 0> // Fixed red, green, blue values
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// 4. Verbose Group - explicit schema names (parentheses)
|
|
249
|
-
{
|
|
250
|
-
`coordinates`: (
|
|
251
|
-
'x': 10
|
|
252
|
-
'y': 20
|
|
253
|
-
'z': 30
|
|
254
|
-
)
|
|
255
|
-
}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**Example: Same data in concise vs verbose groups:**
|
|
259
|
-
```astn
|
|
260
|
-
// Concise - implicit positional names
|
|
261
|
-
`person`: <"John" 30 "Engineer">
|
|
262
|
-
|
|
263
|
-
// Verbose - explicit schema names (equivalent to above)
|
|
264
|
-
`person`: (
|
|
265
|
-
'name': "John"
|
|
266
|
-
'age': 30
|
|
267
|
-
'job': "Engineer"
|
|
268
|
-
)
|
|
269
|
-
```
|
|
270
|
-
schema-aware tooling can create support to toggle between these 2 representations
|
|
271
|
-
|
|
272
|
-
**Concise vs Verbose Groups:** These are interchangeable - concise groups are just verbose groups with implicit position-based schema names (first, second, third, etc.).
|
|
273
|
-
|
|
274
|
-
### Document Structure
|
|
275
|
-
```astn
|
|
276
|
-
// Optional header
|
|
277
|
-
! header "Document metadata or title"
|
|
278
|
-
|
|
279
|
-
// Main document content
|
|
280
|
-
{
|
|
281
|
-
"content": "value"
|
|
282
|
-
}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
### Basic Values
|
|
286
|
-
```astn
|
|
287
|
-
"quoted string" // Can contain newlines and escape sequences
|
|
288
|
-
'apostrophed string' // Used for schema/meta names (keys, state names)
|
|
289
|
-
`backticked string` // Used for identifiers
|
|
290
|
-
undelimited_string // Flexible literals (dates, numbers, booleans, etc.)
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
**String Type Usage:**
|
|
294
|
-
- **Quoted strings** (`"..."`) - General purpose strings that support newlines and escape sequences like `\n`, `\t`, `\"`, etc.
|
|
295
|
-
- **Apostrophed strings** (`'...'`) - Specifically for schema and metadata names such as verbose group keys and tagged value state names
|
|
296
|
-
- **Backticked strings** (`` `...` ``) - Used for identifiers and instance data such as dictionary keys
|
|
297
|
-
- **Undelimited strings** - More flexible than JSON primitives; can represent:
|
|
298
|
-
- Booleans: `true`, `false`
|
|
299
|
-
- Numbers: `42`, `3.14`, `-123`
|
|
300
|
-
- Dates: `2025-07-21`, `2025-07-21T10:30:00Z`
|
|
301
|
-
- Custom literals: `null`, `undefined`, or domain-specific values
|
|
302
|
-
|
|
303
|
-
### Collections
|
|
304
|
-
```astn
|
|
305
|
-
// Dictionary (commas optional, trailing commas allowed)
|
|
306
|
-
{
|
|
307
|
-
`key`: "value" // backtick for instance data key
|
|
308
|
-
`number`: | 'number' "42" // backtick for key, apostrophe for state name
|
|
309
|
-
`description`: "Multi-line
|
|
310
|
-
strings are supported
|
|
311
|
-
in quoted strings"
|
|
312
|
-
`date`: 2025-07-21 // undelimited date
|
|
313
|
-
`enabled`: true // undelimited boolean
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// List with flexible comma usage
|
|
317
|
-
[
|
|
318
|
-
"item1"
|
|
319
|
-
'schema_name' // apostrophe for schema identifier
|
|
320
|
-
`instance_id` // backtick for instance identifier
|
|
321
|
-
2025-07-21 // undelimited date
|
|
322
|
-
42 // undelimited number
|
|
323
|
-
]
|
|
324
|
-
|
|
325
|
-
// Concise Group
|
|
326
|
-
<"item1" 'meta_name' `instance_id`>
|
|
327
|
-
|
|
328
|
-
// Verbose Group (apostrophes for schema keys)
|
|
329
|
-
('schema_key': "value1" 'another_key': "value2")
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### Special Values
|
|
333
|
-
```astn
|
|
334
|
-
// Tagged values (apostrophe for state names)
|
|
335
|
-
| 'number' "42"
|
|
336
|
-
| 'date' 2025-07-21
|
|
337
|
-
| 'boolean' true
|
|
338
|
-
| 'custom_type' "some value"
|
|
339
|
-
|
|
340
|
-
// Optional values
|
|
341
|
-
* "optional value"
|
|
342
|
-
* 2025-12-31 // undelimited date as optional
|
|
343
|
-
|
|
344
|
-
// Not set
|
|
345
|
-
~
|
|
346
|
-
|
|
347
|
-
// File inclusion
|
|
348
|
-
@ "path/to/config.astn"
|
|
349
|
-
@ "../shared/constants.astn"
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
### Comments
|
|
353
|
-
```astn
|
|
354
|
-
// Line comment
|
|
355
|
-
/* Block comment */
|
|
356
|
-
{
|
|
357
|
-
"key": "value" // Trailing comment
|
|
358
|
-
}
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
## VS Code Extension
|
|
362
|
-
|
|
363
|
-
For the best development experience with ASTN files, install the **ASTN** VS Code extension:
|
|
364
|
-
|
|
365
|
-
- **Extension ID**: `astn`
|
|
366
|
-
- **Features**: Syntax highlighting, error detection, and formatting support
|
|
367
|
-
- **Installation**: Search for "astn" in the VS Code Extensions marketplace
|
|
368
|
-
|
|
369
|
-
The extension provides:
|
|
370
|
-
- 🎨 Syntax highlighting for `.astn` files
|
|
371
|
-
- 🔍 Real-time error detection and validation
|
|
372
|
-
- 📝 IntelliSense and autocompletion
|
|
373
|
-
- 🔧 Integrated formatting support
|
|
374
|
-
|
|
375
|
-
## CLI Usage
|
|
376
|
-
|
|
377
|
-
Validate ASTN files:
|
|
378
|
-
|
|
379
|
-
```bash
|
|
380
|
-
npx astn-validate < input.astn
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
## API Reference
|
|
384
|
-
|
|
385
|
-
### Types
|
|
386
|
-
|
|
387
|
-
- `Document` - Root document structure
|
|
388
|
-
- `Value` - Any ASTN value
|
|
389
|
-
- `String` - String with type information
|
|
390
|
-
- `Parse_Error` - Detailed error information
|
|
391
|
-
- `Location` - Position information in source
|
|
392
|
-
|
|
393
|
-
### Functions
|
|
394
|
-
|
|
395
|
-
- `Parser.parse(source, options)` - Parse ASTN source
|
|
396
|
-
- `format.Document(doc, options)` - Format a document
|
|
397
|
-
- `create_error_message.Parse_Error(error, options)` - Create human-readable error messages
|
|
398
|
-
|
|
399
|
-
## Documentation
|
|
400
|
-
|
|
401
|
-
- [Railroad Diagrams](./documentation/railroad_diagram/index.md)
|
|
402
|
-
- [EBNF Grammar](./extra/astn.ebnf)
|
|
403
|
-
|
|
404
|
-
## Contributing
|
|
405
|
-
|
|
406
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
407
|
-
|
|
408
|
-
## License
|
|
409
|
-
|
|
410
|
-
Apache 2.0 License - see LICENSE file for details.
|
|
411
|
-
|
|
412
|
-
## Version
|
|
413
|
-
|
|
414
|
-
Current version: 0.110.5
|
|
7
|
+
For a detailed explanation, head over to the project site [project site](https://github.com/corno/astn) for more details.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "backend",
|
|
3
|
+
"lockfileVersion": 3,
|
|
4
|
+
"requires": true,
|
|
5
|
+
"packages": {
|
|
6
|
+
"": {
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@types/node": "^24.0.15",
|
|
9
|
+
"astn": "^0.110.11"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"node_modules/@types/node": {
|
|
13
|
+
"version": "24.1.0",
|
|
14
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz",
|
|
15
|
+
"integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"undici-types": "~7.8.0"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"node_modules/astn": {
|
|
22
|
+
"version": "0.110.16",
|
|
23
|
+
"resolved": "https://registry.npmjs.org/astn/-/astn-0.110.16.tgz",
|
|
24
|
+
"integrity": "sha512-8QlpaZ0YLMF525RHcasbSJokSUt60jgK6vSMZzJPGKiIivVFBYVQB4zYbgX5OyEDPkJcYcwSGgsyCxSnJE8RJg==",
|
|
25
|
+
"license": "Apache-2.0",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"exupery-core-alg": "^0.1.4",
|
|
28
|
+
"exupery-core-data": "^0.1.0",
|
|
29
|
+
"exupery-core-dev": "^0.1.1",
|
|
30
|
+
"exupery-core-resources": "^0.2.1",
|
|
31
|
+
"pareto-fountain-pen": "^0.1.3",
|
|
32
|
+
"pareto-standard-operations": "^0.1.0"
|
|
33
|
+
},
|
|
34
|
+
"bin": {
|
|
35
|
+
"astn-validate": "dist/bin/validate_astn.js"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=14.0.0"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"node_modules/exupery-core-alg": {
|
|
42
|
+
"version": "0.1.4",
|
|
43
|
+
"resolved": "https://registry.npmjs.org/exupery-core-alg/-/exupery-core-alg-0.1.4.tgz",
|
|
44
|
+
"integrity": "sha512-VPzKIUR5MoYq0Z8vT8pZLNh2kc9/P62+tqy4J2sIQEWcEHZy/uCInRThgFhsdVOn95Rm/CHwoQxwaVHghNX/1w==",
|
|
45
|
+
"license": "ISC",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"exupery-core-internals": "^0.1.2"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"node_modules/exupery-core-data": {
|
|
51
|
+
"version": "0.1.1",
|
|
52
|
+
"resolved": "https://registry.npmjs.org/exupery-core-data/-/exupery-core-data-0.1.1.tgz",
|
|
53
|
+
"integrity": "sha512-0PhBa12lowVQLHq4+8vt6n/nruC82B98oSfe6TWCTGKQ4WaHYozU2+sItgeuJoqz/mr1i6X+kBG/IrV4s4tUBA==",
|
|
54
|
+
"license": "ISC",
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"exupery-core-internals": "^0.1.2"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"node_modules/exupery-core-dev": {
|
|
60
|
+
"version": "0.1.1",
|
|
61
|
+
"resolved": "https://registry.npmjs.org/exupery-core-dev/-/exupery-core-dev-0.1.1.tgz",
|
|
62
|
+
"integrity": "sha512-skyM/gG1o3WsjwoY1hrXkvTZnmhtx6bYIiIyfFETc/JT7tQVWtipY+oExDs9SRNWWG8+hrxUMYH+oySSYpGojg==",
|
|
63
|
+
"license": "ISC",
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"exupery-core-internals": "^0.1.2"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"node_modules/exupery-core-internals": {
|
|
69
|
+
"version": "0.1.2",
|
|
70
|
+
"resolved": "https://registry.npmjs.org/exupery-core-internals/-/exupery-core-internals-0.1.2.tgz",
|
|
71
|
+
"integrity": "sha512-xwmtzAXsL9sixOq/3VQm9H6GKeGMvc/Bkzdvw+j8qlGZi+HBUh5vLnwX6qVdzP5p3KuQP08IgGj8SHtn5sPvZA==",
|
|
72
|
+
"license": "ISC",
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"exupery-core-types": "^0.1.0"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"node_modules/exupery-core-resources": {
|
|
78
|
+
"version": "0.2.1",
|
|
79
|
+
"resolved": "https://registry.npmjs.org/exupery-core-resources/-/exupery-core-resources-0.2.1.tgz",
|
|
80
|
+
"integrity": "sha512-Cw43sR3LFZFWB46/xRAnrykNeOPmZuitKom8lYe3+5nn8jg1QNwgD9gQ4pmK8MDyKLBk/xrqaJLtmXUtTlTGXw==",
|
|
81
|
+
"license": "ISC",
|
|
82
|
+
"dependencies": {
|
|
83
|
+
"exupery-core-internals": "^0.1.2"
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"node_modules/exupery-core-types": {
|
|
87
|
+
"version": "0.1.0",
|
|
88
|
+
"resolved": "https://registry.npmjs.org/exupery-core-types/-/exupery-core-types-0.1.0.tgz",
|
|
89
|
+
"integrity": "sha512-ah5/BRL2wuby3Fv8CgmOnx1qF4ICPjpTlYWROFwGNwRXHsZdL3gKLVcqwHxDpxpGD/32kbl4PFD4N5yUc3sYPg==",
|
|
90
|
+
"license": "Apache-2.0"
|
|
91
|
+
},
|
|
92
|
+
"node_modules/pareto-fountain-pen": {
|
|
93
|
+
"version": "0.1.5",
|
|
94
|
+
"resolved": "https://registry.npmjs.org/pareto-fountain-pen/-/pareto-fountain-pen-0.1.5.tgz",
|
|
95
|
+
"integrity": "sha512-1+S/KVTUqHk/0H+lGesngFWhGk9RpZ4VJcM0YfptrRyuGRqPqweCCnptwEeeu8pup0bVczfZ4fr4jaweqUbLiA==",
|
|
96
|
+
"license": "Apache-2.0",
|
|
97
|
+
"dependencies": {
|
|
98
|
+
"exupery-core-alg": "^0.1.4",
|
|
99
|
+
"exupery-core-data": "^0.1.0",
|
|
100
|
+
"exupery-core-dev": "^0.1.1",
|
|
101
|
+
"exupery-core-resources": "^0.2.1",
|
|
102
|
+
"pareto-standard-operations": "^0.1.1"
|
|
103
|
+
},
|
|
104
|
+
"engines": {
|
|
105
|
+
"node": ">=14.0.0"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
"node_modules/pareto-standard-operations": {
|
|
109
|
+
"version": "0.1.1",
|
|
110
|
+
"resolved": "https://registry.npmjs.org/pareto-standard-operations/-/pareto-standard-operations-0.1.1.tgz",
|
|
111
|
+
"integrity": "sha512-BAepFVctXbVbcs0J66+rpCdJ30rT0UBVG5gOUx6FfmYvIjDbekXxkQXisETpIQHsoLVqJXVk8c6vMFdD+ZnJaA==",
|
|
112
|
+
"dependencies": {
|
|
113
|
+
"exupery-core-alg": "^0.1.4"
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"node_modules/undici-types": {
|
|
117
|
+
"version": "7.8.0",
|
|
118
|
+
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
|
|
119
|
+
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
|
|
120
|
+
"license": "MIT"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import * as _ea from 'exupery-core-alg'
|
|
2
|
+
import * as _et from 'exupery-core-types'
|
|
3
|
+
|
|
4
|
+
import * as astn from "astn"
|
|
5
|
+
|
|
6
|
+
import * as t_ast_2_json from "astn/dist/transformations/ast/json_target"
|
|
7
|
+
import * as s_json from "astn/dist/serializers/json"
|
|
8
|
+
|
|
9
|
+
export type Relative_Location = astn.d_ast.Relative_Location
|
|
10
|
+
|
|
11
|
+
export type Relative_Range = astn.d_ast.Relative_Range
|
|
12
|
+
|
|
13
|
+
export const sort_alphabetically = (
|
|
14
|
+
$: string,
|
|
15
|
+
$p: {
|
|
16
|
+
'position': Relative_Location
|
|
17
|
+
}
|
|
18
|
+
): _et.Optional_Value<astn.d_ide.Text_Edits.L.SG.replace> => {
|
|
19
|
+
return _ea.set({
|
|
20
|
+
'range': {
|
|
21
|
+
'start': $p.position,
|
|
22
|
+
'end': $p.position
|
|
23
|
+
},
|
|
24
|
+
'text': `sort alphabetically at ${$p.position.line}:${$p.position.column}`
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const convert_to_json = ($: string): string | null => {
|
|
29
|
+
return _ea.cc(astn.t_parse.Parse_Result(
|
|
30
|
+
$,
|
|
31
|
+
{
|
|
32
|
+
'tab size': 1
|
|
33
|
+
}
|
|
34
|
+
), ($) => {
|
|
35
|
+
switch ($[0]) {
|
|
36
|
+
case 'failure': return _ea.ss($, ($) => {
|
|
37
|
+
return null
|
|
38
|
+
})
|
|
39
|
+
case 'success': return _ea.ss($, ($) => s_json.Document(
|
|
40
|
+
t_ast_2_json.Document($),
|
|
41
|
+
{
|
|
42
|
+
'indentation': " ",
|
|
43
|
+
'newline': '\n'
|
|
44
|
+
}
|
|
45
|
+
))
|
|
46
|
+
default: return _ea.au($[0])
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type Format_Options = {
|
|
52
|
+
'insert spaces': boolean
|
|
53
|
+
'preserve delimiters': boolean;
|
|
54
|
+
'preserve final newline state': boolean;
|
|
55
|
+
'preserve commas': boolean;
|
|
56
|
+
'indent string': string;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type Format_Result =
|
|
60
|
+
| ['failure', { message: string }]
|
|
61
|
+
| ['success', astn.d_ide.Text_Edits]
|
|
62
|
+
|
|
63
|
+
export type DiagnosticSeverity =
|
|
64
|
+
| ['error', null]
|
|
65
|
+
| ['warning', null]
|
|
66
|
+
| ['information', null]
|
|
67
|
+
| ['hint', null]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
export type Diagnostic = {
|
|
71
|
+
severity: DiagnosticSeverity
|
|
72
|
+
range: astn.d_ast.Range
|
|
73
|
+
message: string
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type Diagnostics = _et.Array<Diagnostic>
|
|
77
|
+
|
|
78
|
+
export const format = (text: string, options: Format_Options): Format_Result => {
|
|
79
|
+
return _ea.cc(astn.t_parse.Parse_Result(
|
|
80
|
+
text,
|
|
81
|
+
{
|
|
82
|
+
'tab size': 1
|
|
83
|
+
}
|
|
84
|
+
), ($) => {
|
|
85
|
+
switch ($[0]) {
|
|
86
|
+
case 'failure': return _ea.ss($, ($): Format_Result => {
|
|
87
|
+
return ['failure', { message: astn.t_create_error_message.Parse_Error($, { 'position info': ['zero based', null] }) }]
|
|
88
|
+
})
|
|
89
|
+
case 'success': return _ea.ss($, ($): Format_Result => {
|
|
90
|
+
return ['success', astn.t_format.Document(
|
|
91
|
+
$,
|
|
92
|
+
{
|
|
93
|
+
'current indentation': "",
|
|
94
|
+
'indentation string': options['indent string'],
|
|
95
|
+
'remove commas': !options['preserve commas'],
|
|
96
|
+
}
|
|
97
|
+
)]
|
|
98
|
+
})
|
|
99
|
+
default: return _ea.au($[0])
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const validate_text_document = (
|
|
106
|
+
$: string,
|
|
107
|
+
$p: {
|
|
108
|
+
}
|
|
109
|
+
): Diagnostics => {
|
|
110
|
+
return _ea.cc(astn.t_parse.Parse_Result(
|
|
111
|
+
$,
|
|
112
|
+
{
|
|
113
|
+
'tab size': 1 // vscode works with character, not with columns, tabs are always 1 character
|
|
114
|
+
}
|
|
115
|
+
), ($) => {
|
|
116
|
+
switch ($[0]) {
|
|
117
|
+
case 'failure': return _ea.ss($, ($): Diagnostics => {
|
|
118
|
+
return _ea.array_literal<Diagnostic>([
|
|
119
|
+
{
|
|
120
|
+
severity: ['error', null],
|
|
121
|
+
range: $.range,
|
|
122
|
+
message: astn.t_create_error_message.Parse_Error_Type($.type)
|
|
123
|
+
}
|
|
124
|
+
])
|
|
125
|
+
})
|
|
126
|
+
case 'success': return _ea.ss($, ($): Diagnostics => {
|
|
127
|
+
|
|
128
|
+
return _ea.array_literal([])
|
|
129
|
+
})
|
|
130
|
+
default: return _ea.au($[0])
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"inlineSourceMap": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true
|
|
12
|
+
},
|
|
13
|
+
"include": [
|
|
14
|
+
"./src"
|
|
15
|
+
]
|
|
16
|
+
}
|