УСЛОВИЕ -> если МУСОР_МЕЖДУ_ЕСЛИ_ТО ТО : { processCorrectIf(); }
МУСОР_МЕЖДУ_ЕСЛИ_ТО -> 0
ТО -> то ФРАГМЕНТ_АЛГОРИТМА* ИНАЧЕ_ВСЕ : { processCorrectThen(); }
ИНАЧЕ_ВСЕ -> все : { processCorrectFi(); }
ИНАЧЕ_ВСЕ -> иначе ФРАГМЕНТ_АЛГОРИТМА* все : { processCorrectElse(); } { processCorrectFi(); }

ВЫБОР -> выбор МУСОР_МЕЖДУ_ВЫБОР_ПРИ при ФРАГМЕНТ_АЛГОРИТМА* ПРИ* ИНАЧЕ_ВСЕ : { processCorrectSwitch(); } { processCorrectCase(); }
МУСОР_МЕЖДУ_ВЫБОР_ПРИ -> 0
ПРИ* -> при ФРАГМЕНТ_АЛГОРИТМА* : { processCorrectCase(); }
ПРИ* -> 0

ЦИКЛ -> нц ФРАГМЕНТ_АЛГОРИТМА* КОНЕЦ_ЦИКЛА : { processCorrectBeginOfLoop(); }
КОНЕЦ_ЦИКЛА -> кц : { processCorrectEndOfLoop();}
КОНЕЦ_ЦИКЛА -> кц_при : { processCorrectEndOfLoop(); }

АЛГОРИТМ* -> 0
АЛГОРИТМ* -> алг МУСОР_МЕЖДУ_АЛГ_НАЧ ДОКУМЕНТАЦИЯ ДАНО_НАДО ТЕЛО_АЛГОРИТМА : { processCorrectAlgHeader(); }
МУСОР_МЕЖДУ_АЛГ_НАЧ -> 0
ТЕЛО_АЛГОРИТМА -> нач ФРАГМЕНТ_АЛГОРИТМА* КОНЕЦ_АЛГОРИТМА : { processCorrectAlgBegin(); }
ДОКУМЕНТАЦИЯ -> строка_документации МУСОР_МЕЖДУ_АЛГ_НАЧ ДОКУМЕНТАЦИЯ : { processCorrectDocLine(); }
ДОКУМЕНТАЦИЯ -> 0
ДАНО_НАДО -> 0
ДАНО_НАДО -> дано МУСОР_МЕЖДУ_АЛГ_НАЧ ДАНО_НАДО : { processCorrectInputRestrictionLine(); }
ДАНО_НАДО -> надо МУСОР_МЕЖДУ_АЛГ_НАЧ ДАНО_НАДО : { processCorrectOutputRestrictionLine(); }
КОНЕЦ_АЛГОРИТМА -> кон : { processCorrectAlgEnd(); }

ПРОСТАЯ_СТРОКА* -> перем : { appendSimpleLine(); }

ПРОСТАЯ_СТРОКА* -> присваивание : { appendSimpleLine(); }
ПРОСТАЯ_СТРОКА* -> вызов_алгоритма : { appendSimpleLine(); }
ПРОСТАЯ_СТРОКА* -> ввод : { appendSimpleLine(); }
ПРОСТАЯ_СТРОКА* -> вывод : { appendSimpleLine(); }
ПРОСТАЯ_СТРОКА* -> ф_ввод : { appendSimpleLine(); }
ПРОСТАЯ_СТРОКА* -> ф_вывод : { appendSimpleLine(); }
ПРОСТАЯ_СТРОКА* -> утв : { appendSimpleLine(); }
ПРОСТАЯ_СТРОКА* -> выход : { appendSimpleLine(); }
ПРОСТАЯ_СТРОКА* -> 0

ФРАГМЕНТ_АЛГОРИТМА* -> 0
ФРАГМЕНТ_АЛГОРИТМА* -> УСЛОВИЕ
ФРАГМЕНТ_АЛГОРИТМА* -> ЦИКЛ
ФРАГМЕНТ_АЛГОРИТМА* -> ВЫБОР
ФРАГМЕНТ_АЛГОРИТМА* -> ПРОСТАЯ_СТРОКА*

# "выход" может встречаться только внутри алгоритмов,
# поэтому не является простой строкой и должен быть описан отдельно
ФРАГМЕНТ_АЛГОРИТМА* -> выход : { appendSimpleLine(); }

ЛИНЕЙНАЯ_СТРОКА* -> ПРОСТАЯ_СТРОКА*
ЛИНЕЙНАЯ_СТРОКА* -> 0

ИСПОЛНИТЕЛЬ* -> исп ЛИШНИЙ_НАЧ_У_ИСПОЛНИТЕЛЯ ЛИНЕЙНАЯ_СТРОКА* АЛГОРИТМ* КОНЕЦ_ИСПОЛНИТЕЛЯ : { processCorrectModuleBegin(); } 
КОНЕЦ_ИСПОЛНИТЕЛЯ -> кон_исп : { processCorrectModuleEnd(); }
#ИСПОЛНИТЕЛЬ* -> исп ЛИНЕЙНАЯ_СТРОКА* АЛГОРИТМ* кон_исп : { processCorrectModuleBegin(); } { processCorrectModuleEnd(); }
ИСПОЛНИТЕЛЬ* -> 0
ЛИШНИЙ_НАЧ_У_ИСПОЛНИТЕЛЯ -> 0

#START -> begin ЗАГРУЗКА* ИСПОЛНИТЕЛЬ* ЛИНЕЙНАЯ_СТРОКА* АЛГОРИТМ* 
START -> begin ЗАГРУЗКА* ЛИНЕЙНАЯ_СТРОКА* ОШИБОЧНАЯ_ЗАГРУЗКА* АЛГОРИТМЫ_ВНЕ_ИСПОЛНИТЕЛЯ* ИСПОЛНИТЕЛЬ* МУСОР_В_КОНЦЕ_ПРОГРАММЫ*
#START -> begin ИСПОЛНИТЕЛЬ* ЛИНЕЙНАЯ_СТРОКА* АЛГОРИТМ* 
#START -> begin ЛИНЕЙНАЯ_СТРОКА* АЛГОРИТМ* ИСПОЛНИТЕЛЬ* 
#START -> begin ЛИНЕЙНАЯ_СТРОКА* АЛГОРИТМ*
#START -> begin АЛГОРИТМ* ИСПОЛНИТЕЛЬ*

АЛГОРИТМЫ_ВНЕ_ИСПОЛНИТЕЛЯ* -> СТРОКА_ВНЕ_АЛГОРИТМА* АЛГОРИТМ*
АЛГОРИТМЫ_ВНЕ_ИСПОЛНИТЕЛЯ* -> АЛГОРИТМ*
АЛГОРИТМЫ_ВНЕ_ИСПОЛНИТЕЛЯ* -> 0

СТРОКА_ПЕРЕД_АЛГОРИТМОМ* -> 0
ОШИБОЧНАЯ_ЗАГРУЗКА* -> 0
СТРОКА_ВНЕ_АЛГОРИТМА* -> 0
МУСОР_В_КОНЦЕ_ПРОГРАММЫ* -> 0

ЗАГРУЗКА* -> 0
ЗАГРУЗКА* -> использовать : { processCorrectLoad(); }
