tree-sitter-bsl 0.1.2 → 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
2
 
73
- CONTINUE_KEYWORD: ($) => keyword("продолжить", "continue"),
74
-
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"),
104
-
105
- NULL_KEYWORD: ($) => /(null)/i,
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
+ };
106
17
 
107
- UNDEFINED_KEYWORD: ($) => keyword("неопределено", "undefine"),
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
+ ];
108
77
 
109
- EXPORT_KEYWORD: ($) => keyword("экспорт", "export"),
78
+ const PREPROC_KEYWORDS = [
79
+ ["если", "if"],
80
+ ["иначеесли", "elsif"],
81
+ ["иначе", "else"],
82
+ ["конецесли", "endif"],
83
+ ["область", "region"],
84
+ ["конецобласти", "endregion"],
85
+ ];
110
86
 
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"),
87
+ function buildKeywords() {
88
+ const kw = {};
89
+ for (const [rus, eng] of CORE_KEYWORDS) {
90
+ kw[`${eng.toUpperCase()}_KEYWORD`] = ($) => keyword(rus, eng);
91
+ }
117
92
 
118
- ASYNC_KEYWORD: ($) => keyword("асинх", "async"),
119
- AWAIT_KEYWORD: ($) => keyword("ждать", "await"),
120
- };
93
+ for (const [rus, eng] of PREPROC_KEYWORDS) {
94
+ kw[`PREPROC_${eng.toUpperCase()}_KEYWORD`] = ($) =>
95
+ keyword("#" + rus, "#" + eng);
96
+ }
121
97
 
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
 
@@ -379,9 +340,10 @@ module.exports = grammar({
379
340
  $.expression,
380
341
  $.DO_KEYWORD,
381
342
  repeat($.statement),
382
- $.END_DO_KEYWORD,
343
+ $.ENDDO_KEYWORD,
383
344
  optional(";")
384
345
  ),
346
+
385
347
  continue_statement: ($) => seq($.CONTINUE_KEYWORD, optional(";")),
386
348
 
387
349
  break_statement: ($) => seq($.BREAK_KEYWORD, optional(";")),
@@ -395,17 +357,11 @@ module.exports = grammar({
395
357
  label_statement: ($) => seq("~", $.identifier, ":", optional(";")),
396
358
 
397
359
  add_handler_statement: ($) =>
398
- seq(
399
- $.ADD_HANDLER_KEYWORD,
400
- $.expression,
401
- ",",
402
- $.expression,
403
- optional(";")
404
- ),
360
+ seq($.ADDHANDLER_KEYWORD, $.expression, ",", $.expression, optional(";")),
405
361
 
406
362
  remove_handler_statement: ($) =>
407
363
  seq(
408
- $.REMOVE_HANDLER_KEYWORD,
364
+ $.REMOVEHANDLER_KEYWORD,
409
365
  $.expression,
410
366
  ",",
411
367
  $.expression,
@@ -422,26 +378,43 @@ module.exports = grammar({
422
378
  $.binary_expression,
423
379
  $.ternary_expression,
424
380
  $.new_expression,
381
+ $.method_call,
425
382
  $.call_expression,
426
383
  $.property_access,
427
384
  $.await_expression
428
385
  ),
386
+
429
387
  unary_expression: ($) =>
430
388
  prec.left(
389
+ PREC.UNARY,
431
390
  seq(
432
- field("operator", alias(choice("-", "+", $.NOT_KEYWORD), $.operation)),
391
+ field("operator", alias(choice("-", "+", $.NOT_KEYWORD), $.operator)),
433
392
  field("argument", $.expression)
434
393
  )
435
394
  ),
436
395
 
437
- binary_expression: ($) =>
438
- prec.left(
439
- seq(
440
- field("left", $.expression),
441
- field("operator", $.operation),
442
- field("right", $.expression)
443
- )
444
- ),
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
+ },
445
418
 
446
419
  ternary_expression: ($) =>
447
420
  prec.right(
@@ -457,51 +430,51 @@ module.exports = grammar({
457
430
  ),
458
431
 
459
432
  new_expression: ($) =>
460
- choice(
461
- prec.right(
462
- 0,
433
+ prec(
434
+ PREC.NEW,
435
+ choice(
463
436
  seq(
464
437
  $.NEW_KEYWORD,
465
438
  field("type", $.identifier),
466
439
  field("arguments", optional($.arguments))
467
- )
468
- ),
469
- seq($.NEW_KEYWORD, field("arguments", $.arguments))
470
- ),
471
-
472
- call_expression: ($) =>
473
- prec(
474
- 2,
475
- choice(
476
- $.method_call,
477
- seq(alias($.identifier, $.property), repeat($._access), ".", $.method_call),
478
- seq($.method_call, repeat($._access), ".", $.method_call)
440
+ ),
441
+ seq($.NEW_KEYWORD, field("arguments", $.arguments))
479
442
  )
480
443
  ),
481
444
 
482
- await_expression: ($) => prec(1, seq($.AWAIT_KEYWORD, $.expression)),
445
+ call_expression: ($) => prec(PREC.CALL - 1, $._access_call),
483
446
 
484
- _assignment_member: ($) =>
485
- choice(
486
- $.identifier,
487
- $.property_access
488
- ),
447
+ await_expression: ($) => prec(PREC.AWAIT, seq($.AWAIT_KEYWORD, $.expression)),
448
+
449
+ _assignment_member: ($) => choice($.identifier, $.property_access),
489
450
 
490
- property_access: ($) => seq(choice($.identifier, $.method_call), repeat1($._access)),
451
+ property_access: ($) =>
452
+ prec(PREC.ACCESS, choice($._access_property, $._access_index)),
491
453
 
492
- _access: ($) => choice($._access_call, $._access_index, $._access_property),
493
- _access_call: ($) => seq(".", $.method_call),
494
- _access_index: ($) => seq("[", alias($.expression, $.index), "]"),
495
- _access_property: ($) => seq(".", alias($.identifier, $.property)),
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)),
496
470
 
497
471
  method_call: ($) =>
498
- seq(field("name", $.identifier), field("arguments", $.arguments)),
472
+ prec(PREC.CALL, seq(field("name", $.identifier), field("arguments", $.arguments))),
499
473
 
500
474
  arguments: ($) => seq("(", sepBy(",", $.expression), ")"),
501
475
 
502
476
  // Primitive
503
- ...Keywords,
504
- ...Operations,
477
+ ...buildKeywords(),
505
478
  ...Preprocessor,
506
479
 
507
480
  _const_value: ($) =>
@@ -542,10 +515,6 @@ module.exports = grammar({
542
515
  identifier: ($) => /[\wа-я_][\wа-я_0-9]*/i,
543
516
 
544
517
  line_comment: ($) => seq("//", /.*/),
545
- _non_special_token: ($) =>
546
- choice(
547
- prec.right(repeat1(choice(...TOKEN_TREE_NON_SPECIAL_PUNCTUATION)))
548
- ),
549
518
  },
550
519
  });
551
520
 
@@ -588,11 +557,3 @@ function sepBy(sep, rule) {
588
557
  function sepBy1(sep, rule) {
589
558
  return seq(rule, repeat(seq(sep, rule)));
590
559
  }
591
-
592
- function keyword(...words) {
593
- return token(choice(...words.map(caseInsensitive)));
594
- }
595
-
596
- function caseInsensitive(word) {
597
- return new RegExp(word, "i");
598
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-sitter-bsl",
3
- "version": "0.1.2",
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",