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";
19
lex.setNewLineSubstitution(";");
23
= список_операторов { ast.addNode(ast.sbl.host, ast.sbl.op.CheckState, 0); }
26
/* Дополняем выражение структурами данных, расширяющие грамматику выражений
27
******************************************************************************/
33
элемент_списка_выражений
34
= определение_безымянной_функции
35
= "&" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.Reference, 0); }
38
выражение_или_определение_безымянной_функции
40
= определение_безымянной_функции
41
= "&" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.Reference, 0); }
44
значение_элемента_объекта
45
= определение_безымянной_функции
46
= "&" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.Reference, 0); }
50
= определение_безымянной_функции
51
= "&" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.Reference, 0); }
54
разделитель_элемента_объекта
58
/* Дополняем единицы измерения для базовых констант
59
******************************************************************************/
61
/// \note Просто наименование е.и. без скобок конфликтует с объявлением типа на
63
/// \todo Нужно перенести разбор е.и. в лексику! Но для этого нужно будет дорабатывать библиотеку лексики.
64
// = базовая_константа название_единицы_измерения
66
= базовая_константа "(" единица_измерения ")"
70
= название_единицы_измерения >
71
= название_единицы_измерения знак_отношения единица_измерения
73
название_единицы_измерения
74
= ID { ast.addNode(ast.sbl.host, ast.sbl1.op.MeasureUnit, 0); }
77
= "*" { ast.addNode(ast.sbl.host, ast.sbl1.op.MeasureRatio, 0); }
78
= "/" { ast.addNode(ast.sbl.host, ast.sbl1.op.MeasureRatio, 0); }
81
/* Начальные определения операторов
82
******************************************************************************/
85
= список_операторов ";" оператор
93
/* Оператор вывода на консоль
94
******************************************************************************/
96
= оператор_вывода_на_консоль
99
оператор_вывода_на_консоль
100
= "print" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.Print, 0); }
101
= "print" "all" выражение { ast.addNode(ast.sbl.host, ast.sbl.op.Print, 1); }
104
/* Оператор объявления переменной/типа
105
******************************************************************************/
107
= объявления_и_определения { ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0); }
110
объявления_и_определения
111
= начало_перечня_контрактов определение_контракта
112
= начало_перечня_контрактов определение_типа
113
= начало_перечня_контрактов определение_типа инициализация_переменной
114
= начало_перечня_контрактов определение_типа ":" список_определений_переменных
115
= начало_перечня_контрактов ":" список_определений_переменных
116
= начало_перечня_контрактов перечень_контрактов определение_контракта
117
= начало_перечня_контрактов перечень_контрактов определение_типа
118
= начало_перечня_контрактов перечень_контрактов определение_типа инициализация_переменной
119
= начало_перечня_контрактов перечень_контрактов определение_типа ":" список_определений_переменных
120
= начало_перечня_контрактов перечень_контрактов ":" список_определений_переменных
123
начало_перечня_контрактов
124
= ключевое_слово_начала_перечня_контрактов контракт
125
= импорт { ast.addNode(ast.sbl.host, ast.sbl.op.Announcement, 0); }
126
= "#" структура_объекта { ast.addNode(ast.sbl.host, ast.sbl.op.Announcement, 0); }
129
ключевое_слово_начала_перечня_контрактов
136
= перечень_контрактов контракт
140
= адрес { ast.addNode(ast.sbl.host, ast.sbl.op.Announcement, 0); }
141
= импорт { ast.addNode(ast.sbl.host, ast.sbl.op.Announcement, 0); }
142
= "#" структура_объекта { ast.addNode(ast.sbl.host, ast.sbl.op.Announcement, 0); }
146
= импорт_обязательная_часть >
148
= импорт_обязательная_часть выражение
152
импорт_обязательная_часть
153
= "import" ANNOTATION { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Import, 1); }
154
= "import" ID { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Import, 1); }
158
= "type" ID { ast.addNode(ast.sbl.host, ast.sbl.op.Type, 1); }
162
= "contract" ID { ast.addNode(ast.sbl.host, ast.sbl.op.Contract, 1); }
165
список_определений_переменных
166
= объявление_или_определение_переменной
167
= список_определений_переменных "," объявление_или_определение_переменной
170
объявление_или_определение_переменной
171
= объявление_переменной
172
= объявление_переменной инициализация_переменной
173
/// \todo Определение группы переменных нарушает семантику использования определяемой
174
/// переменной в выражении инициализации. Нужно поправить.
175
= объявление_группы_переменных инициализация_переменной
176
// { ast.addNode(ast.sbl.host, ast.sbl.op.PostInitialize, 0); }
180
= ID { ast.addNode(ast.sbl.host, ast.sbl.op.Declaration, 0); }
183
инициализация_переменной
184
= знак_инициализации выражение_или_определение_безымянной_функции
185
{ ast.goParent(); ast.addNode(ast.sbl.host, ast.sbl.op.PostInitialize, 0); }
189
= "=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Initialize, 0); }
192
/// \note Присвоение группе переменных с префиксом "[" конфликтует с операцией определения
193
/// индекса в массиве, если префикс находится с новой строки, а предыдущая строка
194
/// заканчивается на имя переменной.
195
///* Оператор присвоения для группы переменных
196
//******************************************************************************/
198
// = присвоение_группе_переменных
201
//присвоение_группе_переменных
202
// = объявление_группы_переменных инициализация_переменной_для_группы
203
// { ast.goParent(); ast.goParent(); }
206
объявление_группы_переменных
207
= начало_группы список_объявлений_элементов_группы "]"
213
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.GroupInitialize, 0);
214
// ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.GroupDeclaration, 0);
218
список_объявлений_элементов_группы
219
= объявление_переменной_группы
220
= первый_пропуск объявление_переменной_группы
221
= "," { ast.addNode(ast.sbl.host, ast.sbl.op.Declaration, 0); }
222
= список_объявлений_элементов_группы объявление_переменной_или_пропуск
225
= "," { ast.addNode(ast.sbl.host, ast.sbl.op.Declaration, 0); }
228
объявление_переменной_или_пропуск
229
= "," объявление_переменной_группы
230
= "," { ast.addNode(ast.sbl.host, ast.sbl.op.Declaration, 0); }
233
объявление_переменной_группы
234
= ID { ast.addNode(ast.sbl.host, ast.sbl.op.Declaration, 0); }
237
//инициализация_переменной_для_группы
238
// = начало_инициализация_переменной_для_группы выражение
241
//начало_инициализация_переменной_для_группы
242
// = "=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.GroupDefinition, 0); }
245
/* Определение безымянной функций
246
******************************************************************************/
248
определение_безымянной_функции
249
= начало_объявления_функции часть_объявления_функции тело_функции
252
ast.addNode(ast.sbl.host, ast.sbl.op.FunctionDefinitionEnd, 2);
254
= начало_объявления_функции перечень_замыканий часть_объявления_функции тело_функции
257
ast.addNode(ast.sbl.host, ast.sbl.op.FunctionDefinitionEnd, 3);
261
начало_объявления_функции
262
= ключевое_слово_для_функции{ ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FunctionDefinition, 0); }
265
ключевое_слово_для_функции
271
= начало_перечня_замыканий список_замыканий "]"
273
= начало_перечня_замыканий "]"
276
начало_перечня_замыканий
277
= "[" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Closure, 0); }
281
= список_замыканий "," замыкание
284
= адрес_переменной_в_замыкании
288
адрес_переменной_в_замыкании
289
= ID { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Closure_Id, 0); }
290
= "*" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Closure_Id, 0); }
293
часть_объявления_функции
294
= определение_аргументов возвращаемый_тип
295
= определение_аргументов
298
определение_аргументов
299
= начало_определения_аргументов список_аргументов ")"
304
начало_определения_аргументов
306
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Params, 0);
311
= определение_аргумента
312
= список_аргументов разделитель_списка_аргументов определение_аргумента
315
разделитель_списка_аргументов
320
/// \note Пока выключил безымянные параметры
321
// = перечень_контрактов ":" {
322
// ast.addNode(ast.sbl.host, ast.sbl1.op.Function_Parameter_Id, 0);
323
// ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0);
325
= перечень_контрактов ":" объявление_переменной
326
{ ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0); }
330
= начало_возвращаемых_типов описание_возвращаемого_типа
334
начало_возвращаемых_типов
335
= "->" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Return_Type, 0); }
338
описание_возвращаемого_типа
339
= перечень_контрактов
343
= начало_тела_функции список_операторов "}"
344
{ ast.addNode(ast.sbl.host, ast.op.None, 2); ast.goParent(); }
345
= начало_тела_функции "}"
346
{ ast.addNode(ast.sbl.host, ast.op.None, 1); ast.goParent(); }
349
= "{" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Body, 0); }
352
/* Определение для простой функции (без контрактов)
353
******************************************************************************/
356
= определение_простой_функции
359
определение_простой_функции
360
= начало_определения_простой_функции завершение_определения_простой_функции
363
ast.addNode(ast.sbl.host, ast.sbl.op.FunctionDefinitionEnd, 1);
365
ast.addNode(ast.sbl.host, ast.sbl.op.PostInitialize, 1);
366
ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 1);
367
ast.addNode(ast.sbl.host, ast.sbl.op.FunctionTethered, 1);
371
начало_определения_простой_функции
372
= ключевое_слово_для_функции ID
374
ast.addNode(ast.sbl.host, ast.sbl.op.AutoDeclaration, 1);
375
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Initialize, 0);
376
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FunctionDefinition, 0);
380
завершение_определения_простой_функции
381
= часть_объявления_функции тело_функции
382
// = перечень_замыканий часть_объявления_функции тело_функции
385
/* Оператор вызова процедуры
386
******************************************************************************/
391
/// \note В данной концепции необходимо начинать оператор с ключевого слова, иначе конфликтует с объявлением переменной
392
= адрес // Вызов процедуры с ожиданием её завершения
393
{ ast.addNode(ast.sbl.host, ast.sbl.op.ProcedureCheck, 0); }
394
= "call" адрес // Вызов процедуры с ожиданием её завершения
395
{ ast.addNode(ast.sbl.host, ast.sbl.op.ProcedureCheck, 1); }
398
/* Оператор присваивания
399
******************************************************************************/
401
= оператор_присваивания
403
оператор_присваивания
404
= адрес знак_присваивания выражение_или_определение_безымянной_функции
406
= адрес знак_присваивания_с_итерацией выражение_или_определение_безымянной_функции
410
= "=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Assignment, 0); }
412
знак_присваивания_с_итерацией
413
= "+=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentAddition, 0); }
414
= "-=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentSubtraction, 0); }
415
= "*=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentMultiplication, 0); }
416
= "/=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentDivision, 0); }
417
= "%=" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.AssignmentModulo, 0); }
421
******************************************************************************/
426
= условие_if оператор_выполнения >
427
{ ast.goParent(); ast.goParent(); }
428
= условие_if оператор_выполнения условие_else
429
{ ast.goParent(); ast.goParent(); }
433
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.If, 0);
434
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.If_True_Body, 0);
438
= слово_else оператор_выполнения
443
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.If_Else_Body, 0);
448
******************************************************************************/
454
= начало_цикла_for объявление_переменной_цикла_for источник_итераций_for оператор_выполнения
455
{ ast.goParent(); ast.goParent(); }
460
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.For, 0);
461
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.For_Variable, 0);
465
объявление_переменной_цикла_for
466
= перечень_контрактов ":" объявление_переменной
468
ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0);
474
= начало_определения_источника_for выражение
477
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Cycle_Body, 0);
481
начало_определения_источника_for
482
= "in" { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.For_Source, 0); }
485
/* Оператор цикла while
486
******************************************************************************/
491
= слово_while условие_while оператор_выполнения
499
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.While, 0);
500
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.While_Condition, 0);
504
= выражение { ast.goParent(); ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Cycle_Body, 0); }
507
/* Оператор цикла do-while
508
******************************************************************************/
513
= слово_do оператор_DoWhile "while" выражение
514
{ ast.goParent(); ast.goParent(); }
518
ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.DoWhile, 0);
519
ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Cycle_Body, 0);
523
= оператор_выполнения
524
{ ast.goParent(); ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.While_Condition, 0); }
527
/* Оператор управления
528
******************************************************************************/
530
= оператор_управления
533
= "break" { ast.addNode(ast.sbl.host, ast.sbl.op.Break, 0); }
534
= "continue" { ast.addNode(ast.sbl.host, ast.sbl.op.Continue, 0); }
538
******************************************************************************/
543
= "return" { ast.addNode(ast.sbl.host, ast.sbl.op.Return, 0); }
544
= "return" выражение_или_определение_безымянной_функции
545
{ ast.addNode(ast.sbl.host, ast.sbl.op.ReturnExpression, 0); }
548
// = "return" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Return, 0); }
552
******************************************************************************/
557
= начало_блока_операторов список_операторов "}"
558
{ ast.addNode(ast.sbl.host, ast.sbl.op.None, 2); ast.goParent(); }
559
= начало_блока_операторов "}"
560
{ ast.addNode(ast.sbl.host, ast.sbl.op.None, 1); ast.goParent(); }
562
начало_блока_операторов
563
= "{" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Block, 0); }
566
/* Оператор объявления зоны видимости для контракта
567
******************************************************************************/
569
= объявление_глобальной_зоны_видимости
572
объявление_глобальной_зоны_видимости
573
= начало_объявления_глобальной_зоны_видимости список_имён_контрактов
577
начало_объявления_глобальной_зоны_видимости
578
= "common" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Apply, 0); }
581
список_имён_контрактов
583
= список_имён_контрактов "," имя_контракта
587
= ID { ast.addNode(ast.sbl.host, ast.sbl.op.None, 0); }
591
// = определение_зоны_видимости
594
//определение_зоны_видимости
595
// = начало_определения_зоны_видимости перечень_контрактов_для_определения_зоны_видимости блок_операторов
596
// { ast.goParent(); }
599
//начало_определения_зоны_видимости
600
// = "using" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Using, 0); }
603
//перечень_контрактов_для_определения_зоны_видимости
604
// = список_контрактов { ast.goParent(); }
607
///////////////////////////////////////////////////////////////////////////////
608
// Многопоточность с использованием языковых конструкций
609
/// \todo Нужно будет реализовать с использованием модуля loom и контрактов
610
///////////////////////////////////////////////////////////////////////////////
612
/* Объявление нити, запуск потока и получение состояния
613
******************************************************************************/
618
= передача_состояния_нити
619
= получение_состояния_нити
620
/// \todo Закрытие нити добавляет сложности в реализацию согласованности, кроме того,
621
/// эту операцию сложно контролировать при анализе. Поэтому не реализуем пока.
626
= начало_объявления_нити адрес
629
/// \note Ключевое слово fiber было бы логичнее, но мы его резервируем для одноимённого контракта
630
начало_объявления_нити
631
= "make_fiber" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberMake, 0); }
634
= начало_запуска_потока_нити адрес
637
начало_запуска_потока_нити
638
= "flow" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberFlow, 0); }
641
= начало_ожидания_нити адрес{ ast.goParent(); ast.addNode(ast.sbl.host, ast.sbl.op.Pop, 0); }
644
= "wait" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberWait, 0); }
646
передача_состояния_нити
647
= начало_передачи_состояния_нити адрес
648
{ ast.goParent(); ast.addNode(ast.sbl.host, ast.sbl.op.FiberPush, 0); }
650
начало_передачи_состояния_нити
651
= "push" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberWait, 0); }
653
получение_состояния_нити
654
= начало_получения_состояния_нити адрес
655
{ ast.goParent(); ast.addNode(ast.sbl.host, ast.sbl.op.FiberPull, 0); }
657
начало_получения_состояния_нити
658
= "pull" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberWait, 0); }
661
// = начало_закрытия_нити адрес
662
// { ast.goParent(); }
664
// начало_закрытия_нити
665
// = "cut" { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberCut, 0); }