loom

Форк
0
/
s-script.fuze 
546 строк · 25.5 Кб
1
/*  Описание грамматики базового языка сценариев SIMODO
2

3
    SIMODO Base Language.
4

5
    MIT License
6

7
    Copyright (c) 2021-2024 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
8

9
    https://bmstu.codes/lsx/simodo/stars
10
*/
11

12
main программа;
13

14
include "include/expression";
15
include "include/json5-array";
16
include "include/json5-object"; 
17
include "include/declarations-definitions"; 
18

19
lex {
20
    lex.setNewLineSubstitution(";");
21
}
22

23
программа
24
    = список_операторов         { ast.addNode(ast.sbl.host, ast.sbl.op.CheckState, 0); }
25
    = список_операторов ";"     { ast.addNode(ast.sbl.host, ast.sbl.op.CheckState, 0); }
26
    ;
27

28
/*  Дополняем выражение структурами данных, расширяющие грамматику выражений
29
******************************************************************************/
30
выражение
31
    = структура_массива
32
    = структура_объекта
33
    ;
34

35
элемент_списка_выражений 
36
    = определение_безымянной_функции
37
    ;
38

39
правая_часть_присваивания
40
    = определение_безымянной_функции
41
    = "&" выражение             { ast.addNode(ast.sbl.host, ast.sbl.op.Reference, 0); }
42
    ;
43
    
44
значение_элемента_объекта
45
    = определение_безымянной_функции
46
    ;
47

48
элемент_массива
49
    = определение_безымянной_функции
50
    ;
51

52
разделитель_элемента_объекта
53
    = "="
54
    ;
55
    
56
/*  Дополняем единицы измерения для базовых констант
57
******************************************************************************/
58
величина
59
/// \note Просто наименование е.и. без скобок конфликтует с объявлением типа на
60
/// следующей строке
61
/// \todo Нужно перенести разбор е.и. в лексику! Но для этого нужно будет дорабатывать библиотеку лексики.
62
//    = базовая_константа название_единицы_измерения
63
//                                { ast.goParent(); }
64
    = базовая_константа "(" единица_измерения ")" 
65
                                { ast.goParent(); }
66
    ;
67
    единица_измерения 
68
        = название_единицы_измерения >
69
        = название_единицы_измерения знак_отношения единица_измерения
70
        ;
71
        название_единицы_измерения
72
            = ID                { ast.addNode(ast.sbl.host, ast.sbl1.op.MeasureUnit, 0); }
73
            ;
74
        знак_отношения
75
            = "*"               { ast.addNode(ast.sbl.host, ast.sbl1.op.MeasureRatio, 0); }
76
            = "/"               { ast.addNode(ast.sbl.host, ast.sbl1.op.MeasureRatio, 0); }
77
            ;
78
    
79
/*  Начальные определения операторов
80
******************************************************************************/
81
список_операторов
82
    = оператор
83
    = список_операторов ";" оператор
84
    ;
85

86
оператор
87
    = оператор_описания
88
    = оператор_выполнения
89
    ;
90
    
91
/*  Оператор вывода на консоль
92
******************************************************************************/
93
оператор_выполнения
94
    = оператор_вывода_на_консоль
95
    ;
96

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); }
100
    ;
101

102
/*  Оператор объявления переменной/типа
103
******************************************************************************/
104
оператор_описания
105
    = объявления_и_определения  { ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0); }
106
    ;
107

108
/*  Определение безымянной функций
109
******************************************************************************/
110

111
определение_безымянной_функции
112
    = начало_объявления_функции часть_объявления_функции тело_функции
113
                                { 
114
                                    ast.goParent(); 
115
                                    ast.addNode(ast.sbl.host, ast.sbl.op.FunctionDefinitionEnd, 2);
116
                                }
117
    = начало_объявления_функции перечень_замыканий часть_объявления_функции тело_функции
118
                                { 
119
                                    ast.goParent(); 
120
                                    ast.addNode(ast.sbl.host, ast.sbl.op.FunctionDefinitionEnd, 3);
121
                                }
122
    ;
123
    
124
начало_объявления_функции
125
    = ключевое_слово_для_функции{ ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FunctionDefinition, 0); }
126
    ;
127

128
ключевое_слово_для_функции
129
    = "function"                
130
    = "fn"                      
131
    ;
132

133
перечень_замыканий
134
    = начало_перечня_замыканий список_замыканий "]"
135
                                { ast.goParent(); }
136
    = начало_перечня_замыканий "]"
137
                                { ast.goParent(); }
138
    ;
139
    начало_перечня_замыканий
140
        = "["                   { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Closure, 0); }
141
        ;
142
    список_замыканий
143
        = замыкание
144
        = список_замыканий "," замыкание
145
        ;
146
        замыкание
147
            = адрес_переменной_в_замыкании
148
                                { ast.goParent(); }
149
            ;
150

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); }
154
    ;
155

156
часть_объявления_функции
157
    = определение_аргументов возвращаемый_тип
158
    = определение_аргументов
159
    ;
160

161
определение_аргументов
162
    = начало_определения_аргументов список_аргументов ")"
163
                                { ast.goParent(); }
164
    = "(" ")"
165
    ;
166

167
начало_определения_аргументов
168
    = "("                       {
169
                                    ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Params, 0);
170
                                }
171
    ;
172

173
список_аргументов
174
    = определение_аргумента
175
    = список_аргументов разделитель_списка_аргументов определение_аргумента
176
    ;
177

178
разделитель_списка_аргументов
179
    = ","
180
    ;
181

182
определение_аргумента
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);
187
//
188
    = перечень_контрактов ":" объявление_переменной
189
                                { ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0); }
190
    ;
191

192
возвращаемый_тип
193
    = начало_возвращаемых_типов описание_возвращаемого_типа 
194
                                { ast.goParent(); }
195
    ;
196

197
начало_возвращаемых_типов
198
    = "->"                      { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Return_Type, 0); }
199
    ;
200

201
описание_возвращаемого_типа
202
    = перечень_контрактов 
203
    ;
204

205
тело_функции
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(); }
210
    ;
211
    начало_тела_функции
212
        = "{"                   { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Function_Body, 0); }
213
        ;
214

215
/*  Определение для простой функции (без контрактов)
216
******************************************************************************/
217

218
оператор_описания
219
    = определение_простой_функции
220
    ;
221
    
222
определение_простой_функции
223
    = начало_определения_простой_функции завершение_определения_простой_функции
224
                                { 
225
                                    ast.goParent(); 
226
                                    ast.addNode(ast.sbl.host, ast.sbl.op.FunctionDefinitionEnd, 1);
227
                                    ast.goParent(); 
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);
231
                                }
232
    ;
233

234
начало_определения_простой_функции
235
    = ключевое_слово_для_функции ID
236
                                { 
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);
240
                                }
241
    ;
242
    
243
завершение_определения_простой_функции
244
    = часть_объявления_функции тело_функции
245
    ;
246
    
247
/*  Оператор вызова процедуры
248
******************************************************************************/
249
оператор_выполнения
250
    = вызов_процедуры
251
    ;
252
    вызов_процедуры
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); }
258
        ;
259
        
260
/*  Оператор присваивания
261
******************************************************************************/
262
оператор_выполнения
263
    = оператор_присваивания
264
    ;
265
    оператор_присваивания
266
        = адрес знак_присваивания правая_часть_присваивания
267
                                { ast.goParent(); }
268
        = адрес знак_присваивания_с_итерацией правая_часть_присваивания
269
                                { ast.goParent(); }
270
        ;
271
    знак_присваивания
272
        = "="                   { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Assignment, 0); }
273
        ;
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); }
280
        ;
281

282
/*  Условный оператор
283
******************************************************************************/
284
оператор_выполнения
285
    = условный_оператор
286
    ;
287
    условный_оператор
288
        = условие_if оператор_выполнения >
289
                                { ast.goParent(); ast.goParent(); }
290
        = условие_if оператор_выполнения условие_else
291
                                { ast.goParent(); ast.goParent(); }
292
        ;
293
        условие_if
294
            = "if" выражение    {
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);
297
                                }
298
            ;
299
        условие_else
300
            = слово_else оператор_выполнения
301
            ;
302
            слово_else
303
                = "else"        { 
304
                                    ast.goParent(); 
305
                                    ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.If_Else_Body, 0); 
306
                                }
307
                ;
308

309
/*  Оператор цикла for
310
******************************************************************************/
311
оператор_выполнения
312
    = цикл_for
313
    ;
314

315
цикл_for
316
    = начало_цикла_for объявление_переменной_цикла_for источник_итераций_for оператор_выполнения
317
                                { ast.goParent(); ast.goParent(); }
318
    ;
319
    
320
начало_цикла_for
321
    = "for"                     { 
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);
324
                                }
325
    ;
326
    
327
объявление_переменной_цикла_for
328
    = перечень_контрактов ":" объявление_переменной
329
                                {
330
                                    ast.addNode(ast.sbl.host, ast.sbl.op.Announcements_Completed, 0);
331
                                    ast.goParent(); 
332
                                }
333
    ;
334
    
335
источник_итераций_for
336
    = начало_определения_источника_for выражение
337
                                { 
338
                                    ast.goParent(); 
339
                                    ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Cycle_Body, 0);
340
                                }
341
    ;
342
    
343
начало_определения_источника_for
344
    = "in"                      { ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.For_Source, 0); }
345
    ;
346

347
/*  Оператор цикла while
348
******************************************************************************/
349
оператор_выполнения
350
    = цикл_while
351
    ;
352
    цикл_while
353
        = слово_while условие_while оператор_выполнения
354
                                {
355
                                    ast.goParent();
356
                                    ast.goParent();
357
                                }
358
        ;
359
        слово_while
360
            = "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);
363
                                }
364
            ;
365
        условие_while
366
            = выражение         { ast.goParent(); ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.Cycle_Body, 0); }
367
            ;
368

369
/*  Оператор цикла do-while
370
******************************************************************************/
371
оператор_выполнения
372
    = цикл_do_while
373
    ;
374
    цикл_do_while
375
        = слово_do оператор_DoWhile "while" выражение
376
                                { ast.goParent(); ast.goParent(); }
377
        ;
378
        слово_do
379
            = "do"              {
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);
382
                                }
383
            ;
384
        оператор_DoWhile
385
            = оператор_выполнения
386
                                { ast.goParent(); ast.addNode_StepInto(ast.sbl.host, ast.sbl1.op.While_Condition, 0); }
387
            ;
388

389
/*  Оператор управления
390
******************************************************************************/
391
оператор_выполнения
392
    = оператор_управления
393
    ;
394
    оператор_управления
395
        = "break"               { ast.addNode(ast.sbl.host, ast.sbl.op.Break, 0); }
396
        = "continue"            { ast.addNode(ast.sbl.host, ast.sbl.op.Continue, 0); }
397
        ;
398

399
/*  Оператор возврата
400
******************************************************************************/
401
оператор_выполнения
402
    = оператор_return
403
    ;
404
    оператор_return
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); }
408
        ;
409

410
/*  Блок операторов
411
******************************************************************************/
412
оператор_выполнения
413
    = блок_операторов
414
    ;
415
    блок_операторов
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(); }
420
        ;
421
        начало_блока_операторов
422
            = "{"               { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Block, 0); }
423
            ;
424

425
/*  Оператор объявления зоны видимости для контракта
426
******************************************************************************/
427
оператор_описания
428
    = объявление_глобальной_зоны_видимости
429
    ;
430

431
объявление_глобальной_зоны_видимости
432
    = начало_объявления_глобальной_зоны_видимости список_имён_контрактов
433
                                { ast.goParent(); }
434
    ;
435

436
начало_объявления_глобальной_зоны_видимости
437
    = "common"                  { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Apply, 0); }
438
    ;
439

440
список_имён_контрактов
441
    = имя_контракта
442
    = список_имён_контрактов "," имя_контракта
443
    ;
444
    
445
имя_контракта
446
    = ID                        { ast.addNode(ast.sbl.host, ast.sbl.op.None, 0); }
447
    ;
448

449
/*  Оператор объявления зоны подстановки объекта
450
******************************************************************************/
451
оператор_выполнения
452
    = определение_зоны_подстановки
453
    ;
454

455
определение_зоны_подстановки
456
    = начало_определения_зоны_подстановки блок_операторов
457
                                { ast.goParent(); }
458
    ;
459

460
начало_определения_зоны_подстановки
461
    = "using" адрес             { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.Using, 0); }
462
    ;
463

464
///////////////////////////////////////////////////////////////////////////////
465
// Многопоточность с использованием языковых конструкций
466
/// \todo Нужно будет реализовать с использованием модуля loom и контрактов
467
///////////////////////////////////////////////////////////////////////////////
468

469
/*  Объявление нити, запуск потока и получение состояния
470
******************************************************************************/
471
оператор_выполнения
472
    = объявление_нити
473
    = запуск_потока_нити
474
    = ожидание_нити
475
    = передача_состояния_нити
476
    = получение_состояния_нити
477
/// \todo Закрытие нити добавляет сложности в реализацию согласованности, кроме того, 
478
/// эту операцию сложно контролировать при анализе. Поэтому не реализуем пока.
479
//    = закрытие_нити
480
    ;
481

482
    объявление_нити
483
        = начало_объявления_нити адрес
484
                                    { ast.goParent(); }
485
        ;
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); }
490
            ;
491
    запуск_потока_нити
492
        = начало_запуска_потока_нити адрес
493
                                    { ast.goParent(); }
494
        ;
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); }
499
            ;
500
    ожидание_нити
501
        = начало_ожидания_нити адрес{ ast.goParent(); }
502
        ;
503
        начало_ожидания_нити
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); }
507
            ;
508
    передача_состояния_нити
509
        = начало_передачи_состояния_нити адрес
510
                                    { ast.goParent(); }
511
        ;
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); }
516
            ;
517
    получение_состояния_нити
518
        = начало_получения_состояния_нити адрес
519
                                    { ast.goParent(); }
520
        ;
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); }
525
            ;
526
//    закрытие_нити
527
//        = начало_закрытия_нити адрес
528
//                                    { ast.goParent(); }
529
//        ;
530
//        начало_закрытия_нити
531
//            = "cut"                 { ast.addNode_StepInto(ast.sbl.host, ast.sbl.op.FiberCut, 0); }
532
//            ;
533
        
534
/*  Оператор вывода на консоль
535
******************************************************************************/
536
оператор_выполнения
537
    = оператор_добавления_среза
538
    = оператор_срезания_среза
539
    ;
540

541
оператор_добавления_среза
542
    = адрес "++" выражение         { ast.addNode(ast.sbl.host, ast.sbl.op.ArrayPush, 0); }
543
    ;
544
оператор_срезания_среза
545
    = адрес "--"                   { ast.addNode(ast.sbl.host, ast.sbl.op.ArrayPop, 0); }
546
    ;
547

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.