tree-sitter-bsl 0.1.2 → 0.1.4

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,120 @@
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
- };
98
+ kw["NULL_KEYWORD"] = ($) => token(/null/i);
99
+ return kw;
100
+ }
121
101
 
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
- };
102
+ function reservedKeywords($) {
103
+ return Object.keys(buildKeywords()).map((k) => $[k]);
104
+ }
134
105
 
135
106
  const Preprocessor = {
136
107
  preprocessor: ($) => {
137
108
  const region = [
138
- seq($.PREPROC_REGION_START_KEYWORD, $.identifier),
139
- $.PREPROC_REGION_END_KEYWORD,
109
+ seq($.PREPROC_REGION_KEYWORD, $.identifier),
110
+ $.PREPROC_ENDREGION_KEYWORD,
140
111
  ];
141
112
 
142
113
  const preproc_if = [
143
114
  seq($.PREPROC_IF_KEYWORD, $.expression, $.THEN_KEYWORD),
144
- seq($.PREPROC_ELSE_IF_KEYWORD, $.expression, $.THEN_KEYWORD),
115
+ seq($.PREPROC_ELSIF_KEYWORD, $.expression, $.THEN_KEYWORD),
145
116
  $.PREPROC_ELSE_KEYWORD,
146
- $.PREPROC_END_IF_KEYWORD,
117
+ $.PREPROC_ENDIF_KEYWORD,
147
118
  ];
148
119
 
149
120
  const preproc_change = [
@@ -213,6 +184,9 @@ module.exports = grammar({
213
184
 
214
185
  word: ($) => $.identifier,
215
186
 
187
+ reserved: {
188
+ global: ($) => reservedKeywords($),
189
+ },
216
190
  rules: {
217
191
  source_file: ($) => repeat($._definition),
218
192
 
@@ -232,7 +206,7 @@ module.exports = grammar({
232
206
  field("parameters", $.parameters),
233
207
  optional(field("export", $.EXPORT_KEYWORD)),
234
208
  repeat($.statement),
235
- $.END_PROCEDURE_KEYWORD
209
+ $.ENDPROCEDURE_KEYWORD
236
210
  ),
237
211
 
238
212
  function_definition: ($) =>
@@ -243,7 +217,7 @@ module.exports = grammar({
243
217
  field("parameters", $.parameters),
244
218
  optional(field("export", $.EXPORT_KEYWORD)),
245
219
  repeat($.statement),
246
- $.END_FUNCTION_KEYWORD
220
+ $.ENDFUNCTION_KEYWORD
247
221
  ),
248
222
 
249
223
  var_definition: ($) =>
@@ -256,8 +230,7 @@ module.exports = grammar({
256
230
  optional(";")
257
231
  )
258
232
  ),
259
- parameters: ($) =>
260
- seq("(", sepBy(",", field("parameter", $.parameter)), ")"),
233
+ parameters: ($) => seq("(", commaSep(field("parameter", $.parameter)), ")"),
261
234
 
262
235
  parameter: ($) =>
263
236
  seq(
@@ -292,7 +265,8 @@ module.exports = grammar({
292
265
  $.await_statement
293
266
  ),
294
267
 
295
- call_statement: ($) => seq($.call_expression, optional(";")),
268
+ call_statement: ($) =>
269
+ seq(choice($.method_call, $.call_expression), optional(";")),
296
270
 
297
271
  assignment_statement: ($) =>
298
272
  seq(
@@ -311,7 +285,7 @@ module.exports = grammar({
311
285
  repeat($.statement),
312
286
  $.EXCEPT_KEYWORD,
313
287
  repeat($.statement),
314
- $.END_TRY_KEYWORD,
288
+ $.ENDTRY_KEYWORD,
315
289
  optional(";")
316
290
  ),
317
291
 
@@ -331,23 +305,16 @@ module.exports = grammar({
331
305
  $.expression,
332
306
  $.THEN_KEYWORD,
333
307
  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,
308
+ repeat($.elseif_clause),
309
+ optional($.else_clause),
310
+ $.ENDIF_KEYWORD,
344
311
  optional(";")
345
312
  ),
346
313
 
347
- else_if: ($) =>
348
- seq($.ELSE_IF_KEYWORD, $.expression, $.THEN_KEYWORD, repeat($.statement)),
314
+ elseif_clause: ($) =>
315
+ seq($.ELSIF_KEYWORD, $.expression, $.THEN_KEYWORD, repeat($.statement)),
349
316
 
350
- else: ($) => seq($.ELSE_KEYWORD, repeat($.statement)),
317
+ else_clause: ($) => seq($.ELSE_KEYWORD, repeat($.statement)),
351
318
 
352
319
  while_statement: ($) =>
353
320
  seq(
@@ -355,18 +322,20 @@ module.exports = grammar({
355
322
  $.expression,
356
323
  $.DO_KEYWORD,
357
324
  repeat($.statement),
358
- $.END_DO_KEYWORD
325
+ $.ENDDO_KEYWORD
359
326
  ),
360
327
 
361
328
  for_statement: ($) =>
362
329
  seq(
363
330
  $.FOR_KEYWORD,
364
- $.assignment_statement,
331
+ $.identifier,
332
+ "=",
333
+ $.expression,
365
334
  $.TO_KEYWORD,
366
335
  $.expression,
367
336
  $.DO_KEYWORD,
368
337
  repeat($.statement),
369
- $.END_DO_KEYWORD,
338
+ $.ENDDO_KEYWORD,
370
339
  optional(";")
371
340
  ),
372
341
 
@@ -379,9 +348,10 @@ module.exports = grammar({
379
348
  $.expression,
380
349
  $.DO_KEYWORD,
381
350
  repeat($.statement),
382
- $.END_DO_KEYWORD,
351
+ $.ENDDO_KEYWORD,
383
352
  optional(";")
384
353
  ),
354
+
385
355
  continue_statement: ($) => seq($.CONTINUE_KEYWORD, optional(";")),
386
356
 
387
357
  break_statement: ($) => seq($.BREAK_KEYWORD, optional(";")),
@@ -395,17 +365,11 @@ module.exports = grammar({
395
365
  label_statement: ($) => seq("~", $.identifier, ":", optional(";")),
396
366
 
397
367
  add_handler_statement: ($) =>
398
- seq(
399
- $.ADD_HANDLER_KEYWORD,
400
- $.expression,
401
- ",",
402
- $.expression,
403
- optional(";")
404
- ),
368
+ seq($.ADDHANDLER_KEYWORD, $.expression, ",", $.expression, optional(";")),
405
369
 
406
370
  remove_handler_statement: ($) =>
407
371
  seq(
408
- $.REMOVE_HANDLER_KEYWORD,
372
+ $.REMOVEHANDLER_KEYWORD,
409
373
  $.expression,
410
374
  ",",
411
375
  $.expression,
@@ -422,26 +386,43 @@ module.exports = grammar({
422
386
  $.binary_expression,
423
387
  $.ternary_expression,
424
388
  $.new_expression,
389
+ $.method_call,
425
390
  $.call_expression,
426
391
  $.property_access,
427
392
  $.await_expression
428
393
  ),
394
+
429
395
  unary_expression: ($) =>
430
396
  prec.left(
397
+ PREC.UNARY,
431
398
  seq(
432
- field("operator", alias(choice("-", "+", $.NOT_KEYWORD), $.operation)),
399
+ field("operator", alias(choice("-", "+", $.NOT_KEYWORD), $.operator)),
433
400
  field("argument", $.expression)
434
401
  )
435
402
  ),
436
403
 
437
- binary_expression: ($) =>
438
- prec.left(
439
- seq(
440
- field("left", $.expression),
441
- field("operator", $.operation),
442
- field("right", $.expression)
443
- )
444
- ),
404
+ binary_expression: ($) => {
405
+ const operations = [
406
+ [PREC.LOGICAL_AND, $.AND_KEYWORD],
407
+ [PREC.LOGICAL_OR, $.OR_KEYWORD],
408
+ [PREC.COMPARISON, choice("<>", "=", ">", "<", ">=", "<=")],
409
+ [PREC.ADDITIVE, choice("+", "-")],
410
+ [PREC.MULTIPLICATIVE, choice("*", "/", "%")],
411
+ ];
412
+
413
+ return choice(
414
+ ...operations.map(([priority, operator]) => {
415
+ return prec.left(
416
+ priority,
417
+ seq(
418
+ field("left", $.expression),
419
+ field("operator", alias(operator, $.operator)),
420
+ field("right", $.expression)
421
+ )
422
+ );
423
+ })
424
+ );
425
+ },
445
426
 
446
427
  ternary_expression: ($) =>
447
428
  prec.right(
@@ -457,51 +438,54 @@ module.exports = grammar({
457
438
  ),
458
439
 
459
440
  new_expression: ($) =>
460
- choice(
461
- prec.right(
462
- 0,
441
+ prec(
442
+ PREC.NEW,
443
+ choice(
463
444
  seq(
464
445
  $.NEW_KEYWORD,
465
446
  field("type", $.identifier),
466
447
  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)
448
+ ),
449
+ seq($.NEW_KEYWORD, field("arguments", $.arguments))
479
450
  )
480
451
  ),
481
452
 
482
- await_expression: ($) => prec(1, seq($.AWAIT_KEYWORD, $.expression)),
453
+ call_expression: ($) => prec(PREC.CALL - 1, $._access_call),
483
454
 
484
- _assignment_member: ($) =>
485
- choice(
486
- $.identifier,
487
- $.property_access
488
- ),
455
+ await_expression: ($) =>
456
+ prec(PREC.AWAIT, seq($.AWAIT_KEYWORD, $.expression)),
489
457
 
490
- property_access: ($) => seq(choice($.identifier, $.method_call), repeat1($._access)),
458
+ _assignment_member: ($) => choice($.identifier, $.property_access),
491
459
 
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)),
460
+ property_access: ($) =>
461
+ prec(PREC.ACCESS, choice($._access_property, $._access_index)),
462
+
463
+ access: ($) =>
464
+ prec(
465
+ 1,
466
+ choice(
467
+ $._access_call,
468
+ $._access_index,
469
+ $._access_property,
470
+ $.identifier,
471
+ $.method_call
472
+ )
473
+ ),
474
+ _access_call: ($) => seq($.access, ".", $.method_call),
475
+ _access_index: ($) => seq($.access, "[", alias($.expression, $.index), "]"),
476
+ _access_property: ($) =>
477
+ seq($.access, ".", alias($.identifier, $.property)),
496
478
 
497
479
  method_call: ($) =>
498
- seq(field("name", $.identifier), field("arguments", $.arguments)),
480
+ prec(
481
+ PREC.CALL,
482
+ seq(field("name", $.identifier), field("arguments", $.arguments))
483
+ ),
499
484
 
500
485
  arguments: ($) => seq("(", sepBy(",", $.expression), ")"),
501
486
 
502
487
  // Primitive
503
- ...Keywords,
504
- ...Operations,
488
+ ...buildKeywords(),
505
489
  ...Preprocessor,
506
490
 
507
491
  _const_value: ($) =>
@@ -513,7 +497,6 @@ module.exports = grammar({
513
497
  $.boolean,
514
498
  $.UNDEFINED_KEYWORD,
515
499
  $.NULL_KEYWORD
516
- //TODO Date
517
500
  ),
518
501
 
519
502
  boolean: ($) => choice($.TRUE_KEYWORD, $.FALSE_KEYWORD),
@@ -542,10 +525,6 @@ module.exports = grammar({
542
525
  identifier: ($) => /[\wа-я_][\wа-я_0-9]*/i,
543
526
 
544
527
  line_comment: ($) => seq("//", /.*/),
545
- _non_special_token: ($) =>
546
- choice(
547
- prec.right(repeat1(choice(...TOKEN_TREE_NON_SPECIAL_PUNCTUATION)))
548
- ),
549
528
  },
550
529
  });
551
530
 
@@ -588,11 +567,3 @@ function sepBy(sep, rule) {
588
567
  function sepBy1(sep, rule) {
589
568
  return seq(rule, repeat(seq(sep, rule)));
590
569
  }
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.4",
4
4
  "description": "1C (BSL) language",
5
5
  "repository": "https://github.com/tree-sitter/tree-sitter-bsl",
6
6
  "license": "MIT",