(*~\Глагол\приложкемяLink\МПГ2009 (компилируется, но НЕ раб.?)\~~~~~~~~~~~~~~~*)
(**)                                                     ОТДЕЛ Выражения;
(****************************************************************************** 
 * НАЗНАЧЕНИЕ: разбор выражений языка
 ******************************************************************************)

ИСПОЛЬЗУЕТ 
  ОБХОД,
        (*  \Глагол\              *)
  оЦепи   ИЗ "..\..\Отделы\Иное\",
   Пустой ИЗ "..\..\Отделы\Иное\",
ЧэргаСлеД ИЗ "..\..\Отделы\Иное\",
(*
  Набор   ИЗ "..\..\Отделы\Иное\",
  Цепь    ИЗ "..\..\Отделы\Иное\",
*)
  Ядро,
  Настрой,
  Данные,
  Обмен,
  Код,
  Узел,
  Рег,
  ВКод,
  Слово,
  Разбор,
  Ошибка;
                      (*--
                               локальные ПОСТоянные 
                        --*)
   (* выходы из КОЛЬЦО *)
ПОСТ
  кУровней=32; (* м.б. вложений *)
ПЕР 
  кУровень:ЦЕЛ; (* текущий ур. вложений *)
  кВыходы:РЯД кУровней ИЗ ЦЕЛ; (* метки выхода для каждого уровня *)
  кДопПер:РЯД кУровней ИЗ ЦЕЛ; (* доп. переменных для указаний ОТ ДО и ВЫБРАТЬ *)

                     (*--- неопределенные (опережающие определение своего опорного вида) доступы ---*)
ВИД
(*НеопрДоступ = ДОСТУП К НАБОР(Набор.Вид)*)
  ДкНеопрВиду = ДОСТУП К (*нНеопрВид;
                           нНеопрВид =*) НАБОР(ЧэргаСлеД.нПустой)
    вид:Данные.ДкВиду;                                       (* доступ к виду *)
    имя:Ядро.Имя                                   (* неопределенное имя вида *)
  КОН;

(*---
                     набор-список доступов к неопределённым видам данных (см. РВ.отд)
  ---*)
ПЕР
  доступыКнеопрВидам:ЧэргаСлеД.нСписок;
(*неопрДоступы      :Набор.Список;*)      (* очередь
                             из доступов к неопределённым видам - ДкНеопрВиду *)

                  (*--- тексторез ---*)
ПОСТ
  трУровней=32; (* м.б. вложений *)  
  (* состояния: *)
  трДоВкл=0; трВкл=1; трОткл=-1;
ПЕР
  трРаботает:КЛЮЧ;
  трУровень:ЦЕЛ;
  трСостояние:РЯД трУровней ИЗ ЦЕЛ;

                  (*--- разное ---*)
ПЕР 
  слово:ЦЕЛ;           (* прочитанное слово из входного текста *)
  оЦепьРазрешена:ЦЕЛ;  (* объявление разрешёно только при >= 0 *)
  размерПриёмников:ЦЕЛ;(* размер приёмников у обрабатываемой задачи *)


                   (*--- вид-доступ к телу звена в списке испИмена ---*)
ВИД
                                          (* для разбора взаимосвязей отделов *)
(*  ИспИмя- = ДОСТУП К НАБОР(Набор.Вид) *)
  ДкИспИмя- = ДОСТУП К (*нИспИмя;
                         нИспИмя =*) НАБОР(ЧэргаСлеД.нПустой)
    имя-  :Ядро.Имя;
    путь- :Пустой.ДкЦепи;    (* :ДОСТУП К ЦЕПЬ; *)
(*  путь- :ДОСТУП К ЦЕПЬ; *)
    начСлова-:Разбор.Положение
                                     КОН;

ПЕР                                       (* местоположение файла "СРЕДА.отд" *)
(*срдМесто:ДОСТУП К ЦЕПЬ;*)
  срдМесто:Пустой.ДкЦепи;  (* :ДОСТУП К ЦЕПЬ; *) 


(*-оооооооооооооо- опережающие определения/заготовки задач -ооооооооооооооооо-*)


ЗАДАЧА^ Заголовок(видОтвета+:Данные.ДкВиду; вложенная,передаваемая,быстрая:КЛЮЧ):ЦЕЛ;
ЗАДАЧА^ Вид(вид+:Данные.ДкВиду);
ЗАДАЧА^ Выражение(уа+:Узел.нВид);
ЗАДАЧА^ Объявления(задача:Данные.ДкПонятию; конИмя-:Ядро.Имя);
ЗАДАЧА^ Указания;
ЗАДАЧА^ Тексторез;


(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ЧитатьСлово;
УКАЗ
        слово:=Разбор.Слова();
  ПОКА (слово = Слово.мумн) И НЕ трРаботает ВЫП
    трРаботает:=ВКЛ;
    Тексторез;
    трРаботает:=ОТКЛ
  КОН
КОН ЧитатьСлово;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ПропуститьСлово(с:ЦЕЛ);
УКАЗ
  ЕСЛИ слово = с ТО ЧитатьСлово ИНАЧЕ Ошибка.Отметить(с) КОН
КОН ПропуститьСлово;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТекущееСлово(с:ЦЕЛ);
УКАЗ
  ЕСЛИ слово # с ТО Ошибка.Отметить(с) КОН
КОН ТекущееСлово;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА БудетСлово(с:ЦЕЛ);
УКАЗ
  ЧитатьСлово;
  ЕСЛИ слово # с ТО Ошибка.Отметить(с) КОН
КОН БудетСлово;

(******************************************************************************)
ЗАДАЧА СледующееСлово():ЦЕЛ;
УКАЗ
  ЧитатьСлово;
  ВОЗВРАТ слово
КОН СледующееСлово;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА НайтиПонятие():Данные.ДкПонятию;
(* Цель:  найти понятие в текущей области видимости, учитывая приставки отделов
 * До:    слово = Слово.название
 * Возвр: найденное понятие *)
ПЕР
  пон:Данные.ДкПонятию;
УКАЗ
  пон:=Данные.ИскатьПонятие(Разбор.имя);
  ЕСЛИ пон = ПУСТО ТО
    Ошибка.ОтметитьИмя(Ошибка.НЕ_ОБЪЯВЛЕНО,Разбор.имя)
  КОН;
  ЕСЛИ пон.родп = Данные.пОтдел ТО
    БудетСлово(Слово.точка);
    БудетСлово(Слово.название);
    ЕСЛИ Данные.прТекущегоОтдела В пон.признаки ТО (* в своём отделе по своему *)
      пон:=Данные.ИскатьВСписке(пон.первпон,Разбор.имя);
      ЕСЛИ пон = ПУСТО ТО
        Ошибка.ОтметитьИмя(Ошибка.НЕ_ОБЪЯВЛЕНО,Разбор.имя)
      КОН
    ИНАЧЕ
      пон:=Данные.ИскатьВСписке(пон.первпон,Разбор.имя);
      ЕСЛИ (пон = ПУСТО) ИЛИ (* или скрытый вид *)
      (пон.родп = Данные.пВид) И НЕ (Данные.прОбщедоступная В пон.признаки) ТО
        Ошибка.ОтметитьИмя(Ошибка.НЕ_ОБЪЯВЛЕНО,Разбор.имя)
      КОН
    КОН
  КОН;
  ЕСЛИ пон.родп = Данные.пОтдел ТО
    Ошибка.Отметить(Ошибка.НЕОЖИДАННЫЙ_ОТДЕЛ)
  КОН;
  ЧитатьСлово;
  ВОЗВРАТ пон
КОН НайтиПонятие;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Признаки():МНОЖ;
(* Цель:  прочитать признаки доступности понятия
 * Прим:  не используется для приёмников и отделов *)
ПЕР
  признаки:МНОЖ;
УКАЗ
  ЧитатьСлово;
  ЕСЛИ слово = Слово.плюс ТО
    признаки:={Данные.прОбщедоступная};
    ЧитатьСлово
  АЕСЛИ слово = Слово.минус ТО
    признаки:={Данные.прОбщедоступная,Данные.прНеизменяемая};
    ЧитатьСлово
  ИНАЧЕ
    признаки:={}
  КОН;
  ВОЗВРАТ признаки
КОН Признаки;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ПостВыражение(у+:Узел.нВид);
УКАЗ
  Выражение(у);
  ЕСЛИ у.роду = Узел.уКодУсл ТО
    Узел.СнятьКУ(у)
  КОН;
  ЕСЛИ у.роду # Узел.уПост ТО
    Ошибка.Отметить(Ошибка.ЭТО_НЕ_ПОСТОЯННАЯ)
  КОН
КОН ПостВыражение;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВидНабор(вид+:Данные.ДкВиду);
ПЕР
  смещение:ЦЕЛ;           (* смещение адреса свойства от начала набора *)
  размер:ЦЕЛ;             (* размер данных набора *)
  видоб:Данные.ДкВиду;       (* общий вид для объединения *)
  овид:Данные.ДкВиду;        (* опорный вид набора и свойства *)
  пон,перв:Данные.ДкПонятию;(* свойство и первое свойство объединения *)
УКАЗ
  смещение:=0;
  вид:=Данные.СоздатьВид(Данные.вНабор);
  ЕСЛИ слово = Слово.лкругл ТО (* есть опорный вид *)
    БудетСлово(Слово.название);
    пон:=НайтиПонятие();
    ЕСЛИ пон.родп # Данные.пВид ТО
      Ошибка.Отметить(Ошибка.ЭТО_НЕ_ВИД)
    АЕСЛИ вид.родв # Данные.вНабор ТО
      Ошибка.Отметить(Ошибка.ЭТО_НЕ_НАБОР)
    АЕСЛИ пон.вид = Данные.нетвид ТО
      Ошибка.Отметить(Ошибка.ПЕРЕКРЁСТНЫЙ_ВИД)
    КОН;
    овид:=пон.вид;
    вид.овид:=овид;
    смещение:=овид.размер;
    ПропуститьСлово(Слово.пркругл)
  КОН;
  (* свойства набора *)
  Данные.ОткрытьОбласть("НАБОР");
  КОЛЬЦО
    ЕСЛИ слово = Слово.название ТО
      (* объединение свойств с общим видом *)
      перв:=ПУСТО;
      КОЛЬЦО
        ТекущееСлово(Слово.название);
        ЕСЛИ вид.овид # Данные.неопрвид ТО
          пон:=Данные.ИскатьСвойство(вид,Разбор.имя);
          ЕСЛИ пон # ПУСТО ТО
            Ошибка.ОтметитьИмя(Ошибка.ПЕРЕОПРЕДЕЛЕНИЕ,Разбор.имя)
          КОН
        КОН;
        пон:=Данные.Вставить(Разбор.имя);
        пон.родп:=Данные.пСвойство;
        пон.признаки:=Признаки();
        ЕСЛИ (Данные.уровень > 0) И (Данные.прОбщедоступная В пон.признаки) ТО
          Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ОТМЕТКА)
        КОН;
        ЕСЛИ перв = ПУСТО ТО 
          перв:=пон 
        КОН;
        ЕСЛИ слово # Слово.запятая ТО ВЫХОД КОН;
        ЧитатьСлово
      КОН;
      ПропуститьСлово(Слово.двоеточие);
      Вид(видоб);
      размер:=видоб.размер;
      (* выравнивание адреса свойства *)
      овид:=видоб;
      ПОКА овид.родв = Данные.вРяд ВЫП
        овид:=овид.овид
      КОН;
      ЕСЛИ овид.размер >= 4 ТО
        УВЕЛИЧИТЬ(смещение,(-смещение) ОСТАТОК 4)
      АЕСЛИ овид.размер = 2 ТО
        УВЕЛИЧИТЬ(смещение,смещение ОСТАТОК 2)
      КОН;
      (* выставляем вид и адрес у объединения свойств *)
      пон:=перв;
      ПОКА пон # ПУСТО ВЫП
        пон.вид:=видоб;
        пон.адр:=смещение;
        УВЕЛИЧИТЬ(смещение,размер);
        пон:=пон.след
      КОН
    КОН;
    ЕСЛИ слово # Слово.точкасзап ТО ВЫХОД КОН;
    ЧитатьСлово
  КОН;
  УВЕЛИЧИТЬ(смещение,(-смещение) ОСТАТОК 4);
  вид.размер:=смещение;
  вид.первпон:=Данные.текОбласть.первпон;
  Код.ПодготовитьОВ(вид);
  Данные.ЗакрытьОбласть;
  ПропуститьСлово(Слово.кон)
КОН ВидНабор;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВидРяд(вид+:Данные.ДкВиду);
ПЕР
  у:Узел.нВид;
УКАЗ
  вид:=Данные.СоздатьВид(Данные.вРяд);
  ПостВыражение(у);
  ЕСЛИ НЕ (у.вид.родв В Данные.множЦелых) ТО
    Ошибка.Отметить(Ошибка.ПОСТОЯННАЯ_НЕ_ЦЕЛАЯ)
  АЕСЛИ у.a <= 0 ТО
    Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ПОСТОЯННАЯ)
  КОН;
  ЕСЛИ слово = Слово.из ТО
    ЧитатьСлово;
    Вид(вид.овид)
  АЕСЛИ слово = Слово.запятая ТО
    ЧитатьСлово;
    ВидРяд(вид.овид)
  ИНАЧЕ
    Ошибка.Отметить(Слово.из)
  КОН;
  вид.размер:=у.a*вид.овид.размер
КОН ВидРяд;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВидБегунок(вид+:Данные.ДкВиду);
ПЕР
  у:Узел.нВид;
УКАЗ
  вид:=Данные.СоздатьВид(Данные.вБегунок);
  вид.размер:=Настрой.рБегунок;
  ЕСЛИ слово # Слово.по ТО
    ПостВыражение(у);
    ЕСЛИ НЕ (у.вид.родв В Данные.множЦелых) ТО
      Ошибка.Отметить(Ошибка.ПОСТОЯННАЯ_НЕ_ЦЕЛАЯ)
    КОН;
    вид.шаг:=у.a
  ИНАЧЕ
    вид.шаг:=1
  КОН;
  ПропуститьСлово(Слово.по);
  Вид(вид.овид)
КОН ВидБегунок;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВидЗадача(вид+:Данные.ДкВиду);
ПЕР
  рПриёмников:ЦЕЛ;
  передаваемая,быстрая:КЛЮЧ;
УКАЗ
  вид:=Данные.СоздатьВид(Данные.вЗадача);
  вид.размер:=Настрой.рЗадача;
  передаваемая:=ОТКЛ;
  быстрая:=ОТКЛ;
  ЕСЛИ слово = Слово.минус ТО
    передаваемая:=ВКЛ;
    вид.шаг:=1;
    ЧитатьСлово
  АЕСЛИ слово = Слово.умножить ТО
    быстрая:=ВКЛ;
    вид.шаг:=2;
    ЧитатьСлово
  КОН;
  ЕСЛИ слово = Слово.лкругл ТО
    ЧитатьСлово;
    Данные.ОткрытьОбласть("ЗАДАЧА");
    рПриёмников:=Заголовок(вид.овид,ОТКЛ,передаваемая,быстрая);
    вид.первпон:=Данные.текОбласть.первпон;
    Данные.текОбласть.видотв:=вид.овид;
    Данные.ЗакрытьОбласть
  ИНАЧЕ
    вид.овид:=Данные.нетвид;
    вид.первпон:=ПУСТО
  КОН
КОН ВидЗадача;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВидДоступ(вид+:Данные.ДкВиду);
ПЕР
  пон:Данные.ДкПонятию; (* именной вид *)

  неопрДоступ:ДкНеопрВиду;
УКАЗ
  вид:=Данные.СоздатьВид(Данные.вДоступ);
  вид.размер:=Настрой.рЗадача;
  ПропуститьСлово(Слово.к);
  ЕСЛИ слово = Слово.название ТО
    пон:=Данные.ИскатьПонятие(Разбор.имя);
    ЕСЛИ пон = ПУСТО ТО
      (* точно нет такого название *)
      вид.овид:=Данные.неопрвид;
      СОЗДАТЬ(неопрДоступ);
              неопрДоступ.имя:=Разбор.имя;
              неопрДоступ.вид:=вид;

      ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(доступыКнеопрВидам,неопрДоступ);
      ЧитатьСлово
    ИНАЧЕ
      (* может это название отдела *)
      пон:=НайтиПонятие();
      ЕСЛИ пон.родп # Данные.пВид ТО
        Ошибка.Отметить(Ошибка.ЭТО_НЕ_ВИД)
      АЕСЛИ НЕ (пон.вид.родв В {Данные.вНабор,Данные.вРяд}) ТО
        Ошибка.Отметить(Ошибка.ДОСТУП_ЗАПРЕЩЕН)
      КОН;
      вид.овид:=пон.вид
    КОН
  ИНАЧЕ
    Вид(вид.овид);
    ЕСЛИ НЕ (вид.овид.родв В {Данные.вНабор,Данные.вРяд}) ТО
      Ошибка.Отметить(Ошибка.ДОСТУП_ЗАПРЕЩЕН)
    КОН
  КОН
КОН ВидДоступ;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВидЦепь(вид+:Данные.ДкВиду);
ПЕР
  у:Узел.нВид;
УКАЗ
  вид:=Данные.СоздатьВидЦепь(0);
  ЕСЛИ слово = Слово.лквадр ТО
    ЧитатьСлово();
    ПостВыражение(у);
    ЕСЛИ НЕ (у.вид.родв В Данные.множЦелых) ТО
      Ошибка.Отметить(Ошибка.ПОСТОЯННАЯ_НЕ_ЦЕЛАЯ)
    АЕСЛИ у.a <= 0 ТО
      Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ПОСТОЯННАЯ)
    КОН;
    вид.размер:=у.a*вид.овид.размер;
    ПропуститьСлово(Слово.прквадр)
  АЕСЛИ оЦепьРазрешена < -1 ТО
    Ошибка.Отметить(Ошибка.ОРЯД_НЕДОПУСТИМ)
  КОН
КОН ВидЦепь;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Вид(вид+:Данные.ДкВиду);
ПЕР
  пон:Данные.ДкПонятию;
УКАЗ
  УМЕНЬШИТЬ(оЦепьРазрешена);
  ВЫБРАТЬ слово ИЗ
  | Слово.название: (* имя другого вида *)
      пон:=НайтиПонятие();
      ЕСЛИ пон.родп # Данные.пВид ТО
        Ошибка.Отметить(Ошибка.ЭТО_НЕ_ВИД)
      АЕСЛИ пон.вид = Данные.нетвид ТО
        Ошибка.Отметить(Ошибка.НЕ_ОБЪЯВЛЕНО)
      АЕСЛИ пон.вид = Данные.оячейкивид ТО
        ЕСЛИ оЦепьРазрешена < -1 ТО
          Ошибка.Отметить(Ошибка.ОРЯД_НЕДОПУСТИМ)
        КОН
      КОН;
      вид:=пон.вид
  | Слово.ряд:    ЧитатьСлово; ВидРяд(вид)
  | Слово.цепь:   ЧитатьСлово; ВидЦепь(вид)
  | Слово.набор:  ЧитатьСлово; ВидНабор(вид)
  | Слово.доступ: ЧитатьСлово; ВидДоступ(вид)
  | Слово.задача: ЧитатьСлово; ВидЗадача(вид)
  | Слово.бегунок:ЧитатьСлово; ВидБегунок(вид)
  ИНАЧЕ
    Ошибка.Отметить(Ошибка.НЕВЕРНОЕ_НАЧАЛО_ВИДА)
  КОН;
  УВЕЛИЧИТЬ(оЦепьРазрешена)
КОН Вид;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Заголовок(видОтвета+:Данные.ДкВиду; вложенная,передаваемая,быстрая:КЛЮЧ):ЦЕЛ;
(* Цель:  приёмники в объявлении задачи
 * После: <видОтвета>                 - вид ответа задачи
 *        <вложенная>                 - признак вложенной задачи
 *        <передаваемая>              - признак передаваемой задачи
 *        <быстрая>                   - признак быстрой (регистровой) задачи
 *        <Данные.текОбласть.первпон> - список приёмников у которых:
 *        <.адр>                      - смещение приёмника от FP или номер регистра
 * Возвр: общий размер всех приёмников *)
ПЕР
  рПриёмников:ЦЕЛ;         (* общий размер всех прёмников            *)
  ответ:Данные.ДкПонятию;    (* для вида ответа                        *)
  видоб:Данные.ДкВиду;        (* общий вид для объединения              *)
  пон,перв:Данные.ДкПонятию; (* приёмник и первый приёмник объединения *)
(* 
  пример расположения в памяти 2-х приёмников (рПриёмников=8):
память   | FP'  LR   пр2   пр1
         |----------------------
адр до   |             4     0
адр после| (0)  (4)    8    12
рег      |            R1    R0

  пример со 2-м приёмником оЦепь (рПриёмников=12):
память   | FP'  LR   пр2    рпр2 пр1  
         |----------------------------
адр до   |             8    (4)    0 
адр после| (0)  (4)    8   (12)   16  
рег      |            R1    R2    R0

  пример со 2-м приёмником 2-мерным оРяд (рПриёмников=16):
память   | FP'  LR   пр2    р1    р2   пр1  
         |----------------------------------
адр до   |            12    (8)   (4)    0 
адр после| (0)  (4)    8   (12)  (16)   20  
рег      |            R1    R2    R3    R0

  пример со 2-м приёмником ссылкой на набор (рПриёмников=12):
память   | FP'  LR   пр2   ОВ2   пр1  
         |----------------------------
адр до   |             8    (4)    0 
адр после| (0)  (4)    8   (12)   16  
рег      |            R1    R2    R0

  пример для вложенной задачи с 2-мя приёмниками (рПриёмников=12):
память   | FP'  LR   SL'  пр2   пр1
         |---------------------------
адр до   |             8     4     0
адр после| (0)  (4)   (8)   12    16
рег      |            FP    R1    R0

FP  - указатель окна
FP' - связь окон по вызовам
SL' - связь окон по уровням

приёмники быстрых задач расположены в регистрах R0, R1, ...
*)
УКАЗ
  рПриёмников:=0;
  ЕСЛИ слово = Слово.название ТО
    КОЛЬЦО
      перв:=ПУСТО;
      КОЛЬЦО
        ТекущееСлово(Слово.название);
        пон:=Данные.Вставить(Разбор.имя);
        пон.признаки:={Данные.прВложенная,Данные.прПриёмник};
        ЧитатьСлово;
        ЕСЛИ (слово = Слово.плюс) ИЛИ (слово = Слово.минус) ТО
          пон.родп:=Данные.пСсылка;
          ЕСЛИ слово = Слово.минус ТО
            пон.признаки:=пон.признаки+{Данные.прНеизменяемая}
          КОН;
          ЧитатьСлово
        ИНАЧЕ
          пон.родп:=Данные.пПер
        КОН;
        ЕСЛИ перв = ПУСТО ТО 
          перв:=пон 
        КОН;
        ЕСЛИ слово # Слово.запятая ТО ВЫХОД КОН;
        ЧитатьСлово
      КОН;
      ПропуститьСлово(Слово.двоеточие);
      Вид(видоб);
      ЕСЛИ (видоб.родв В {Данные.вБегунок,Данные.вОРяд,Данные.вОЦепь}) 
          И передаваемая ТО
        Ошибка.Отметить(Ошибка.ВИД_ПЕРЕДАВАЕМОЙ)
      КОН;
      (* привязываем вид и адр к приёмникам объединения *)
      пон:=перв;
      ПОКА пон # ПУСТО ВЫП
        ЕСЛИ видоб.родв В {Данные.вРяд,Данные.вОРяд,Данные.вЦепь,Данные.вОЦепь,Данные.вОЯчейки,Данные.вНабор} ТО
          (* приёмник значений не может иметь сложный вид *)
          ЕСЛИ пон.родп = Данные.пПер ТО
            Ошибка.Отметить(Ошибка.ПРИЁМНИК_СОСТ_ВИДА)
          КОН
        ИНАЧЕ
          (* неизменяемые приёмники простых видов будут приёмниками значений *)
          ЕСЛИ (пон.родп = Данные.пСсылка) И (Данные.прНеизменяемая В пон.признаки) ТО
            пон.родп:=Данные.пПер
          КОН
        КОН;
        пон.вид:=видоб;
        (* стог для размеров оРяд *)
        ЕСЛИ НЕ быстрая И (видоб.родв В {Данные.вОЯчейки,Данные.вОРяд,Данные.вОЦепь}) ТО
          УВЕЛИЧИТЬ(рПриёмников,4*видоб.размер)
        КОН;
        (* стог для ОВ *)
        ЕСЛИ НЕ быстрая И (видоб.родв = Данные.вНабор) ТО
          УВЕЛИЧИТЬ(рПриёмников,4)
        КОН;
        (* место для приёмника *)
        пон.адр:=рПриёмников;
        УВЕЛИЧИТЬ(рПриёмников,4);
        (* регистры для размеров оРяд *)
        ЕСЛИ быстрая И (видоб.родв В {Данные.вОЯчейки,Данные.вОРяд,Данные.вОЦепь}) ТО
          УВЕЛИЧИТЬ(рПриёмников,4*видоб.размер)
        КОН;
        (* регистр для ОВ *)
        ЕСЛИ быстрая И (видоб.родв = Данные.вНабор) ТО
          УВЕЛИЧИТЬ(рПриёмников,4)
        КОН;
        пон:=пон.след
      КОН;
      ЕСЛИ слово # Слово.точкасзап ТО ВЫХОД КОН;
      ЧитатьСлово
    КОН
  КОН;
  ПропуститьСлово(Слово.пркругл);
  (* вид ответа *)
  ЕСЛИ слово = Слово.двоеточие ТО
    БудетСлово(Слово.название);
    ответ:=НайтиПонятие();
    ЕСЛИ ответ.родп # Данные.пВид ТО
      Ошибка.Отметить(Ошибка.ЭТО_НЕ_ВИД)
    АЕСЛИ ответ.вид.родв >= Данные.вРяд ТО
      Ошибка.Отметить(Ошибка.СЛОЖНЫЙ_ОТВЕТ)
    КОН;
    видОтвета:=ответ.вид
  ИНАЧЕ
    видОтвета:=Данные.нетвид
  КОН;
  ЕСЛИ вложенная И НЕ быстрая ТО
    УВЕЛИЧИТЬ(рПриёмников,4) (* для SL' *)
  КОН;
  (* смещения всех приёмников от FP или № регистра *)
  пон:=Данные.текОбласть.первпон;
  ПОКА пон # ПУСТО ВЫП
    ЕСЛИ быстрая ТО (* номер регистра *)
      пон.признаки:=пон.признаки+{Данные.прБыстрая};
      пон.адр:=пон.адр ДЕЛИТЬ 4
    ИНАЧЕ (* смещение от FP *)
      пон.адр:=4+рПриёмников-пон.адр (* 4 это место для FP' и LR *)
    КОН;
    пон:=пон.след
  КОН;
  ВОЗВРАТ рПриёмников
КОН Заголовок;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Источники(приёмник:Данные.ДкПонятию; быстрая:КЛЮЧ);
(* вычисление и передача источников *)
ПЕР
  источник:Узел.нВид;
УКАЗ
  ЕСЛИ слово # Слово.пркругл ТО
    КОЛЬЦО
      ЕСЛИ НЕ Данные.ЭтоПриёмник(приёмник) ТО
        Ошибка.Отметить(Ошибка.МНОГО_ИСТОЧНИКОВ)
      КОН;
      ЕСЛИ быстрая ТО
        Рег.Нужен(Рег.ЗанятьСледПер()) (* убыстрение *)
      КОН;
      Выражение(источник);
      ВКод.Передать(источник,приёмник,быстрая);
      ЕСЛИ Данные.быстрая ТО (* убыстрение *)
        Рег.Нужен(-1)
      КОН;
      Узел.Освободить(источник); 
      приёмник:=приёмник.след;
      ЕСЛИ слово # Слово.запятая ТО ВЫХОД КОН;
      ЧитатьСлово
    КОН
  КОН;
  ЕСЛИ быстрая ТО
    Рег.ОсвободитьВсеПер()
  КОН;
  ПропуститьСлово(Слово.пркругл);
  ЕСЛИ Данные.ЭтоПриёмник(приёмник) ТО
    Ошибка.Отметить(Ошибка.МАЛО_ИСТОЧНИКОВ)
  КОН
КОН Источники;

(******************************************************************************)
ЗАДАЧА Переключатель(уа+:Узел.нВид);
ПЕР
  пон:Данные.ДкПонятию; 
  уб:Узел.нВид;
УКАЗ
  КОЛЬЦО
    ЕСЛИ слово = Слово.лквадр ТО
      ЧитатьСлово;
      КОЛЬЦО
        ЕСЛИ уа.роду В {Узел.уПост,Узел.уВид..Узел.уВстрЗадача} ТО
          Ошибка.Отметить(Ошибка.ЭТО_НЕ_ПЕРЕМЕННАЯ)
        КОН;
        ЕСЛИ (уа.вид # ПУСТО) И (уа.вид.родв = Данные.вДоступ) ТО
          Узел.Доступ(уа)
        КОН;
        Выражение(уб);
        Узел.АдрПерРяда(уа,уб);
        ЕСЛИ слово # Слово.запятая ТО ВЫХОД КОН;
        ЧитатьСлово
      КОН;
      ПропуститьСлово(Слово.прквадр)
    АЕСЛИ слово = Слово.точка ТО
      БудетСлово(Слово.название);
      ЕСЛИ уа.вид = ПУСТО ТО
        Ошибка.Отметить(Ошибка.ЭТО_НЕ_ВИД)
      КОН;
      ЕСЛИ уа.вид.родв = Данные.вДоступ ТО
        Узел.Доступ(уа)
      КОН;
      ЕСЛИ уа.вид.родв # Данные.вНабор ТО
        Ошибка.Отметить(Ошибка.ЭТО_НЕ_НАБОР)
      КОН;
      пон:=Данные.ИскатьСвойство(уа.вид,Разбор.имя);
      ЕСЛИ пон = ПУСТО ТО
        Ошибка.Отметить(Ошибка.НЕТ_СВОЙСТВА)
      КОН;
      Узел.Свойство(уа,пон); 
      ЧитатьСлово
    АЕСЛИ слово = Слово.стрелка ТО
      ЧитатьСлово;
      Узел.Доступ(уа)
    АЕСЛИ (слово = Слово.лкругл)
        И (НЕ (уа.роду В {Узел.уВид,Узел.уПост,Узел.уЗадача,Узел.уВстрЗадача}))
        И (уа.вид.родв # Данные.вЗадача) ТО
      (* охрана вида *)
      БудетСлово(Слово.название);
      пон:=НайтиПонятие();
      ВКод.ОхранаВида(уа,пон,ОТКЛ);
      уа.вид:=пон.вид;
      ПропуститьСлово(Слово.пркругл)
    ИНАЧЕ
      ВЫХОД
    КОН
  КОН
КОН Переключатель;

(******************************************************************************)
ЗАДАЧА ВызовВстрЗадачи(у0+:Узел.нВид);
ПЕР
  у1,у2:Узел.нВид;
  задача,приёмников:ЦЕЛ;
УКАЗ
  задача:=у0.пон.адр;
  приёмников:=0;
  ПропуститьСлово(Слово.лкругл);
  КОЛЬЦО
    ВЫБРАТЬ приёмников ИЗ
    | 0: Выражение(у0); Узел.ВстрПриёмник0(задача,у0)
    | 1: Выражение(у1); Узел.ВстрПриёмник1(задача,у0,у1)
    | 2: Выражение(у2); Узел.ВстрПриёмник2(задача,у0,у1,у2)
    ИНАЧЕ
      Ошибка.Отметить(Ошибка.МНОГО_ИСТОЧНИКОВ)
    КОН;
    УВЕЛИЧИТЬ(приёмников);
    ЕСЛИ слово # Слово.запятая ТО ВЫХОД КОН;
    ЧитатьСлово
  КОН;
  Узел.ВстрПриёмникN(задача,приёмников,у0,у1,у2);
  ПропуститьСлово(Слово.пркругл)
КОН ВызовВстрЗадачи;

(******************************************************************************)
ЗАДАЧА Элемент(у+:Узел.нВид);
ПЕР
  у1,у2:Узел.нВид;
УКАЗ
  Выражение(у1);
  ЕСЛИ слово = Слово.дветочки ТО
    ЧитатьСлово;
    Выражение(у2);
    Узел.ВнестиНеск(у,у1,у2)
  ИНАЧЕ
    Узел.Внести1(у,у1)
  КОН 
КОН Элемент;

(******************************************************************************)
ЗАДАЧА Множество(x+:Узел.нВид);
ПЕР
  y:Узел.нВид;
УКАЗ
  x.вид:=Данные.множвид; 
  y.вид:=Данные.множвид;
  ЕСЛИ слово # Слово.прфигурн ТО
    Элемент(x);
    ПОКА слово = Слово.запятая ВЫП
      ЧитатьСлово;
      Элемент(y);
      Узел.Действие(Слово.плюс,x,y)
    КОН
  ИНАЧЕ (* {} *)
    x.роду:=Узел.уПост;
    x.a:=0
  КОН;
  ПропуститьСлово(Слово.прфигурн)
КОН Множество;
             
(******************************************************************************)
ЗАДАЧА Вызов(у+:Узел.нВид; сОтветом:КЛЮЧ);
ПЕР
  приёмники:Данные.ДкПонятию;
  сохрРеги:МНОЖ;
  быстрая:КЛЮЧ;
УКАЗ
  ЕСЛИ у.роду = Узел.уВстрЗадача ТО
    ЕСЛИ Данные.быстрая И 
      (у.пон.адр В {Данные.зВШирЦел,Данные.зДлина,Данные.зМодуль,
                    Данные.зЦелЧасть,Данные.зОбнулить,Данные.зСоздать,
                    Данные.зСтоп,Данные.зОбраз,Данные.зСписать}) ТО
      Ошибка.Отметить(Ошибка.НЕ_СОВМЕСТИМО_С_БЫСТРОЙ)
    КОН;
    ВызовВстрЗадачи(у);
    ЕСЛИ (НЕ сОтветом) И (у.вид.родв # Данные.вНет) ТО
      Ошибка.Отметить(Ошибка.ОТВЕТ_НЕ_ИСПОЛЬЗОВАН)
    КОН
  АЕСЛИ (слово = Слово.лкругл) ИЛИ НЕ сОтветом ТО
    ЕСЛИ Данные.быстрая ТО
      Ошибка.Отметить(Ошибка.НЕ_СОВМЕСТИМО_С_БЫСТРОЙ)
    КОН;
    ЕСЛИ у.роду = Узел.уЗадача ТО
      ЕСЛИ Данные.прПередаваемая В у.пон.признаки ТО
        Ошибка.Отметить(Ошибка.ВЫЗОВ_ПЕРЕДАВАЕМОЙ)
      КОН;
      быстрая:=Данные.прБыстрая В у.пон.признаки;
      приёмники:=у.пон.первпон
    АЕСЛИ (у.вид # ПУСТО) И (у.вид.родв = Данные.вЗадача) ТО
      ЕСЛИ у.вид.шаг = 1 ТО
        Ошибка.Отметить(Ошибка.ВЫЗОВ_ПЕРЕДАВАЕМОЙ)
      АЕСЛИ у.вид.шаг = 2 ТО
        быстрая:=ВКЛ
      ИНАЧЕ
        быстрая:=ОТКЛ
      КОН;
      приёмники:=у.вид.первпон
    ИНАЧЕ
      Ошибка.Отметить(Ошибка.ЭТО_НЕ_ЗАДАЧА)
    КОН;
    ЕСЛИ сОтветом ТО
      сохрРеги:=ВКод.СохранитьРеги()
    КОН;
    ЕСЛИ слово = Слово.лкругл ТО
      ЧитатьСлово;
      Источники(приёмники,быстрая)
    АЕСЛИ (НЕ сОтветом) И Данные.ЭтоПриёмник(приёмники) ТО
      Ошибка.Отметить(Ошибка.МАЛО_ИСТОЧНИКОВ)
    КОН;
    ВКод.Вызов(у,быстрая);
    ЕСЛИ сОтветом ТО
      ВКод.ПолучитьОтвет(сохрРеги,у)
    АЕСЛИ у.вид.родв # Данные.вНет ТО
      Ошибка.Отметить(Ошибка.ОТВЕТ_НЕ_ИСПОЛЬЗОВАН)
    КОН
  КОН
КОН Вызов;

(******************************************************************************)
ЗАДАЧА Множитель(у+:Узел.нВид);
ПЕР
  пон:Данные.ДкПонятию;
УКАЗ
  ВЫБРАТЬ слово ИЗ
    Слово.название:
      Узел.Создать(НайтиПонятие(),у);
      Переключатель(у);
      ЕСЛИ у.роду = Узел.уВстрЗадача ТО
        ВызовВстрЗадачи(у)
      АЕСЛИ слово = Слово.лкругл ТО
        Вызов(у,ВКЛ)
      КОН
  | Слово.знак:
      у.роду:=Узел.уПост;
      у.a:=Разбор.целЗнач;
      у.вид:=Данные.знаквид;
      ЧитатьСлово
  | Слово.целпост:
      у.роду:=Узел.уПост;
      у.a:=Разбор.целЗнач;
      Узел.ОпредЦелВид(у);
      ЧитатьСлово
  | Слово.вещпост:
      у.роду:=Узел.уПост;
      у.a:=ОБХОД.Значение(ЦЕЛ,Разбор.вещЗнач);
      у.вид:=Данные.вещ32вид;
      ЧитатьСлово
  | Слово.цепьпост:
      пон:=Данные.СоздатьПостЦепь(Разбор.цепьЗнач);
      Узел.Создать(пон,у);
      ЧитатьСлово
  | Слово.пусто:
      у.роду:=Узел.уПост;
      у.вид:=Данные.пустовид;
      у.a:=0;
      ЧитатьСлово
  | Слово.лкругл:
      ЧитатьСлово;
      Выражение(у);
      ПропуститьСлово(Слово.пркругл)
  | Слово.лфигурн:
      ЧитатьСлово;
      Множество(у)
  | Слово.не:
      ЧитатьСлово;
      Множитель(у);
      Узел.Действие1(Слово.не,у)
  ИНАЧЕ
    Ошибка.Отметить(Ошибка.НЕВЕРНОЕ_НАЧАЛО_МНОЖИТЕЛЯ)
  КОН
КОН Множитель;

(******************************************************************************)
ЗАДАЧА Слагаемое(уа+:Узел.нВид);
ПЕР
  уб:Узел.нВид; 
  действие:ЦЕЛ;
УКАЗ
  Множитель(уа);
  ПОКА (Слово.умножить <= слово) И (слово <= Слово.и) ВЫП
    действие:=слово;
    ЕСЛИ действие = Слово.и ТО
      Узел.Действие1(Слово.и,уа)
    КОН;
    ЧитатьСлово;
    Множитель(уб);
    Узел.Действие(действие,уа,уб)
  КОН
КОН Слагаемое;

(******************************************************************************)
ЗАДАЧА ПростоеВыражение(уа+:Узел.нВид);
ПЕР
  уб:Узел.нВид;
  действие:ЦЕЛ;
УКАЗ
  ЕСЛИ (слово = Слово.минус) ИЛИ (слово = Слово.плюс) ТО
    действие:=слово;
    ЧитатьСлово;
    Слагаемое(уа);
    Узел.Действие1(действие,уа)
  ИНАЧЕ
    Слагаемое(уа)
  КОН;
  ПОКА (Слово.плюс <= слово) И (слово <= Слово.или) ВЫП
    действие:=слово;
    ЕСЛИ действие = Слово.или ТО
      Узел.Действие1(Слово.или,уа)
    КОН;
    ЧитатьСлово;
    Слагаемое(уб);
    Узел.Действие(действие,уа,уб)
  КОН
КОН ПростоеВыражение;

(******************************************************************************)
ЗАДАЧА Выражение(уа+:Узел.нВид);
ПЕР
  уб:Узел.нВид;
  действие:ЦЕЛ;
УКАЗ
  ПростоеВыражение(уа);
  ЕСЛИ (Слово.равно <= слово) И (слово <= Слово.бравно) ТО
    действие:=слово;
    ЕСЛИ уа.вид.родв = Данные.вКлюч ТО
      Узел.Действие1(действие,уа)
    КОН;
    ЧитатьСлово;
    ПростоеВыражение(уб);
    Узел.Действие(действие,уа,уб)
  АЕСЛИ слово = Слово.в ТО
    ЧитатьСлово;
    ПростоеВыражение(уб);
    Узел.ВМнож(уа,уб)
  АЕСЛИ слово = Слово.является ТО
    БудетСлово(Слово.название);
    ВКод.ОхранаВида(уа,НайтиПонятие(),ВКЛ)
  КОН
КОН Выражение;

(******************************************************************************)
ЗАДАЧА Выбрать;
ПЕР 
  табл:РЯД Настрой.ВсегоВыборов ИЗ НАБОР
                                        от,до,метка:ЦЕЛ
                                   КОН;
  от,до:ЦЕЛ; (* границы *)
  выборов:ЦЕЛ;
  метка,мОт,мДо,мТабл,мИначе,мКон:ЦЕЛ;
  у:Узел.нВид;
  i,j:ЦЕЛ;

 (*................................................подЗАДАЧА...*)
  ЗАДАЧА СписокМеток;
  ПЕР
    уот,удо:Узел.нВид;
    i:ЦЕЛ;
  УКАЗ
    КОЛЬЦО 
      ПостВыражение(уот);
      ЕСЛИ уот.вид.родв В Данные.множЦелых ТО
        ЕСЛИ уот.вид.родв > у.вид.родв ТО
          Ошибка.Отметить(Ошибка.НЕПРАВИЛЬНЫЙ_ВИД_МЕТКИ)
        КОН
      АЕСЛИ уот.вид.родв # у.вид.родв ТО
        Ошибка.Отметить(Ошибка.НЕПРАВИЛЬНЫЙ_ВИД_МЕТКИ)
      КОН;
      ЕСЛИ слово = Слово.дветочки ТО
        ЧитатьСлово;
        ПостВыражение(удо);
        ЕСЛИ (удо.вид.родв # уот.вид.родв) И НЕ ((уот.вид.родв В Данные.множЦелых) И (удо.вид.родв В Данные.множЦелых)) ТО
          Ошибка.Отметить(Ошибка.НЕПРАВИЛЬНЫЙ_ВИД_МЕТКИ)
        КОН;
        ЕСЛИ удо.a < уот.a ТО
          Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ПОСТОЯННАЯ)
        КОН
      ИНАЧЕ
        удо:=уот
      КОН;
      ЕСЛИ уот.a < от ТО от:=уот.a КОН;
      ЕСЛИ удо.a > до ТО до:=удо.a КОН;
      ЕСЛИ до-от >= Настрой.РазбросВыборов ТО
        Ошибка.Отметить(Ошибка.БОЛЬШОЙ_ВЫБОР)
      КОН;
      (* заносим отрезок в упорядоченную таблицу *)
      i:=выборов;
      ЕСЛИ i >= Настрой.ВсегоВыборов ТО
        Ошибка.Отметить(Ошибка.МНОГО_МЕТОК)
      КОН;
      КОЛЬЦО
        ЕСЛИ i = 0 ТО ВЫХОД КОН;
        ЕСЛИ табл[i-1].от <= удо.a ТО
          ЕСЛИ табл[i-1].до >= уот.a ТО
            Ошибка.Отметить(Ошибка.ПОВТОРНАЯ_МЕТКА)
          КОН;
          ВЫХОД
        КОН;
        табл[i]:=табл[i-1];
        УМЕНЬШИТЬ(i)
      КОН;
      табл[i].от:=уот.a;
      табл[i].до:=удо.a;
      табл[i].метка:=метка;
      УВЕЛИЧИТЬ(выборов);
      ЕСЛИ слово # Слово.запятая ТО ВЫХОД КОН;
      ЧитатьСлово
    КОН
  КОН СписокМеток;

УКАЗ
  Выражение(у);
  ЕСЛИ НЕ(у.вид.родв В Данные.множМеток) ТО
    Ошибка.Отметить(Ошибка.ВИД_ВЫБОРА)
  КОН;
  (* получим метки *)
  мОт:=Код.ПолучитьМетку();
  мДо:=Код.ПолучитьМетку();
  мТабл:=Код.ПолучитьМетку();
  мИначе:=Код.ПолучитьМетку();
  мКон:=Код.ПолучитьМетку();
  (* вызов по таблице *)
  ВКод.Выбрать(у,мОт,мДо,мТабл,мИначе);
  ПропуститьСлово(Слово.из);
  (* ветки *)
  от:=МАКС(ЦЕЛ);
  до:=МИН(ЦЕЛ);
  выборов:=0;
  КОЛЬЦО
    ЕСЛИ слово < Слово.черта ТО
      метка:=Код.ПолучитьМетку();
      СписокМеток;
      ПропуститьСлово(Слово.двоеточие);
Код.ПоставитьМетку(метка);
      Указания;
      Код.ПереходНа(мКон)
    КОН;
    ЕСЛИ слово # Слово.черта ТО ВЫХОД КОН;
    ЧитатьСлово
  КОН;
  ЕСЛИ выборов = 0 ТО
    Ошибка.Отметить(Ошибка.НЕТ_МЕТОК)
  КОН;
  Код.ЗначениеМетке(мОт,от);
  Код.ЗначениеМетке(мДо,до);
Код.ПоставитьМетку(мИначе);
  ЕСЛИ слово = Слово.иначе ТО
    ЧитатьСлово;
    Указания;
    Код.ПереходНа(мКон)
  ИНАЧЕ
    Код.Ловушка(Код.AL,Ядро.лВыбрать)
  КОН;
  (* вывод таблицы *)
  Код.СбросПост;
  Код.Примечание("Таблица переходов");
  Код.ПоставитьМетку(мТабл);
  i:=табл[0].от;
  ОТ j:=0 ДО выборов-1 ВЫП
    ПОКА i < табл[j].от ВЫП
      Код.ПоставитьАдресМетки(мИначе);
      УВЕЛИЧИТЬ(i)
    КОН;
    ПОКА i <= табл[j].до ВЫП
      Код.ПоставитьАдресМетки(табл[j].метка);
      УВЕЛИЧИТЬ(i)
    КОН
  КОН;
Код.ПоставитьМетку(мКон)
КОН Выбрать;

(******************************************************************************)
ЗАДАЧА ДляВида();
ПЕР 
  табл:РЯД Настрой.ВсегоВыборов ИЗ 
    НАБОР 
      вид:Данные.ДкВиду;
      метка:ЦЕЛ 
    КОН;
  выборов,i:ЦЕЛ;
  метка,мТабл,мИначе,мКон:ЦЕЛ;
  понп,понв:Данные.ДкПонятию;
  видп,видв:Данные.ДкВиду;
  виднп,виднв:Данные.ДкВиду;
  у:Узел.нВид;
УКАЗ
  ТекущееСлово(Слово.название);
  понп:=НайтиПонятие();
  ЕСЛИ НЕ (понп.родп В {Данные.пПер,Данные.пСсылка}) ТО
    Ошибка.Отметить(Ошибка.ЭТО_НЕ_ПЕРЕМЕННАЯ)
  КОН;
  Узел.Создать(понп,у);
  ПропуститьСлово(Слово.вида);
  видп:=понп.вид;
  ЕСЛИ видп.родв = Данные.вДоступ ТО
    виднп:=видп.овид
  ИНАЧЕ
    виднп:=видп
  КОН;
  (* получим метки *)
  мТабл:=Код.ПолучитьМетку();
  мИначе:=Код.ПолучитьМетку();
  мКон:=Код.ПолучитьМетку();
  (* вызов по таблице *)
  ВКод.ДляВида(у,мТабл);
  (* ветки *)
  выборов:=0;
  ПОВТОРЯТЬ
    ЕСЛИ слово = Слово.черта ТО ЧитатьСлово КОН;
    ТекущееСлово(Слово.название);
    понв:=НайтиПонятие();
    видв:=понв.вид;
    ЕСЛИ видв.родв = Данные.вДоступ ТО
      виднв:=видв.овид
    ИНАЧЕ
      виднв:=видв
    КОН;
    ВКод.ВозможнаОхрана(понп,понв);
    ПропуститьСлово(Слово.двоеточие);
    метка:=Код.ПолучитьМетку();
Код.ПоставитьМетку(метка);
    понп.вид:=видв; 
    Указания;
    понп.вид:=видп;
    Код.ПереходНа(мКон);
    табл[выборов].метка:=метка;
    табл[выборов].вид:=виднв;
    УВЕЛИЧИТЬ(выборов)
  ДО слово # Слово.черта;
  ЕСЛИ выборов = 0 ТО
    Ошибка.Отметить(Ошибка.НЕТ_МЕТОК)
  КОН;
Код.ПоставитьМетку(мИначе);
  ЕСЛИ слово = Слово.иначе ТО 
    ЧитатьСлово;
    Указания;
    Код.ПереходНа(мКон)
  ИНАЧЕ 
    Код.Ловушка(Код.AL,Ядро.лДля)
  КОН;
  (* вывод таблицы *)
  Код.СбросПост;
  Код.Примечание("Таблица УРВ(в)/ОВ(в)/переход");
  Код.ПоставитьМетку(мТабл);
  ОТ i:=0 ДО выборов-1 ВЫП
    виднв:=табл[i].вид;
    Код.ПоставитьЧисло(ВКод.УровеньРасширения(виднв));
    Код.ПоставитьАдресОВ(виднв);
    Код.ПоставитьАдресМетки(табл[i].метка)
  КОН;
  (* отбойник в конце таблицы *)
  Код.ПоставитьЧисло(ВКод.УровеньРасширения(виднп));
  Код.ПоставитьАдресОВ(виднп);
  Код.ПоставитьАдресМетки(мИначе);
Код.ПоставитьМетку(мКон)
КОН ДляВида;

(******************************************************************************)
ЗАДАЧА ПринимаемаяЗадача(задача:Данные.ДкПонятию);
(* читаем внешнее имя задачи и имя файла, содержащего эту задачу *)
ПЕР
  внешнееИмя:ДОСТУП К ЦЕПЬ;
  у:Узел.нВид;
УКАЗ
  (* внешнее имя задачи *)
  ЧитатьСлово;
  ПостВыражение(у);
  ЕСЛИ у.вид.родв = Данные.вЗнак ТО
    Узел.ЗнакВЦепь(у);
  КОН;
  ЕСЛИ НЕ ((у.вид.родв = Данные.вЦепь) И (у.пон.родп = Данные.пПост)) ТО
    Ошибка.Отметить(Ошибка.НЕ_СОВМЕСТИМО_С_ЗАДАЧЕЙ)
  КОН;
  внешнееИмя:=у.пон.достцепь;
  (* имя файла *)
  ПропуститьСлово(Слово.из);
  ПостВыражение(у);
  ЕСЛИ у.вид.родв = Данные.вЗнак ТО
    Узел.ЗнакВЦепь(у);
  КОН;
  ЕСЛИ НЕ ((у.вид.родв = Данные.вЦепь) И (у.пон.родп = Данные.пПост)) ТО
    Ошибка.Отметить(Ошибка.НЕ_СОВМЕСТИМО_С_ЗАДАЧЕЙ)
  КОН;
  ПропуститьСлово(Слово.точкасзап);
  (* отработка *)
  ВКод.ПринимаемаяЗадача(задача,внешнееИмя^,размерПриёмников)
КОН ПринимаемаяЗадача;

(******************************************************************************)
ЗАДАЧА ЗадачаВставка(задача:Данные.ДкПонятию; конИмя-:Ядро.Имя);
УКАЗ
  Код.ПоставитьИмя(задача);
  Обмен.НачалоВставки;
  ПОВТОРЯТЬ ДО СледующееСлово() = Слово.кон;
  Обмен.КонецВставки;
  БудетСлово(Слово.название);
  ЕСЛИ Разбор.имя # конИмя ТО
    Ошибка.Отметить(Ошибка.НЕСОВПАДЕНИЕ_ИМЕНИ)
  КОН;
  ЧитатьСлово;
  ПропуститьСлово(Слово.точкасзап)
КОН ЗадачаВставка;

(******************************************************************************)
ЗАДАЧА ОбъявлениеЗадачи;
ПЕР
  задача,заготовка:Данные.ДкПонятию;
  имя:Ядро.Имя;
  признаки:МНОЖ;
  стрелка,передаваемая,вложенная,быстрая:КЛЮЧ;
  былРазмерПриёмников,рПриёмников:ЦЕЛ;
УКАЗ
  рПриёмников:=0;
  задача:=ПУСТО;
  заготовка:=ПУСТО;
  вложенная:=Данные.уровень > 0;
  передаваемая:=ОТКЛ;
  быстрая:=ОТКЛ;
  ЕСЛИ слово = Слово.минус ТО
    ЧитатьСлово;
    передаваемая:=ВКЛ
  АЕСЛИ слово = Слово.умножить ТО
    ЧитатьСлово;
    быстрая:=ВКЛ
  КОН;
  стрелка:=ОТКЛ;
  ЕСЛИ слово = Слово.стрелка ТО
    ЧитатьСлово;
    стрелка:=ВКЛ
  КОН;
  ТекущееСлово(Слово.название);
  имя:=Разбор.имя;
  признаки:=Признаки();
  ЕСЛИ передаваемая ТО
    признаки:=признаки+{Данные.прПередаваемая}
  КОН;
  ЕСЛИ быстрая ТО
    признаки:=признаки+{Данные.прБыстрая}
  КОН;
  ЕСЛИ вложенная И ((Данные.прОбщедоступная В признаки) ИЛИ передаваемая) ТО
    Ошибка.Отметить(Ошибка.НУЖНО_0_УРОВЕНЬ)
  КОН;
  ЕСЛИ (Данные.прОбщедоступная В признаки) И НЕ (Данные.прНеизменяемая В признаки) ТО
    Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ОТМЕТКА)
  КОН;
  заготовка:=Данные.ИскатьПонятие(имя);
  ЕСЛИ (заготовка # ПУСТО) И (заготовка.обл # Данные.текОбласть) ТО
    заготовка:=ПУСТО
  КОН;
  ЕСЛИ заготовка # ПУСТО ТО
    ЕСЛИ (заготовка.родп # Данные.пЗадача) ИЛИ (Данные.прОбъявлена В заготовка.признаки) ТО
      Ошибка.ОтметитьИмя(Ошибка.ПЕРЕОПРЕДЕЛЕНИЕ,заготовка.имя)
    АЕСЛИ заготовка.признаки # признаки ТО
      Ошибка.Отметить(Ошибка.МЕТКА_НЕ_СОВПАДАЕТ)
    КОН;
    задача:=Данные.СоздатьПонятие()
  ИНАЧЕ
    задача:=Данные.Вставить(имя)
  КОН;
  задача.родп:=Данные.пЗадача;
  задача.вид:=Данные.нетвид;
  задача.признаки:=признаки;
  УВЕЛИЧИТЬ(Данные.уровень);
  Данные.ОткрытьОбласть(имя);
  ЕСЛИ слово = Слово.лкругл ТО (* есть приёмники *)
    ЧитатьСлово;
    рПриёмников:=Заголовок(задача.вид,вложенная,передаваемая,быстрая)
  АЕСЛИ вложенная И НЕ быстрая ТО
    рПриёмников:=4 (* для SL' *)
  КОН;
  задача.первпон:=Данные.текОбласть.первпон;
  Данные.текОбласть.видотв:=задача.вид;
  ЕСЛИ заготовка # ПУСТО ТО
    (* проверяем соответствие приёмников заготовки *)
    ВКод.СравнитьПриёмники(задача.первпон,заготовка.первпон);
    ЕСЛИ задача.вид # заготовка.вид ТО
      Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ЗАГОТОВКА)
    КОН;
    задача:=заготовка
  КОН;
  ПропуститьСлово(Слово.точкасзап);
  ЕСЛИ НЕ стрелка ТО
    задача.признаки:=задача.признаки+{Данные.прОбъявлена};
    былРазмерПриёмников:=размерПриёмников;
    размерПриёмников:=рПриёмников; 
    ЕСЛИ слово = Слово.код ТО
      ЗадачаВставка(задача,имя);
    АЕСЛИ слово = Слово.вызов ТО
      ЕСЛИ передаваемая ТО
        Ошибка.Отметить(Ошибка.НЕ_СОВМЕСТИМО_С_ЗАДАЧЕЙ)
      АЕСЛИ быстрая ТО
        Ошибка.Отметить(Ошибка.НЕ_СОВМЕСТИМО_С_БЫСТРОЙ)
      КОН;
      ПринимаемаяЗадача(задача)
    ИНАЧЕ
      ЕСЛИ быстрая ТО
        Данные.быстрая:=ВКЛ
      КОН;
      Объявления(задача,имя);
      ЕСЛИ быстрая ТО
        Данные.быстрая:=ОТКЛ
      КОН
    КОН;
    размерПриёмников:=былРазмерПриёмников
  КОН;
  Данные.ЗакрытьОбласть;
  УМЕНЬШИТЬ(Данные.уровень)
КОН ОбъявлениеЗадачи;

(******************************************************************************)
ЗАДАЧА Указания;
ПЕР
  естьДопПер:КЛЮЧ;
  рДопПер:ЦЕЛ;
  уа,уб,ув,уг:Узел.нВид;
  мИначе,мКон,мПока,мПовторять,мКольцо:ЦЕЛ; (* метки *)
УКАЗ
  КОЛЬЦО
    ВЫБРАТЬ слово ИЗ
    | Слово.название:
        Узел.Создать(НайтиПонятие(),уа);
        Переключатель(уа);
        ЕСЛИ слово = Слово.присвоить ТО
          ЧитатьСлово;
          ЕСЛИ уа.вид.родв = Данные.вОЦепь ТО (* исправить!! *)
            Ошибка.Отметить(Ошибка.НЕСОВМЕСТИМОЕ_ПРИСВАИВАНИЕ)
          КОН;
          Выражение(уб);
          ВКод.Присвоить(уа,уб)
        ИНАЧЕ
          Вызов(уа,ОТКЛ)
        КОН
    | Слово.если:
        ЧитатьСлово;
        Выражение(уа);
        мИначе:=Узел.ПереходПоОтклНа(уа);
        (* ВКЛ - сюда *)
        Рег.ОсвободитьВсеРОНы;
        ПропуститьСлово(Слово.то);
        Указания;
        мКон:=Код.ПолучитьМетку(); (* конец у ЕСЛИ *)
        ПОКА слово = Слово.аесли ВЫП
          ЧитатьСлово;
          Код.ПереходНа(мКон); (* конец пред. указаний *)
          Код.СбросПост;
Код.ПоставитьМетку(мИначе);
          Выражение(уа);
          мИначе:=Узел.ПереходПоОтклНа(уа);
          (* ВКЛ - сюда *)
          Рег.ОсвободитьВсеРОНы;
          ПропуститьСлово(Слово.то);
          Указания
        КОН;
        ЕСЛИ слово = Слово.иначе ТО
          ЧитатьСлово;
          Код.ПереходНа(мКон); (* конец пред. указаний *)
          Код.СбросПост;
Код.ПоставитьМетку(мИначе);
          Указания
        ИНАЧЕ
Код.ПоставитьМетку(мИначе)
        КОН;
Код.ПоставитьМетку(мКон);
        ПропуститьСлово(Слово.кон)
    | Слово.выбрать:
        ЧитатьСлово;
        Выбрать;
        ПропуститьСлово(Слово.кон)
    | Слово.пока:
        ЧитатьСлово;
        мПока:=Код.ПолучитьМетку();
Код.ПоставитьМетку(мПока);
        Выражение(уа);
        мКон:=Узел.ПереходПоОтклНа(уа);
        (* ВКЛ - сюда *)
        Рег.ОсвободитьВсеРОНы;
        ПропуститьСлово(Слово.вып);
        Указания;
        Код.ПереходНа(мПока);
Код.ПоставитьМетку(мКон);
        ПропуститьСлово(Слово.кон)
    | Слово.повторять:
        ЧитатьСлово;
        мПовторять:=Код.ПолучитьМетку();
Код.ПоставитьМетку(мПовторять);
        Указания;
        ПропуститьСлово(Слово.до);
        Выражение(уа);
        Узел.ПовторятьДо(уа,мПовторять)
    | Слово.от:
        ЧитатьСлово;
        ТекущееСлово(Слово.название);
        Узел.Создать(НайтиПонятие(),уа);
        Переключатель(уа);
        ЕСЛИ уа.роду В {Узел.уПост,Узел.уВид..Узел.уВстрЗадача} ТО
          Ошибка.Отметить(Ошибка.ЭТО_НЕ_ПЕРЕМЕННАЯ)
        АЕСЛИ НЕ (уа.вид.родв В Данные.множЦелых) ТО
          Ошибка.Отметить(Ошибка.УПР_НЕ_ЦЕЛАЯ)
        АЕСЛИ уа.толькочт ТО
          Ошибка.Отметить(Ошибка.ПЕР_ДЛЯ_ЧТЕНИЯ)
        КОН;
        уг:=уа;
        ПропуститьСлово(Слово.присвоить); 
        Выражение(уб);
        ВКод.Присвоить(уа,уб); 
        ПропуститьСлово(Слово.до); 
        ЕСЛИ Данные.быстрая ТО (* убыстрение *)
          (* может ответ нужен в доп. регистровой пер. *)
          рДопПер:=Рег.ЗанятьСледПер();
          Рег.Нужен(рДопПер)
        КОН;
        Выражение(уб);
        ЕСЛИ Данные.быстрая ТО (* убыстрение *)
          Рег.Нужен(-1)
        КОН;
        ЕСЛИ НЕ  (уа.вид.родв В Данные.множЦелых)
             ИЛИ (уб.вид.родв > уа.вид.родв) ТО
          Ошибка.Отметить(Ошибка.НЕСОВМЕСТИМОЕ_ПРИСВАИВАНИЕ)
        КОН;
        ЕСЛИ уб.роду # Узел.уПост ТО (* нужна дополнительная переменная *)
          ЕСЛИ Данные.быстрая ТО (* убыстрение *)
            Узел.ПеренестиВТребРег(уб,рДопПер)
          ИНАЧЕ
            ВКод.ВДопПер(уб)
          КОН;
          УВЕЛИЧИТЬ(кДопПер[кУровень]);
          естьДопПер:=ВКЛ
        ИНАЧЕ
          ЕСЛИ Данные.быстрая ТО (* убыстрение *)
            Рег.ОсвободитьПредПер
          КОН;
          естьДопПер:=ОТКЛ
        КОН;
        ЕСЛИ слово = Слово.по ТО
          ЧитатьСлово;
          ПостВыражение(ув);
          ЕСЛИ НЕ (ув.вид.родв В Данные.множЦелых) ИЛИ (ув.a = 0) ТО
            Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ПОСТОЯННАЯ)
          КОН
        ИНАЧЕ
          Узел.СоздатьЦелПост(ув,1)
        КОН;
        ув.вид:=уа.вид;
        мПока:=Код.ПолучитьМетку();
Код.ПоставитьМетку(мПока);
        уа:=уг;
        ЕСЛИ ув.a > 0 ТО
          Узел.Действие(Слово.мравно,уа,уб)
        АЕСЛИ ув.a < 0 ТО
          Узел.Действие(Слово.бравно,уа,уб)
        КОН;
        мКон:=Узел.ПереходПоОтклНа(уа);
        (* ВКЛ - сюда *)
        ПропуститьСлово(Слово.вып);
        Указания;
        ПропуститьСлово(Слово.кон);
        уа:=уг;
        Узел.Увеличить(уа,ув);
        Код.ПереходНа(мПока);
Код.ПоставитьМетку(мКон);
        ЕСЛИ естьДопПер ТО
          ВКод.УбратьДопПер(1);
          УМЕНЬШИТЬ(кДопПер[кУровень])
        КОН
    | Слово.кольцо:
        ЧитатьСлово;
        УВЕЛИЧИТЬ(кУровень);
        ЕСЛИ кУровень >= кУровней ТО
          Ошибка.Отметить(Ошибка.МНОГО_ВЛОЖЕНИЙ_КОЛЬЦО)
        КОН;
        мКольцо:=Код.ПолучитьМетку();
Код.ПоставитьМетку(мКольцо);
        кВыходы[кУровень]:=Код.ПолучитьМетку();
        кДопПер[кУровень]:=0;
        Указания;
        ПропуститьСлово(Слово.кон);
        Код.ПереходНа(мКольцо);
Код.ПоставитьМетку(кВыходы[кУровень]);
        УМЕНЬШИТЬ(кУровень)
    | Слово.для:
        ЧитатьСлово;
        ДляВида;
        ПропуститьСлово(Слово.кон)
    | Слово.выход:
        ЧитатьСлово;
        ЕСЛИ кУровень = 0 ТО
          Ошибка.Отметить(Ошибка.ВЫХОД_ВНЕ_КОЛЬЦА)
        КОН;
        ВКод.УбратьДопПер(кДопПер[кУровень]);
        Код.ПереходНа(кВыходы[кУровень])
    | Слово.возврат:
        ЧитатьСлово;
        ЕСЛИ слово < Слово.точкасзап ТО
          Выражение(уа);
          ВКод.Ответ(уа,Данные.текОбласть.видотв,Данные.быстрая)
        АЕСЛИ Данные.текОбласть.видотв.родв # Данные.вНет ТО
          Ошибка.Отметить(Ошибка.ПРИСВАИВАНИЕ_ОТВЕТУ)
        КОН;
        ВКод.Возврат(размерПриёмников,Данные.быстрая)
    ИНАЧЕ
    КОН;
    Рег.ОсвободитьВсеРОНы;
    ЕСЛИ (слово >= Слово.черта) И (слово <= Слово.до) ТО ВЫХОД КОН;
    ПропуститьСлово(Слово.точкасзап)
  КОН
КОН Указания;

(******************************************************************************)
ЗАДАЧА Объявления(задача:Данные.ДкПонятию; конИмя-:Ядро.Имя);
ПЕР
  вид,видоб:Данные.ДкВиду;
  пон,перв:Данные.ДкПонятию;
  у:Узел.нВид;
  размер:ЦЕЛ;
  имя:Ядро.Имя;
  признаки:МНОЖ;

  неопрВидД:ДкНеопрВиду;    (* доступ к виду НеопрВид = телу звена *)
(*неопрДоступ:ДкНеопрВиду;*)
     звеноД:ЧэргаСлеД.ДкЗвену_телоД;
(*   звено :Набор.Звено;  *)

  рДанных:ЦЕЛ;
УКАЗ
  рДанных:=0;

  ЧэргаСлеД.ОчиститьСписок(доступыКнеопрВидам);

  КОЛЬЦО
    ВЫБРАТЬ слово ИЗ
    | Слово.пост:
        ПОКА СледующееСлово() = Слово.название ВЫП
          имя:=Разбор.имя;
          признаки:=Признаки();
          ЕСЛИ Данные.прОбщедоступная В признаки ТО
            ЕСЛИ
                 (Данные.уровень > 0)
                ИЛИ
                 НЕ (Данные.прНеизменяемая В признаки)
            ТО
              Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ОТМЕТКА)
            КОН
          КОН;
          ПропуститьСлово(Слово.равно);
          ПостВыражение(у);

                 пон:=Данные.Вставить(имя);
                 пон.родп:=Данные.пПост;
                 пон.признаки:=признаки;
                 пон.вид:=у.вид;
                 пон.адр:=у.a;
          ЕСЛИ
               у.пон # ПУСТО
          ТО                         (* т.к. узел пропадает, сохраним цепочку *)
                 пон.достцепь:=у.пон.достцепь
          КОН;
          ТекущееСлово(Слово.точкасзап)
        КОН
    | Слово.вид:
        ПОКА СледующееСлово() = Слово.название ВЫП
          пон:=Данные.Вставить(Разбор.имя);
          пон.родп:=Данные.пВид;
          пон.вид:=Данные.нетвид;
          признаки:=Признаки();
          ЕСЛИ Данные.прОбщедоступная В признаки ТО
            ЕСЛИ
                 (Данные.уровень > 0)
                ИЛИ
                 НЕ (Данные.прНеизменяемая В признаки)
            ТО
              Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ОТМЕТКА)
            КОН
          КОН;
          пон.признаки:=признаки;
          ПропуститьСлово(Слово.равно);
          Вид(вид);
          пон.вид:=вид;
          ЕСЛИ вид.понвида = ПУСТО ТО
            вид.понвида:=пон
          КОН;
          ЕСЛИ
               вид.родв В {Данные.вНабор,Данные.вРяд}
          ТО
                                 (* доопределяем неопределённые ранее доступы *)
(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
                         звеноД:=ЧэргаСлеД.Дк1муЗвену(доступыКнеопрВидам);
            ПОКА
                         звеноД # ПУСТО
            ВЫП
              неопрВидД:=звеноД.телоД(ДкНеопрВиду);
              ЕСЛИ
              неопрВидД.имя = пон.имя
              ТО
              неопрВидД.вид.овид:=вид
              КОН;
                         звеноД:=звеноД.слеД
            КОН
          КОН;
          ТекущееСлово(Слово.точкасзап)
        КОН
    | Слово.пер:
        ПОКА СледующееСлово() = Слово.название ВЫП
          перв:=ПУСТО;
          КОЛЬЦО
            ТекущееСлово(Слово.название);
            пон:=Данные.Вставить(Разбор.имя);
            пон.признаки:=Признаки();
            ЕСЛИ (Данные.уровень > 0) И (Данные.прОбщедоступная В пон.признаки) ТО
              Ошибка.Отметить(Ошибка.НЕВЕРНАЯ_ОТМЕТКА)
            КОН;
            пон.родп:=Данные.пПер;
            пон.вид:=Данные.неопрвид;
            ЕСЛИ перв = ПУСТО ТО 
              перв:=пон 
            КОН;
            ЕСЛИ слово # Слово.запятая ТО ВЫХОД КОН;
            ЧитатьСлово
          КОН;
          ПропуститьСлово(Слово.двоеточие);
          Вид(видоб);
          ЕСЛИ видоб.родв В {Данные.вОРяд,Данные.вОЦепь,Данные.вОЯчейки} ТО
            Ошибка.Отметить(Ошибка.ОРЯД_НЕДОПУСТИМ)
          АЕСЛИ Данные.быстрая И 
            (видоб.родв В {Данные.вРяд,Данные.вЦепь,Данные.вНабор}) ТО
            Ошибка.Отметить(Ошибка.НЕ_СОВМЕСТИМО_С_БЫСТРОЙ)
          КОН;
          пон:=перв;
          ПОКА пон # ПУСТО ВЫП
            пон.вид:=видоб;
            размер:=видоб.размер;
            ЕСЛИ Данные.уровень = 0 ТО
              пон.признаки:=пон.признаки+{Данные.прТекущегоОтдела};
              Код.ПоставитьПер(пон)
            ИНАЧЕ
              пон.признаки:=пон.признаки+{Данные.прВложенная};
              ЕСЛИ Данные.быстрая ТО
                пон.признаки:=пон.признаки+{Данные.прБыстрая};
                пон.адр:=(размерПриёмников+рДанных) ДЕЛИТЬ 4;
                УВЕЛИЧИТЬ(рДанных,4)
              ИНАЧЕ                                           (* выравнивание *)
                УВЕЛИЧИТЬ(рДанных,размер);
                ЕСЛИ размер = 2 ТО
                  УВЕЛИЧИТЬ(рДанных,рДанных ОСТАТОК 2)
                АЕСЛИ размер >= 4 ТО
                  УВЕЛИЧИТЬ(размер,(-размер) ОСТАТОК 4);
                  УВЕЛИЧИТЬ(рДанных,(-рДанных) ОСТАТОК 4)
                КОН;
                пон.адр:=-рДанных
              КОН
            КОН;
            пон:=пон.след
          КОН;
          ТекущееСлово(Слово.точкасзап)
        КОН
    ИНАЧЕ
      ВЫХОД
    КОН 
  КОН;
  ЕСЛИ Данные.быстрая ТО
    Рег.ЗанятьПер((размерПриёмников+рДанных) ДЕЛИТЬ 4)
  КОН;
  ЕСЛИ Данные.уровень > 0 ТО
    УВЕЛИЧИТЬ(рДанных,(-рДанных) ОСТАТОК 4)
  КОН;
                           (* проверяем нет ли больше неопределённых доступов *)
(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
               звеноД:=ЧэргаСлеД.Дк1муЗвену(доступыКнеопрВидам);
  ПОКА
               звеноД # ПУСТО
  ВЫП
    неопрВидД:=звеноД.телоД(ДкНеопрВиду);
    ЕСЛИ
                                 Данные.неопрвид = неопрВидД.вид.овид
    ТО
      Ошибка.ОтметитьИмя(Ошибка.НЕСУЩЕСТВУЮЩИЙ_ВИД,неопрВидД.имя)
    КОН;
               звеноД:=звеноД.слеД
  КОН;
  ЧэргаСлеД.ОчиститьСписок(доступыКнеопрВидам);
                                                        (* начало кода отдела *)
  ЕСЛИ Данные.уровень = 0 ТО
    Код.Начало
  КОН;
                                                               (* свои задачи *)
  ПОКА слово = Слово.задача ВЫП
    ЕСЛИ Данные.быстрая ТО
      Ошибка.Отметить(Ошибка.НЕ_СОВМЕСТИМО_С_БЫСТРОЙ)
    КОН;
    ЧитатьСлово;
    ОбъявлениеЗадачи
  КОН;
                                                        (* начало кода задачи *)
  ЕСЛИ Данные.прПередаваемая В задача.признаки ТО
    ВКод.ПередаваемаяЗадача(задача)
  КОН;
  Код.ПоставитьИмя(задача);
  ВКод.Вход(рДанных,Данные.быстрая);
  ЕСЛИ (Данные.уровень = 0) И (Настрой.отдВид = Настрой.приложение) ТО
    Код.ЗапускПриложения
  КОН;
  ЕСЛИ слово = Слово.указ ТО
    ЧитатьСлово;
    Указания
  АЕСЛИ слово # Слово.кон ТО
    Ошибка.Отметить(Ошибка.ОЖИДАЕТСЯ_ЗАДАЧА_УКАЗ_КОН)
  КОН;
                                                         (* конец кода задачи *)
  ЕСЛИ
       (Данные.уровень = 0)
      И
       (Настрой.отдВид = Настрой.приложение)
  ТО
    ВКод.ОстановПриложения
  КОН;
  ВКод.Возврат(размерПриёмников,Данные.быстрая);
  ЕСЛИ Данные.быстрая ТО
    Рег.ОсвободитьВсеПер()
  КОН;
  Код.СбросПост;
  ПропуститьСлово(Слово.кон);
  ТекущееСлово(Слово.название);
  ЕСЛИ
       Разбор.имя # конИмя
  ТО
    Ошибка.Отметить(Ошибка.НЕСОВПАДЕНИЕ_ИМЕНИ)
  КОН;
  ЕСЛИ Данные.уровень = 0 ТО
    БудетСлово(Слово.точка)
  ИНАЧЕ
    БудетСлово(Слово.точкасзап);
    ЧитатьСлово
  КОН
КОН Объявления;

(******************************************************************************)
ЗАДАЧА
       Отдел-(  отдИмя-:Ядро.Имя;
              испИмена+:ЧэргаСлеД.нСписок;     (* список испИмена *)
          толькоСписок :КЛЮЧ);
ПЕР
     звеноД:ЧэргаСлеД.ДкЗвену_телоД;
(*   звено :Набор.Звено;  *)

  испИмя:Выражения.ДкИспИмя;  (* доступ к звену в списке испИмена *)

  пон:Данные.ДкПонятию;
  имя:Ядро.Имя;
  отдВид:ЦЕЛ;
(*                                                    см. РВ.отд
  пустаяЦепьД:Пустой.ДкЦепи; (* :ДОСТУП К ЦЕПЬ; *)
*)
  пусто:ДОСТУП К ЦЕПЬ;
УКАЗ
  Данные.уровень:=0;
  Данные.быстрая:=ОТКЛ;
                                                         (* переменные отдела *)
  размерПриёмников:=0;
  кУровень:=0;
  трРаботает:=ОТКЛ;
  трУровень:=0;
  оЦепьРазрешена:=0;
  трСостояние[0]:=трВкл;
                                                           (* свои переменные *)
  СОЗДАТЬ(пусто,"");

  ЧэргаСлеД.ОчиститьСписок(испИмена);
                                                           (* начинаем разбор *)
  Разбор.Открыть;
  БудетСлово(Слово.отдел);
  БудетСлово(Слово.название);
  ЕСЛИ отдИмя # Разбор.имя ТО 
    Ошибка.ОтметитьИмя(Ошибка.ОТДЕЛ_ОТЛИЧАЕТСЯ_ОТ_ФАЙЛА,Разбор.имя)
  КОН;
  ЧитатьСлово;
  ЕСЛИ слово = Слово.плюс ТО
    отдВид:=Настрой.приложение;

    СОЗДАТЬ(испИмя);
            испИмя.имя:="СРЕДА";
            испИмя.начСлова:=Разбор.начСлова;
            испИмя.путь:=срдМесто;

    (* создаём новое <звеноД> (с доступом к телоД=испИмя) внутри задачи ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(..)
                                                          и присоединяем это звено к концу списка звеньев *)
    ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(испИмена,испИмя);

    ЧитатьСлово
  АЕСЛИ слово = Слово.минус ТО
    отдВид:=Настрой.описание;
    ЧитатьСлово
  ИНАЧЕ
    отдВид:=Настрой.отдел
  КОН;
  ПропуститьСлово(Слово.точкасзап);
  ЕСЛИ
       слово = Слово.использует
  ТО
    ПОВТОРЯТЬ
      БудетСлово(Слово.название);
      СОЗДАТЬ(испИмя);
              испИмя.имя:=Разбор.имя;
              испИмя.начСлова:=Разбор.начСлова;
              испИмя.путь:=пусто;
      ЧитатьСлово;

      ЕСЛИ испИмя.имя = "СРЕДА" ТО
        испИмя.путь:=срдМесто
      АЕСЛИ слово = Слово.из ТО
        БудетСлово(Слово.цепьпост);
        испИмя.путь:=Разбор.цепьЗнач;
        ЧитатьСлово
      КОН;
      ЕСЛИ
            НЕ ((испИмя.имя = "СРЕДА")
          И 
            (отдВид = Настрой.приложение))
      ТО
        (* создаём новое <звеноД> (с доступом к телоД=испИмя) внутри задачи ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(..)
                                                          и присоединяем это звено к концу списка звеньев *)
        ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(испИмена,испИмя)
      КОН
    ДО слово # Слово.запятая;
    ПропуститьСлово(Слово.точкасзап)
  КОН;
  ЕСЛИ толькоСписок ТО
    Разбор.Закрыть;
    ВОЗВРАТ
  КОН;
                                                  (* готовим зависимые отделы *)
        Настрой.УстОтдел(отдИмя,отдВид);
         Данные.УстОтдел(отдИмя);
   Данные.ОткрытьОбласть(отдИмя);
                                             (* считываем используемые отделы *)
(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
             звеноД:=ЧэргаСлеД.Дк1муЗвену(испИмена);
  ПОКА
             звеноД # ПУСТО
  ВЫП                                                       (* преобразование  
                    телоД                    из ЧэргаСлеД.ДкПустомуНабору 
                          Выражения.ДкИспИмя <- ЧэргаСлеД.ДкПустомуНабору     *)
    испИмя :=звеноД.телоД(Выражения.ДкИспИмя);

    Данные.Использовать(испИмя.имя,испИмя.путь^);

             звеноД:=звеноД.слеД
  КОН;
                                    (* отдел *)
  пон:=Данные.Вставить(отдИмя);
  пон.родп:=Данные.пОтдел;
  пон.признаки:={Данные.прТекущегоОтдела};
  пон.вид:=Данные.нетвид;
  пон.первпон:=Данные.текОбласть.первпон;
                                    (* главная задача отдела и приложения *)
  ЕСЛИ
       отдВид = Настрой.приложение
  ТО
    имя:="Nachalo"
  ИНАЧЕ
    имя:=отдИмя;

    оЦепи.ДобавитьВКонецЗнак(имя,"!");
  КОН;

    пон:=Данные.Вставить(имя);
    пон.родп:=Данные.пЗадача;
    пон.признаки:={Данные.прОбщедоступная};
    пон.вид:=Данные.нетвид;
  ЕСЛИ
       отдВид = Настрой.приложение
  ТО
    пон.обл:=ПУСТО
  КОН;
                                                     (* начало выработки кода *)
  Код.Открыть();
  Объявления(пон,отдИмя);
  Код.Закрыть;
  ЕСЛИ
       Настрой.отдВид # Настрой.приложение
  ТО
    Данные.Сохранить
  КОН;
    Данные.ЗакрытьОбласть;

  ЕСЛИ
       трУровень > 0
  ТО
    Ошибка.Отметить(Ошибка.ТЕКСТОРЕЗ_НЕ_ОКОНЧЕН)
  КОН;
  Разбор.Закрыть
КОН Отдел;

(******************************************************************************)
ЗАДАЧА Тексторез;
ПЕР
  состояние:ЦЕЛ;
  трСлово:ЦЕЛ;
  условие:КЛЮЧ;
  у:Узел.нВид;
УКАЗ
  ЧитатьСлово;
  трСлово:=слово;
  ЧитатьСлово;
  ЕСЛИ
       (трСлово = Слово.если)
      ИЛИ
       (трСлово = Слово.аесли)
  ТО
    ПостВыражение(у);
    ЕСЛИ
         у.вид.родв # Данные.вКлюч
    ТО
      Ошибка.Отметить(Ошибка.ОЖИДАЕТСЯ_КЛЮЧ)
    КОН;
    ПропуститьСлово(Слово.то);
    условие:=у.a = 1
  КОН;
  ПропуститьСлово(Слово.умнб);
  состояние:=трСостояние[трУровень];
  ВЫБРАТЬ трСлово ИЗ
  | Слово.если:
      УВЕЛИЧИТЬ(трУровень);
      ЕСЛИ трУровень = трУровней ТО 
        Ошибка.Отметить(Ошибка.МНОГО_УРОВНЕЙ_ТЕКСТОРЕЗА) 
      КОН; 
      ЕСЛИ состояние = трВкл ТО
        ЕСЛИ условие ТО
          трСостояние[трУровень]:=трВкл
        ИНАЧЕ
          трСостояние[трУровень]:=трДоВкл
        КОН
      ИНАЧЕ
        трСостояние[трУровень]:=трОткл
      КОН
  | Слово.аесли:
      ЕСЛИ (состояние = трДоВкл) И условие ТО
        трСостояние[трУровень]:=трВкл
      АЕСЛИ состояние = трВкл ТО
        трСостояние[трУровень]:=трОткл
      КОН
  | Слово.иначе:
      ЕСЛИ состояние = трДоВкл ТО
        трСостояние[трУровень]:=трВкл
      АЕСЛИ состояние = трВкл ТО
        трСостояние[трУровень]:=трОткл
      КОН
  | Слово.кон:
      ЕСЛИ трУровень = 0 ТО 
        Ошибка.Отметить(Ошибка.ЛИШНИЙ_КОН_У_ТЕКСТОРЕЗА) 
      КОН; 
      УМЕНЬШИТЬ(трУровень)
  ИНАЧЕ     
    Ошибка.Отметить(Ошибка.ТЕКСТОРЕЗ_НЕ_ПОНИМАЕТ) 
  КОН; 
  ЕСЛИ
       трСостояние[трУровень] # трВкл
  ТО
    ПОКА слово # Слово.мумн ВЫП ЧитатьСлово КОН
  КОН
КОН Тексторез;

(******************************************************************************)
ЗАДАЧА Подготовить-(срдМесто-:ЦЕПЬ);
(*
 * Цель:  выставляет местоположение файла "СРЕДА.отд"
 * До:    <СрдМесто>  - местоположение файла "СРЕДА.отд"
 * После: <срдМесто^> - местоположение файла "СРЕДА.отд"
 * Прим:  вызывается только один раз до разбора всех файлов
 *)
УКАЗ
  СОЗДАТЬ(Выражения.срдМесто,срдМесто)
КОН Подготовить;

КОН Выражения.
