@birdcc/parser 0.0.1-alpha.0 → 0.0.1-alpha.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@birdcc/parser",
3
- "version": "0.0.1-alpha.0",
3
+ "version": "0.0.1-alpha.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "GPL-3.0-only",
@@ -9,14 +9,21 @@
9
9
  "email": "npm-dev@birdcc.link",
10
10
  "url": "https://github.com/bird-chinese-community/"
11
11
  },
12
+ "description": "Tree-sitter parser for BIRD2 configuration files.",
12
13
  "main": "./dist/index.js",
13
- "types": "./src/index.ts",
14
+ "types": "./dist/index.d.ts",
14
15
  "exports": {
15
16
  ".": {
16
- "types": "./src/index.ts",
17
+ "types": "./dist/index.d.ts",
17
18
  "default": "./dist/index.js"
18
19
  }
19
20
  },
21
+ "sideEffects": false,
22
+ "files": [
23
+ "dist/**",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
20
27
  "devDependencies": {
21
28
  "tree-sitter-cli": "0.25.10"
22
29
  },
package/.oxfmtrc.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "$schema": "../../../node_modules/oxfmt/configuration_schema.json",
3
- "ignorePatterns": [
4
- "node_modules/*",
5
- "package.json",
6
- "dist/*",
7
- ".turbo/*",
8
- "target/*",
9
- "*.lock",
10
- "pnpm-*.yaml",
11
- "*-lock.json"
12
- ],
13
- "printWidth": 80,
14
- "tabWidth": 2,
15
- "useTabs": false
16
- }
package/grammar.js DELETED
@@ -1,601 +0,0 @@
1
- const commaSep1 = (rule) => seq(rule, repeat(seq(",", rule)));
2
-
3
- export default grammar({
4
- name: "bird",
5
-
6
- extras: ($) => [/\s/, $.comment],
7
-
8
- word: ($) => $.identifier,
9
-
10
- rules: {
11
- // Entry: keep top-level declarations explicit so downstream AST extraction stays stable.
12
- source_file: ($) => repeat($._top_level_item),
13
-
14
- _top_level_item: ($) =>
15
- choice(
16
- $.include_declaration,
17
- $.define_declaration,
18
- $.router_id_declaration,
19
- $.table_declaration,
20
- $.protocol_declaration,
21
- $.template_declaration,
22
- $.filter_declaration,
23
- $.function_declaration,
24
- $.top_level_statement,
25
- ),
26
-
27
- comment: () => token(seq("#", /.*/)),
28
-
29
- string: () =>
30
- token(
31
- choice(
32
- seq('"', repeat(choice(/[^"\\\n]+/, /\\./)), '"'),
33
- seq("'", repeat(choice(/[^'\\\n]+/, /\\./)), "'"),
34
- ),
35
- ),
36
-
37
- identifier: () => /[A-Za-z_][A-Za-z0-9_-]*/,
38
- number: () => /[0-9][0-9A-Za-z_]*/,
39
- ipv4_literal: () => token(/[0-9]{1,3}(\.[0-9]{1,3}){3}/),
40
- ipv6_literal: () => token(/[0-9A-Fa-f]*:[0-9A-Fa-f:]+/),
41
- ip_literal: ($) => choice($.ipv4_literal, $.ipv6_literal),
42
- prefix_literal: () =>
43
- token(/[0-9A-Fa-f:.]+\/[0-9]{1,3}([+-]|\{[0-9]{1,3},[0-9]{1,3}\})?/),
44
-
45
- // Generic fallback token used to keep recovery resilient in partial grammar coverage.
46
- raw_token: () => token(prec(-1, /[^{}\s"';#]+/)),
47
-
48
- // Top-level declarations
49
- include_declaration: ($) =>
50
- seq("include", optional(field("path", $.string)), ";"),
51
-
52
- define_declaration: ($) =>
53
- choice(
54
- seq(
55
- "define",
56
- field("name", $.identifier),
57
- optional(
58
- seq(
59
- "=",
60
- repeat1(
61
- choice(
62
- $.string,
63
- $.number,
64
- $.ip_literal,
65
- $.prefix_literal,
66
- $.identifier,
67
- $.raw_token,
68
- $.block,
69
- ),
70
- ),
71
- ),
72
- ),
73
- ";",
74
- ),
75
- seq("define", ";"),
76
- ),
77
-
78
- router_id_declaration: ($) =>
79
- seq("router", "id", optional(field("value", $.router_id_value)), ";"),
80
-
81
- router_id_value: ($) =>
82
- choice(
83
- $.router_id_from_clause,
84
- $.ipv4_literal,
85
- $.number,
86
- $.identifier,
87
- $.raw_token,
88
- ),
89
-
90
- router_id_from_clause: ($) =>
91
- seq("from", field("from_source", choice("routing", "dynamic"))),
92
-
93
- table_declaration: ($) =>
94
- choice(
95
- seq(
96
- field("table_type", "routing"),
97
- "table",
98
- optional(field("name", $.identifier)),
99
- optional(field("attrs", $.table_attrs)),
100
- ";",
101
- ),
102
- seq(
103
- field("table_type", $.table_type),
104
- "table",
105
- optional(field("name", $.identifier)),
106
- optional(field("attrs", $.table_attrs)),
107
- ";",
108
- ),
109
- seq("table", ";"),
110
- ),
111
-
112
- table_type: () =>
113
- choice("ipv4", "ipv6", "vpn4", "vpn6", "roa4", "roa6", "flow4", "flow6"),
114
-
115
- table_attrs: ($) =>
116
- seq(
117
- "attrs",
118
- choice(
119
- $.identifier,
120
- seq("(", commaSep1(choice($.identifier, $.raw_token)), ")"),
121
- seq(
122
- "{",
123
- repeat(
124
- choice($.identifier, $.raw_token, $.number, $.string, ",", ";"),
125
- ),
126
- "}",
127
- ),
128
- ),
129
- ),
130
-
131
- protocol_declaration: ($) =>
132
- choice(
133
- prec(
134
- 1,
135
- seq(
136
- "protocol",
137
- field("protocol_type", $.identifier),
138
- field("body", $.block),
139
- optional(";"),
140
- ),
141
- ),
142
- prec(
143
- 2,
144
- seq(
145
- "protocol",
146
- field("protocol_type", $.identifier),
147
- field("protocol_variant", $.protocol_variant),
148
- field("name", $.identifier),
149
- optional(seq("from", field("from_template", $.identifier))),
150
- field("body", $.block),
151
- optional(";"),
152
- ),
153
- ),
154
- prec(
155
- 2,
156
- seq(
157
- "protocol",
158
- field("protocol_type", $.identifier),
159
- field("name", $.identifier),
160
- optional(seq("from", field("from_template", $.identifier))),
161
- field("body", $.block),
162
- optional(";"),
163
- ),
164
- ),
165
- ),
166
-
167
- protocol_variant: () => token(prec(1, /v[0-9]+/)),
168
-
169
- template_declaration: ($) =>
170
- choice(
171
- prec(
172
- 1,
173
- seq(
174
- "template",
175
- field("template_type", $.identifier),
176
- field("body", $.block),
177
- optional(";"),
178
- ),
179
- ),
180
- prec(
181
- 2,
182
- seq(
183
- "template",
184
- field("template_type", $.identifier),
185
- field("name", $.identifier),
186
- field("body", $.block),
187
- optional(";"),
188
- ),
189
- ),
190
- ),
191
-
192
- filter_declaration: ($) =>
193
- choice(
194
- prec(1, seq("filter", field("body", $.block), optional(";"))),
195
- prec(
196
- 2,
197
- seq(
198
- "filter",
199
- field("name", $.identifier),
200
- field("body", $.block),
201
- optional(";"),
202
- ),
203
- ),
204
- ),
205
-
206
- function_declaration: ($) =>
207
- choice(
208
- prec(
209
- 1,
210
- seq(
211
- "function",
212
- optional($.parameter_list),
213
- optional($.return_annotation),
214
- field("body", $.block),
215
- optional(";"),
216
- ),
217
- ),
218
- prec(
219
- 2,
220
- seq(
221
- "function",
222
- field("name", $.identifier),
223
- optional($.parameter_list),
224
- optional($.return_annotation),
225
- field("body", $.block),
226
- optional(";"),
227
- ),
228
- ),
229
- ),
230
-
231
- parameter_list: ($) =>
232
- seq(
233
- "(",
234
- optional(
235
- commaSep1(
236
- choice(
237
- $.identifier,
238
- $.string,
239
- $.number,
240
- $.ip_literal,
241
- $.prefix_literal,
242
- $.raw_token,
243
- ),
244
- ),
245
- ),
246
- ")",
247
- ),
248
-
249
- return_annotation: ($) =>
250
- seq("->", repeat1(choice($.identifier, $.raw_token))),
251
-
252
- top_level_statement: ($) =>
253
- prec(
254
- -1,
255
- seq(
256
- repeat1(
257
- choice(
258
- $.string,
259
- $.number,
260
- $.ip_literal,
261
- $.prefix_literal,
262
- $.identifier,
263
- $.raw_token,
264
- $.block,
265
- ),
266
- ),
267
- ";",
268
- ),
269
- ),
270
-
271
- // Block is intentionally permissive for error recovery (missing brace / incomplete header).
272
- block: ($) => seq("{", repeat($._block_item), "}"),
273
-
274
- _block_item: ($) =>
275
- choice(
276
- $.local_as_statement,
277
- $.neighbor_statement,
278
- $.channel_keep_filtered_statement,
279
- $.channel_limit_statement,
280
- $.import_statement,
281
- $.export_statement,
282
- $.channel_statement,
283
- $.if_statement,
284
- $.accept_statement,
285
- $.reject_statement,
286
- $.return_statement,
287
- $.case_statement,
288
- $.expression_statement,
289
- $.block,
290
- ";",
291
- ),
292
-
293
- // Protocol common statements used by linter rules.
294
- local_as_statement: ($) =>
295
- seq(
296
- "local",
297
- "as",
298
- field("asn", choice($.number, $.identifier, $.raw_token)),
299
- ";",
300
- ),
301
-
302
- neighbor_statement: ($) =>
303
- seq(
304
- "neighbor",
305
- field(
306
- "address",
307
- choice($.ip_literal, $.number, $.identifier, $.string, $.raw_token),
308
- ),
309
- optional(
310
- seq(
311
- "%",
312
- field("interface", choice($.identifier, $.string, $.raw_token)),
313
- ),
314
- ),
315
- optional(
316
- seq("as", field("asn", choice($.number, $.identifier, $.raw_token))),
317
- ),
318
- ";",
319
- ),
320
-
321
- channel_statement: ($) =>
322
- choice(
323
- prec(
324
- 2,
325
- seq(
326
- field("channel_type", $.channel_type),
327
- field("body", $.channel_block),
328
- ";",
329
- ),
330
- ),
331
- prec(
332
- 1,
333
- seq(
334
- field("channel_type", $.channel_type),
335
- field("body", $.channel_block),
336
- ),
337
- ),
338
- seq(field("channel_type", $.channel_type), ";"),
339
- ),
340
-
341
- channel_type: () =>
342
- choice(
343
- "ipv4",
344
- "ipv6",
345
- "vpn4",
346
- "vpn6",
347
- "roa4",
348
- "roa6",
349
- "flow4",
350
- "flow6",
351
- "mpls",
352
- ),
353
-
354
- channel_block: ($) => seq("{", repeat($._channel_item), "}"),
355
-
356
- _channel_item: ($) =>
357
- choice(
358
- $.channel_table_statement,
359
- $.channel_keep_filtered_statement,
360
- $.channel_limit_statement,
361
- $.import_statement,
362
- $.export_statement,
363
- $.channel_debug_statement,
364
- $.if_statement,
365
- $.accept_statement,
366
- $.reject_statement,
367
- $.return_statement,
368
- $.case_statement,
369
- $.expression_statement,
370
- $.block,
371
- ";",
372
- ),
373
-
374
- channel_table_statement: ($) =>
375
- seq("table", field("table_name", $.identifier), ";"),
376
-
377
- channel_keep_filtered_statement: ($) =>
378
- seq(
379
- "import",
380
- "keep",
381
- "filtered",
382
- field("switch_value", choice($.identifier, $.number, $.raw_token)),
383
- ";",
384
- ),
385
-
386
- channel_limit_statement: ($) =>
387
- seq(
388
- field("direction", choice("import", "receive", "export")),
389
- "limit",
390
- field(
391
- "limit_value",
392
- choice("off", $.number, $.identifier, $.raw_token),
393
- ),
394
- optional(
395
- seq(
396
- "action",
397
- field("limit_action", choice($.identifier, $.raw_token)),
398
- ),
399
- ),
400
- ";",
401
- ),
402
-
403
- channel_debug_statement: ($) =>
404
- seq(
405
- "debug",
406
- field(
407
- "debug_clause",
408
- repeat1(
409
- choice(
410
- $.identifier,
411
- $.number,
412
- $.raw_token,
413
- $.string,
414
- "all",
415
- "off",
416
- ",",
417
- "{",
418
- "}",
419
- ),
420
- ),
421
- ),
422
- ";",
423
- ),
424
-
425
- import_statement: ($) =>
426
- choice(
427
- seq(
428
- "import",
429
- field(
430
- "clause",
431
- choice(
432
- $.all_clause,
433
- $.none_clause,
434
- $.where_clause,
435
- $.filter_name_clause,
436
- $.generic_clause,
437
- ),
438
- ),
439
- ";",
440
- ),
441
- seq("import", field("clause", $.filter_block_clause)),
442
- ),
443
-
444
- export_statement: ($) =>
445
- choice(
446
- seq(
447
- "export",
448
- field(
449
- "clause",
450
- choice(
451
- $.all_clause,
452
- $.none_clause,
453
- $.where_clause,
454
- $.filter_name_clause,
455
- $.generic_clause,
456
- ),
457
- ),
458
- ";",
459
- ),
460
- seq("export", field("clause", $.filter_block_clause)),
461
- ),
462
-
463
- all_clause: () => "all",
464
-
465
- none_clause: () => "none",
466
-
467
- where_clause: ($) =>
468
- seq("where", field("where_expression", $.simple_expression)),
469
-
470
- filter_name_clause: ($) =>
471
- seq("filter", field("filter_name", $.identifier)),
472
-
473
- filter_block_clause: ($) => seq("filter", field("filter_block", $.block)),
474
-
475
- generic_clause: ($) =>
476
- repeat1(
477
- choice(
478
- $.string,
479
- $.number,
480
- $.ip_literal,
481
- $.prefix_literal,
482
- $.identifier,
483
- $.raw_token,
484
- $.block,
485
- ),
486
- ),
487
-
488
- if_statement: ($) =>
489
- seq(
490
- "if",
491
- optional(field("condition", $.simple_expression)),
492
- "then",
493
- field("consequence", $.inline_statement),
494
- optional(seq("else", field("alternative", $.inline_statement))),
495
- ),
496
-
497
- inline_statement: ($) =>
498
- choice(
499
- $.block,
500
- $.accept_statement,
501
- $.reject_statement,
502
- $.return_statement,
503
- $.expression_statement,
504
- ),
505
-
506
- accept_statement: () => seq("accept", ";"),
507
-
508
- reject_statement: () => seq("reject", ";"),
509
-
510
- return_statement: ($) =>
511
- seq("return", optional(field("value", $.simple_expression)), ";"),
512
-
513
- case_statement: ($) =>
514
- seq(
515
- "case",
516
- optional(field("subject", $.simple_expression)),
517
- field("body", $.block),
518
- ),
519
-
520
- expression_statement: ($) =>
521
- seq(field("expression", $.simple_expression), ";"),
522
-
523
- simple_expression: ($) =>
524
- choice($.binary_expression, $.unary_expression, $.expression_atom),
525
-
526
- binary_expression: ($) =>
527
- prec.left(
528
- seq(
529
- field("left", $.expression_atom),
530
- field(
531
- "operator",
532
- choice("~", "=", "!=", "<", ">", "<=", ">=", "&&", "||"),
533
- ),
534
- field("right", $.expression_atom),
535
- ),
536
- ),
537
-
538
- unary_expression: ($) =>
539
- prec(2, seq(choice("!", "-"), field("value", $.expression_atom))),
540
-
541
- expression_atom: ($) =>
542
- choice(
543
- $.function_call,
544
- $.member_expression,
545
- $.set_literal,
546
- $.literal_expression,
547
- $.identifier,
548
- $.raw_token,
549
- seq("(", $.simple_expression, ")"),
550
- ),
551
-
552
- function_call: ($) =>
553
- seq(
554
- field("name", $.identifier),
555
- "(",
556
- optional(commaSep1($.simple_expression)),
557
- ")",
558
- ),
559
-
560
- member_expression: ($) =>
561
- seq(
562
- field("object", $.identifier),
563
- repeat1(seq(".", field("member", $.identifier))),
564
- ),
565
-
566
- set_literal: ($) =>
567
- seq(
568
- "[",
569
- repeat(
570
- choice(
571
- $.string,
572
- $.number,
573
- $.ip_literal,
574
- $.prefix_literal,
575
- $.identifier,
576
- $.raw_token,
577
- ",",
578
- "..",
579
- "+",
580
- "-",
581
- "{",
582
- "}",
583
- "*",
584
- "=",
585
- ),
586
- ),
587
- "]",
588
- ),
589
-
590
- literal_expression: ($) =>
591
- choice(
592
- $.string,
593
- $.number,
594
- $.ip_literal,
595
- $.prefix_literal,
596
- $.bool_literal,
597
- ),
598
-
599
- bool_literal: () => choice("true", "false"),
600
- },
601
- });
@@ -1,21 +0,0 @@
1
- import { copyFileSync, existsSync, mkdirSync, renameSync } from "node:fs";
2
- import { dirname, join } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
-
5
- const scriptDir = dirname(fileURLToPath(import.meta.url));
6
- const pkgDir = dirname(scriptDir);
7
-
8
- const rootWasm = join(pkgDir, "tree-sitter-birdcc.wasm");
9
- const srcWasm = join(pkgDir, "src", "tree-sitter-birdcc.wasm");
10
- const distWasm = join(pkgDir, "dist", "tree-sitter-birdcc.wasm");
11
-
12
- if (existsSync(rootWasm)) {
13
- renameSync(rootWasm, srcWasm);
14
- }
15
-
16
- if (!existsSync(srcWasm)) {
17
- throw new Error(`Missing WASM grammar file: ${srcWasm}`);
18
- }
19
-
20
- mkdirSync(dirname(distWasm), { recursive: true });
21
- copyFileSync(srcWasm, distWasm);