tree-sitter-bsl 0.1.1 → 0.1.3

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/grammar.js CHANGED
@@ -1,149 +1,116 @@
1
- /**
2
- * @file Tree sitter parser for bsl
3
- * @author Dmitrii Liubanevich <dlyubanevich@gmail.com>
4
- * @license MIT
5
- */
6
-
7
1
  /// <reference types="tree-sitter-cli/dsl" />
8
- // @ts-check
9
-
10
- // https://its.1c.ru/db/v838doc#bookmark:dev:TI000000139
11
- const TOKEN_TREE_NON_SPECIAL_PUNCTUATION = [
12
- "+",
13
- "-",
14
- "*",
15
- "/",
16
- "%",
17
- "<>",
18
- "=",
19
- ">",
20
- "<",
21
- ">=",
22
- "<=",
23
- ".",
24
- ",",
25
- ";",
26
- ":",
27
- "?",
28
- "~",
29
- "|",
30
- "&",
31
- "#",
32
- ];
33
-
34
- const Keywords = {
35
- IF_KEYWORD: ($) => keyword("если", "if"),
36
-
37
- THEN_KEYWORD: ($) => keyword("тогда", "then"),
38
-
39
- ELSE_IF_KEYWORD: ($) => keyword("иначеесли", "elsif"),
40
-
41
- ELSE_KEYWORD: ($) => keyword("иначе", "else"),
42
-
43
- END_IF_KEYWORD: ($) => keyword("конецесли", "endif"),
44
-
45
- FOR_KEYWORD: ($) => keyword("для", "for"),
46
-
47
- EACH_KEYWORD: ($) => keyword("каждого", "each"),
48
-
49
- IN_KEYWORD: ($) => keyword("из", "in"),
50
-
51
- TO_KEYWORD: ($) => keyword("по", "to"),
52
-
53
- WHILE_KEYWORD: ($) => keyword("пока", "while"),
54
-
55
- DO_KEYWORD: ($) => keyword("цикл", "do"),
56
-
57
- END_DO_KEYWORD: ($) => keyword("конеццикла", "enddo"),
58
-
59
- PROCEDURE_KEYWORD: ($) => keyword("процедура", "procedure"),
60
-
61
- FUNCTION_KEYWORD: ($) => keyword("функция", "function"),
62
-
63
- END_PROCEDURE_KEYWORD: ($) => keyword("конецпроцедуры", "endprocedure"),
64
-
65
- END_FUNCTION_KEYWORD: ($) => keyword("конецфункции", "endfunction"),
66
-
67
- VAR_KEYWORD: ($) => keyword("перем", "var"),
68
-
69
- GOTO_KEYWORD: ($) => keyword("перейти", "goto"),
70
-
71
- RETURN_KEYWORD: ($) => keyword("возврат", "return"),
72
-
73
- CONTINUE_KEYWORD: ($) => keyword("продолжить", "continue"),
74
2
 
75
- BREAK_KEYWORD: ($) => keyword("прервать", "break"),
76
-
77
- AND_KEYWORD: ($) => keyword("и", "and"),
78
-
79
- OR_KEYWORD: ($) => keyword("или", "or"),
80
-
81
- NOT_KEYWORD: ($) => keyword("не", "not"),
82
-
83
- TRY_KEYWORD: ($) => keyword("попытка", "try"),
84
-
85
- EXCEPT_KEYWORD: ($) => keyword("исключение", "except"),
86
-
87
- RAISE_KEYWORD: ($) => keyword("вызватьисключение", "raise"),
88
-
89
- END_TRY_KEYWORD: ($) => keyword("конецпопытки", "endtry"),
90
-
91
- NEW_KEYWORD: ($) => keyword("новый", "new"),
92
-
93
- EXECUTE_KEYWORD: ($) => keyword("выполнить", "execute"),
94
-
95
- ADD_HANDLER_KEYWORD: ($) => keyword("добавитьобработчик", "addhandler"),
96
-
97
- REMOVE_HANDLER_KEYWORD: ($) => keyword("удалитьобработчик", "removehandler"),
98
-
99
- VAL_KEYWORD: ($) => keyword("знач", "val"),
100
-
101
- TRUE_KEYWORD: ($) => keyword("истина", "true"),
102
-
103
- FALSE_KEYWORD: ($) => keyword("ложь", "false"),
3
+ const PREC = {
4
+ LOGICAL_OR: 10,
5
+ LOGICAL_AND: 11,
6
+ COMPARISON: 13,
7
+ ADDITIVE: 14,
8
+ MULTIPLICATIVE: 15,
9
+ UNARY: 16,
10
+ ACCESS: 17,
11
+ CALL: 18,
12
+ NEW: 19,
13
+ TERNARY: 20,
14
+ ASSIGNMENT: 21,
15
+ AWAIT: 22
16
+ };
104
17
 
105
- NULL_KEYWORD: ($) => /(null)/i,
18
+ const keyword = (...words) => token(choice(...words.map(caseInsensitive)));
19
+ const caseInsensitive = (word) => new RegExp(word, "i");
20
+
21
+ const CORE_KEYWORDS = [
22
+ // Control flow
23
+ ["если", "if"],
24
+ ["тогда", "then"],
25
+ ["иначеесли", "elsif"],
26
+ ["иначе", "else"],
27
+ ["конецесли", "endif"],
28
+ ["для", "for"],
29
+ ["каждого", "each"],
30
+ ["из", "in"],
31
+ ["по", "to"],
32
+ ["пока", "while"],
33
+ ["цикл", "do"],
34
+ ["конеццикла", "enddo"],
35
+ ["перейти", "goto"],
36
+ ["возврат", "return"],
37
+ ["прервать", "break"],
38
+ ["продолжить", "continue"],
39
+
40
+ // Declarations
41
+ ["процедура", "procedure"],
42
+ ["функция", "function"],
43
+ ["конецпроцедуры", "endprocedure"],
44
+ ["конецфункции", "endfunction"],
45
+ ["перем", "var"],
46
+ ["экспорт", "export"],
47
+ ["знач", "val"],
48
+
49
+ // Values
50
+ ["истина", "true"],
51
+ ["ложь", "false"],
52
+ ["неопределено", "undefined"],
53
+
54
+ // Exceptions
55
+ ["попытка", "try"],
56
+ ["исключение", "except"],
57
+ ["вызватьисключение", "raise"],
58
+ ["конецпопытки", "endtry"],
59
+
60
+ // Async
61
+ ["асинх", "async"],
62
+ ["ждать", "await"],
63
+
64
+ // New && exec
65
+ ["новый", "new"],
66
+ ["выполнить", "execute"],
67
+
68
+ // Handlers
69
+ ["добавитьобработчик", "addhandler"],
70
+ ["удалитьобработчик", "removehandler"],
71
+
72
+ // Operators
73
+ ["и", "and"],
74
+ ["или", "or"],
75
+ ["не", "not"],
76
+ ];
106
77
 
107
- UNDEFINED_KEYWORD: ($) => keyword("неопределено", "undefine"),
78
+ const PREPROC_KEYWORDS = [
79
+ ["если", "if"],
80
+ ["иначеесли", "elsif"],
81
+ ["иначе", "else"],
82
+ ["конецесли", "endif"],
83
+ ["область", "region"],
84
+ ["конецобласти", "endregion"],
85
+ ];
108
86
 
109
- EXPORT_KEYWORD: ($) => keyword("экспорт", "export"),
87
+ function buildKeywords() {
88
+ const kw = {};
89
+ for (const [rus, eng] of CORE_KEYWORDS) {
90
+ kw[`${eng.toUpperCase()}_KEYWORD`] = ($) => keyword(rus, eng);
91
+ }
110
92
 
111
- PREPROC_IF_KEYWORD: ($) => keyword("#если", "#if"),
112
- PREPROC_ELSE_IF_KEYWORD: ($) => keyword("#иначеесли", "#elsif"),
113
- PREPROC_ELSE_KEYWORD: ($) => keyword("#иначе", "#else"),
114
- PREPROC_END_IF_KEYWORD: ($) => keyword("#конецесли", "#endif"),
115
- PREPROC_REGION_START_KEYWORD: ($) => keyword("#область", "#region"),
116
- PREPROC_REGION_END_KEYWORD: ($) => keyword("#конецобласти", "#endregion"),
93
+ for (const [rus, eng] of PREPROC_KEYWORDS) {
94
+ kw[`PREPROC_${eng.toUpperCase()}_KEYWORD`] = ($) =>
95
+ keyword("#" + rus, "#" + eng);
96
+ }
117
97
 
118
- ASYNC_KEYWORD: ($) => keyword("асинх", "async"),
119
- AWAIT_KEYWORD: ($) => keyword("ждать", "await"),
120
- };
121
-
122
- const Operations = {
123
- operation: ($) => {
124
- const boolOperation = [$.AND_KEYWORD, $.OR_KEYWORD];
125
- const compareOperation = ["<>", "=", ">", "<", ">=", "<="];
126
- const arithmeticOperation = ["+", "-", "*", "/", "%"];
127
- return choice(
128
- ...boolOperation,
129
- ...arithmeticOperation,
130
- ...compareOperation
131
- );
132
- },
133
- };
98
+ kw["NULL_KEYWORD"] = ($) => token(/null/i);
99
+ return kw;
100
+ }
134
101
 
135
102
  const Preprocessor = {
136
103
  preprocessor: ($) => {
137
104
  const region = [
138
- seq($.PREPROC_REGION_START_KEYWORD, $.identifier),
139
- $.PREPROC_REGION_END_KEYWORD,
105
+ seq($.PREPROC_REGION_KEYWORD, $.identifier),
106
+ $.PREPROC_ENDREGION_KEYWORD,
140
107
  ];
141
108
 
142
109
  const preproc_if = [
143
110
  seq($.PREPROC_IF_KEYWORD, $.expression, $.THEN_KEYWORD),
144
- seq($.PREPROC_ELSE_IF_KEYWORD, $.expression, $.THEN_KEYWORD),
111
+ seq($.PREPROC_ELSIF_KEYWORD, $.expression, $.THEN_KEYWORD),
145
112
  $.PREPROC_ELSE_KEYWORD,
146
- $.PREPROC_END_IF_KEYWORD,
113
+ $.PREPROC_ENDIF_KEYWORD,
147
114
  ];
148
115
 
149
116
  const preproc_change = [
@@ -232,7 +199,7 @@ module.exports = grammar({
232
199
  field("parameters", $.parameters),
233
200
  optional(field("export", $.EXPORT_KEYWORD)),
234
201
  repeat($.statement),
235
- $.END_PROCEDURE_KEYWORD
202
+ $.ENDPROCEDURE_KEYWORD
236
203
  ),
237
204
 
238
205
  function_definition: ($) =>
@@ -243,7 +210,7 @@ module.exports = grammar({
243
210
  field("parameters", $.parameters),
244
211
  optional(field("export", $.EXPORT_KEYWORD)),
245
212
  repeat($.statement),
246
- $.END_FUNCTION_KEYWORD
213
+ $.ENDFUNCTION_KEYWORD
247
214
  ),
248
215
 
249
216
  var_definition: ($) =>
@@ -256,8 +223,7 @@ module.exports = grammar({
256
223
  optional(";")
257
224
  )
258
225
  ),
259
- parameters: ($) =>
260
- seq("(", sepBy(",", field("parameter", $.parameter)), ")"),
226
+ parameters: ($) => seq("(", commaSep(field("parameter", $.parameter)), ")"),
261
227
 
262
228
  parameter: ($) =>
263
229
  seq(
@@ -292,7 +258,7 @@ module.exports = grammar({
292
258
  $.await_statement
293
259
  ),
294
260
 
295
- call_statement: ($) => seq($.call_expression, optional(";")),
261
+ call_statement: ($) => seq(choice($.method_call, $.call_expression), optional(";")),
296
262
 
297
263
  assignment_statement: ($) =>
298
264
  seq(
@@ -311,7 +277,7 @@ module.exports = grammar({
311
277
  repeat($.statement),
312
278
  $.EXCEPT_KEYWORD,
313
279
  repeat($.statement),
314
- $.END_TRY_KEYWORD,
280
+ $.ENDTRY_KEYWORD,
315
281
  optional(";")
316
282
  ),
317
283
 
@@ -331,23 +297,16 @@ module.exports = grammar({
331
297
  $.expression,
332
298
  $.THEN_KEYWORD,
333
299
  repeat($.statement),
334
- repeat(
335
- seq(
336
- $.ELSE_IF_KEYWORD,
337
- $.expression,
338
- $.THEN_KEYWORD,
339
- repeat($.statement)
340
- )
341
- ),
342
- optional($.else),
343
- $.END_IF_KEYWORD,
300
+ repeat($.elseif_clause),
301
+ optional($.else_clause),
302
+ $.ENDIF_KEYWORD,
344
303
  optional(";")
345
304
  ),
346
305
 
347
- else_if: ($) =>
348
- seq($.ELSE_IF_KEYWORD, $.expression, $.THEN_KEYWORD, repeat($.statement)),
306
+ elseif_clause: ($) =>
307
+ seq($.ELSIF_KEYWORD, $.expression, $.THEN_KEYWORD, repeat($.statement)),
349
308
 
350
- else: ($) => seq($.ELSE_KEYWORD, repeat($.statement)),
309
+ else_clause: ($) => seq($.ELSE_KEYWORD, repeat($.statement)),
351
310
 
352
311
  while_statement: ($) =>
353
312
  seq(
@@ -355,18 +314,20 @@ module.exports = grammar({
355
314
  $.expression,
356
315
  $.DO_KEYWORD,
357
316
  repeat($.statement),
358
- $.END_DO_KEYWORD
317
+ $.ENDDO_KEYWORD
359
318
  ),
360
319
 
361
320
  for_statement: ($) =>
362
321
  seq(
363
322
  $.FOR_KEYWORD,
364
- $.assignment_statement,
323
+ $.identifier,
324
+ "=",
325
+ $.expression,
365
326
  $.TO_KEYWORD,
366
327
  $.expression,
367
328
  $.DO_KEYWORD,
368
329
  repeat($.statement),
369
- $.END_DO_KEYWORD,
330
+ $.ENDDO_KEYWORD,
370
331
  optional(";")
371
332
  ),
372
333
 
@@ -377,13 +338,12 @@ module.exports = grammar({
377
338
  $.identifier,
378
339
  $.IN_KEYWORD,
379
340
  $.expression,
380
- $.TO_KEYWORD,
381
- $.expression,
382
341
  $.DO_KEYWORD,
383
342
  repeat($.statement),
384
- $.END_DO_KEYWORD,
343
+ $.ENDDO_KEYWORD,
385
344
  optional(";")
386
345
  ),
346
+
387
347
  continue_statement: ($) => seq($.CONTINUE_KEYWORD, optional(";")),
388
348
 
389
349
  break_statement: ($) => seq($.BREAK_KEYWORD, optional(";")),
@@ -397,17 +357,11 @@ module.exports = grammar({
397
357
  label_statement: ($) => seq("~", $.identifier, ":", optional(";")),
398
358
 
399
359
  add_handler_statement: ($) =>
400
- seq(
401
- $.ADD_HANDLER_KEYWORD,
402
- $.expression,
403
- ",",
404
- $.expression,
405
- optional(";")
406
- ),
360
+ seq($.ADDHANDLER_KEYWORD, $.expression, ",", $.expression, optional(";")),
407
361
 
408
362
  remove_handler_statement: ($) =>
409
363
  seq(
410
- $.REMOVE_HANDLER_KEYWORD,
364
+ $.REMOVEHANDLER_KEYWORD,
411
365
  $.expression,
412
366
  ",",
413
367
  $.expression,
@@ -424,26 +378,43 @@ module.exports = grammar({
424
378
  $.binary_expression,
425
379
  $.ternary_expression,
426
380
  $.new_expression,
381
+ $.method_call,
427
382
  $.call_expression,
428
383
  $.property_access,
429
384
  $.await_expression
430
385
  ),
386
+
431
387
  unary_expression: ($) =>
432
388
  prec.left(
389
+ PREC.UNARY,
433
390
  seq(
434
- field("operator", alias(choice("-", "+", $.NOT_KEYWORD), $.operation)),
391
+ field("operator", alias(choice("-", "+", $.NOT_KEYWORD), $.operator)),
435
392
  field("argument", $.expression)
436
393
  )
437
394
  ),
438
395
 
439
- binary_expression: ($) =>
440
- prec.left(
441
- seq(
442
- field("left", $.expression),
443
- field("operator", $.operation),
444
- field("right", $.expression)
445
- )
446
- ),
396
+ binary_expression: ($) => {
397
+ const operations = [
398
+ [PREC.LOGICAL_AND, $.AND_KEYWORD],
399
+ [PREC.LOGICAL_OR, $.OR_KEYWORD],
400
+ [PREC.COMPARISON, choice("<>", "=", ">", "<", ">=", "<=")],
401
+ [PREC.ADDITIVE, choice("+", "-")],
402
+ [PREC.MULTIPLICATIVE, choice("*", "/", "%")],
403
+ ];
404
+
405
+ return choice(
406
+ ...operations.map(([priority, operator]) => {
407
+ return prec.left(
408
+ priority,
409
+ seq(
410
+ field("left", $.expression),
411
+ field("operator", alias(operator, $.operator)),
412
+ field("right", $.expression)
413
+ )
414
+ );
415
+ })
416
+ );
417
+ },
447
418
 
448
419
  ternary_expression: ($) =>
449
420
  prec.right(
@@ -459,51 +430,51 @@ module.exports = grammar({
459
430
  ),
460
431
 
461
432
  new_expression: ($) =>
462
- choice(
463
- prec.right(
464
- 0,
433
+ prec(
434
+ PREC.NEW,
435
+ choice(
465
436
  seq(
466
437
  $.NEW_KEYWORD,
467
438
  field("type", $.identifier),
468
439
  field("arguments", optional($.arguments))
469
- )
470
- ),
471
- seq($.NEW_KEYWORD, field("arguments", $.arguments))
472
- ),
473
-
474
- call_expression: ($) =>
475
- prec(
476
- 2,
477
- choice(
478
- $.method_call,
479
- seq(alias($.identifier, $.property), repeat($._access), ".", $.method_call),
480
- seq($.method_call, repeat($._access), ".", $.method_call)
440
+ ),
441
+ seq($.NEW_KEYWORD, field("arguments", $.arguments))
481
442
  )
482
443
  ),
483
444
 
484
- await_expression: ($) => prec(1, seq($.AWAIT_KEYWORD, $.expression)),
445
+ call_expression: ($) => prec(PREC.CALL - 1, $._access_call),
485
446
 
486
- _assignment_member: ($) =>
487
- choice(
488
- $.identifier,
489
- $.property_access
490
- ),
447
+ await_expression: ($) => prec(PREC.AWAIT, seq($.AWAIT_KEYWORD, $.expression)),
491
448
 
492
- property_access: ($) => seq(choice($.identifier, $.method_call), repeat1($._access)),
449
+ _assignment_member: ($) => choice($.identifier, $.property_access),
493
450
 
494
- _access: ($) => choice($._access_call, $._access_index, $._access_property),
495
- _access_call: ($) => seq(".", $.method_call),
496
- _access_index: ($) => seq("[", alias($.expression, $.index), "]"),
497
- _access_property: ($) => seq(".", alias($.identifier, $.property)),
451
+ property_access: ($) =>
452
+ prec(PREC.ACCESS, choice($._access_property, $._access_index)),
453
+
454
+ access: ($) =>
455
+ prec(
456
+ 1,
457
+ choice(
458
+ $._access_call,
459
+ $._access_index,
460
+ $._access_property,
461
+ $.identifier,
462
+ $.method_call
463
+ )
464
+ ),
465
+ _access_call: ($) => seq($.access, ".", $.method_call),
466
+ _access_index: ($) =>
467
+ seq($.access, "[", alias($.expression, $.index), "]"),
468
+ _access_property: ($) =>
469
+ seq($.access, ".", alias($.identifier, $.property)),
498
470
 
499
471
  method_call: ($) =>
500
- seq(field("name", $.identifier), field("arguments", $.arguments)),
472
+ prec(PREC.CALL, seq(field("name", $.identifier), field("arguments", $.arguments))),
501
473
 
502
474
  arguments: ($) => seq("(", sepBy(",", $.expression), ")"),
503
475
 
504
476
  // Primitive
505
- ...Keywords,
506
- ...Operations,
477
+ ...buildKeywords(),
507
478
  ...Preprocessor,
508
479
 
509
480
  _const_value: ($) =>
@@ -544,10 +515,6 @@ module.exports = grammar({
544
515
  identifier: ($) => /[\wа-я_][\wа-я_0-9]*/i,
545
516
 
546
517
  line_comment: ($) => seq("//", /.*/),
547
- _non_special_token: ($) =>
548
- choice(
549
- prec.right(repeat1(choice(...TOKEN_TREE_NON_SPECIAL_PUNCTUATION)))
550
- ),
551
518
  },
552
519
  });
553
520
 
@@ -590,11 +557,3 @@ function sepBy(sep, rule) {
590
557
  function sepBy1(sep, rule) {
591
558
  return seq(rule, repeat(seq(sep, rule)));
592
559
  }
593
-
594
- function keyword(...words) {
595
- return token(choice(...words.map(caseInsensitive)));
596
- }
597
-
598
- function caseInsensitive(word) {
599
- return new RegExp(word, "i");
600
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-sitter-bsl",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "1C (BSL) language",
5
5
  "repository": "https://github.com/tree-sitter/tree-sitter-bsl",
6
6
  "license": "MIT",