1
/* Описание грамматики базового языка сценариев SIMODO
7
Copyright (c) 2021-2024 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
9
https://bmstu.codes/lsx/simodo/stars
14
include "include/expression";
15
include "include/json5-array";
16
include "include/json5-object";
17
include "include/declarations-definitions";
20
lex.setNewLineSubstitution(";");
24
= список_операторов { ast.addNode(ast.sbl.host, ast.sbl.op.CheckState, 0); }
25
= список_операторов ";" { ast.addNode(ast.sbl.host, ast.sbl.op.CheckState, 0); }
28
/* Дополняем выражение структурами данных, расширяющие грамматику выражений
29
******************************************************************************/
35
элемент_списка_выражений
36
= определение_безымянной_функции
39
правая_часть_присваивания
40
= определение_безымянной_функции
41
= "&" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.Reference, 0); }
44
значение_элемента_объекта
45
= определение_безымянной_функции
49
= определение_безымянной_функции
52
разделитель_элемента_объекта
56
/* Дополняем единицы измерения для базовых констант
57
******************************************************************************/
59
/// \note Просто наименование е.и. без скобок конфликтует с объявлением типа на
61
/// \todo Нужно перенести разбор е.и. в лексику! Но для этого нужно будет дорабатывать библиотеку лексики.
62
// = базовая_константа название_единицы_измерения
64
= базовая_константа "(" единица_измерения ")"
68
= название_единицы_измерения >
69
= название_единицы_измерения знак_отношения единица_измерения
71
название_единицы_измерения
72
= ID { ast.addNode(ast.sbl.host, ast.sbl1.op.MeasureUnit, 0); }
75
= "*" { ast.addNode(ast.sbl.host, ast.sbl1.op.MeasureRatio, 0); }
76
= "/" { ast.addNode(ast.sbl.host, ast.sbl1.op.MeasureRatio, 0); }
79
/* Начальные определения операторов
80
******************************************************************************/
83
= список_операторов ";" оператор
91
/* Оператор вывода на консоль
92
******************************************************************************/
94
= оператор_вывода_на_консоль
97
оператор_вывода_на_консоль
98
= "print" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.Print, 0); }
99
= "print" "all" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.Print, 1); }
102
/* Оператор объявления переменной/типа
103
******************************************************************************/
105
= объявления_и_определения { ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0); }
108
/* Определение безымянной функций
109
******************************************************************************/
111
определение_безымянной_функции
112
= начало_объявления_функции часть_объявления_функции тело_функции
115
ast.addNode(ast.sbl.host, ast.sbl.op.FunctionDefinitionEnd, 2);
117
= начало_объявления_функции перечень_замыканий часть_объявления_функции тело_функции
120
ast.addNode(ast.sbl.host, ast.sbl.op.FunctionDefinitionEnd, 3);
124
начало_объявления_функции
125
= ключевое_слово_для_функции{ ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FunctionDefinition, 0); }
128
ключевое_слово_для_функции
134
= начало_перечня_замыканий список_замыканий "]"
136
= начало_перечня_замыканий "]"
139
начало_перечня_замыканий
140
= "[" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Closure, 0); }
144
= список_замыканий "," замыкание
147
= адрес_переменной_в_замыкании
151
адрес_переменной_в_замыкании
152
= ID { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Closure_Id, 0); }
153
= "*" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Closure_Id, 0); }
156
часть_объявления_функции
157
= определение_аргументов возвращаемый_тип
158
= определение_аргументов
161
определение_аргументов
162
= начало_определения_аргументов список_аргументов ")"
167
начало_определения_аргументов
169
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Params, 0);
174
= определение_аргумента
175
= список_аргументов разделитель_списка_аргументов определение_аргумента
178
разделитель_списка_аргументов
183
/// \note Пока выключил безымянные параметры
184
// = перечень_контрактов ":" {
185
// ast.addNode(ast.sbl.host, ast.sbl1.op.Function_Parameter_Id, 0);
186
// ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0);
188
= перечень_контрактов ":" объявление_переменной
189
{ ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0); }
193
= начало_возвращаемых_типов описание_возвращаемого_типа
197
начало_возвращаемых_типов
198
= "->" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Return_Type, 0); }
201
описание_возвращаемого_типа
202
= перечень_контрактов
206
= начало_тела_функции список_операторов "}"
207
{ ast.addNode(ast.sbl.host, ast.op.None, 2); ast.goParent(); }
208
= начало_тела_функции "}"
209
{ ast.addNode(ast.sbl.host, ast.op.None, 1); ast.goParent(); }
212
= "{" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Body, 0); }
215
/* Определение для простой функции (без контрактов)
216
******************************************************************************/
219
= определение_простой_функции
222
определение_простой_функции
223
= начало_определения_простой_функции завершение_определения_простой_функции
226
ast.addNode(ast.sbl.host, ast.sbl.op.FunctionDefinitionEnd, 1);
228
ast.addNode(ast.sbl.host, ast.sbl.op.PostInitialize, 1);
229
ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 1);
230
ast.addNode(ast.sbl.host, ast.sbl.op.FunctionTethered, 1);
234
начало_определения_простой_функции
235
= ключевое_слово_для_функции ID
237
ast.addNode(ast.sbl.host, ast.sbl.op.AutoDeclaration, 1);
238
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Initialize, 0);
239
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FunctionDefinition, 0);
243
завершение_определения_простой_функции
244
= часть_объявления_функции тело_функции
247
/* Оператор вызова процедуры
248
******************************************************************************/
253
/// \note В данной концепции необходимо начинать оператор с ключевого слова, иначе конфликтует с объявлением переменной
254
= адрес // Вызов процедуры с ожиданием её завершения
255
{ ast.addNode(ast.sbl.host, ast.sbl.op.ProcedureCheck, 0); }
256
= "call" адрес // Вызов процедуры с ожиданием её завершения
257
{ ast.addNode(ast.sbl.host, ast.sbl.op.ProcedureCheck, 1); }
260
/* Оператор присваивания
261
******************************************************************************/
263
= оператор_присваивания
265
оператор_присваивания
266
= адрес знак_присваивания правая_часть_присваивания
268
= адрес знак_присваивания_с_итерацией правая_часть_присваивания
272
= "=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Assignment, 0); }
274
знак_присваивания_с_итерацией
275
= "+=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentAddition, 0); }
276
= "-=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentSubtraction, 0); }
277
= "*=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentMultiplication, 0); }
278
= "/=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentDivision, 0); }
279
= "%=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentModulo, 0); }
283
******************************************************************************/
288
= условие_if оператор_выполнения >
289
{ ast.goParent(); ast.goParent(); }
290
= условие_if оператор_выполнения условие_else
291
{ ast.goParent(); ast.goParent(); }
295
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.If, 0);
296
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.If_True_Body, 0);
300
= слово_else оператор_выполнения
305
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.If_Else_Body, 0);
310
******************************************************************************/
316
= начало_цикла_for объявление_переменной_цикла_for источник_итераций_for оператор_выполнения
317
{ ast.goParent(); ast.goParent(); }
322
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.For, 0);
323
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.For_Variable, 0);
327
объявление_переменной_цикла_for
328
= перечень_контрактов ":" объявление_переменной
330
ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0);
336
= начало_определения_источника_for выражение
339
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Cycle_Body, 0);
343
начало_определения_источника_for
344
= "in" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.For_Source, 0); }
347
/* Оператор цикла while
348
******************************************************************************/
353
= слово_while условие_while оператор_выполнения
361
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.While, 0);
362
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.While_Condition, 0);
366
= выражение { ast.goParent(); ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Cycle_Body, 0); }
369
/* Оператор цикла do-while
370
******************************************************************************/
375
= слово_do оператор_DoWhile "while" выражение
376
{ ast.goParent(); ast.goParent(); }
380
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.DoWhile, 0);
381
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Cycle_Body, 0);
385
= оператор_выполнения
386
{ ast.goParent(); ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.While_Condition, 0); }
389
/* Оператор управления
390
******************************************************************************/
392
= оператор_управления
395
= "break" { ast.addNode(ast.sbl.host, ast.sbl.op.Break, 0); }
396
= "continue" { ast.addNode(ast.sbl.host, ast.sbl.op.Continue, 0); }
400
******************************************************************************/
405
= "return" { ast.addNode(ast.sbl.host, ast.sbl.op.Return, 0); }
406
= "return" правая_часть_присваивания
407
{ ast.addNode(ast.sbl.host, ast.sbl.op.ReturnExpression, 0); }
411
******************************************************************************/
416
= начало_блока_операторов список_операторов "}"
417
{ ast.addNode(ast.sbl.host, ast.sbl.op.None, 2); ast.goParent(); }
418
= начало_блока_операторов "}"
419
{ ast.addNode(ast.sbl.host, ast.sbl.op.None, 1); ast.goParent(); }
421
начало_блока_операторов
422
= "{" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Block, 0); }
425
/* Оператор объявления зоны видимости для контракта
426
******************************************************************************/
428
= объявление_глобальной_зоны_видимости
431
объявление_глобальной_зоны_видимости
432
= начало_объявления_глобальной_зоны_видимости список_имён_контрактов
436
начало_объявления_глобальной_зоны_видимости
437
= "common" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Apply, 0); }
440
список_имён_контрактов
442
= список_имён_контрактов "," имя_контракта
446
= ID { ast.addNode(ast.sbl.host, ast.sbl.op.None, 0); }
449
/* Оператор объявления зоны подстановки объекта
450
******************************************************************************/
452
= определение_зоны_подстановки
455
определение_зоны_подстановки
456
= начало_определения_зоны_подстановки блок_операторов
460
начало_определения_зоны_подстановки
461
= "using" адрес { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Using, 0); }
464
///////////////////////////////////////////////////////////////////////////////
465
// Многопоточность с использованием языковых конструкций
466
/// \todo Нужно будет реализовать с использованием модуля loom и контрактов
467
///////////////////////////////////////////////////////////////////////////////
469
/* Объявление нити, запуск потока и получение состояния
470
******************************************************************************/
475
= передача_состояния_нити
476
= получение_состояния_нити
477
/// \todo Закрытие нити добавляет сложности в реализацию согласованности, кроме того,
478
/// эту операцию сложно контролировать при анализе. Поэтому не реализуем пока.
483
= начало_объявления_нити адрес
486
/// \note Ключевое слово fiber было бы логичнее, но мы его резервируем для одноимённого контракта
487
начало_объявления_нити
488
= "make" "fiber" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberMake, 0); }
489
= "fiber" "make" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberMake, 0); }
492
= начало_запуска_потока_нити адрес
495
начало_запуска_потока_нити
496
= "flow" "fiber" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberFlow, 0); }
497
= "fiber" "flow" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberFlow, 0); }
498
= "flow" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberFlow, 0); }
501
= начало_ожидания_нити адрес{ ast.goParent(); }
504
= "wait" "fiber" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberWait, 0); }
505
= "fiber" "wait" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberWait, 0); }
506
= "wait" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberWait, 0); }
508
передача_состояния_нити
509
= начало_передачи_состояния_нити адрес
512
начало_передачи_состояния_нити
513
= "push" "fiber" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberPush, 0); }
514
= "fiber" "push" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberPush, 0); }
515
= "push" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberPush, 0); }
517
получение_состояния_нити
518
= начало_получения_состояния_нити адрес
521
начало_получения_состояния_нити
522
= "pull" "fiber" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberPull, 0); }
523
= "fiber" "pull" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberPull, 0); }
524
= "pull" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberPull, 0); }
527
// = начало_закрытия_нити адрес
528
// { ast.goParent(); }
530
// начало_закрытия_нити
531
// = "cut" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberCut, 0); }
534
/* Оператор вывода на консоль
535
******************************************************************************/
537
= оператор_добавления_среза
538
= оператор_срезания_среза
541
оператор_добавления_среза
542
= адрес "++" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.ArrayPush, 0); }
544
оператор_срезания_среза
545
= адрес "--" { ast.addNode(ast.sbl.host, ast.sbl.op.ArrayPop, 0); }