(*~\Глагол\ПриложенияLink\ПГ\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                              ОТДЕЛ РВ;
(*============================================================================*)
(* НАЗНАЧЕНИЕ: Разбор Выражений языка                                         *)
(*============================================================================*)

ИСПОЛЬЗУЕТ
        (*  \Глагол\              *)
  Пустой  ИЗ "..\..\Отделы\Иное\",
ЧэргаСлеД ИЗ "..\..\Отделы\Иное\",

  ВД,ПД,НП,РС,ОО,СС,ПЗ;

ПОСТ
                    (* Род понятий (нПонятие.родп). Из ВД. *)
  пОтдел     =0;
  пОбласть   =1;
  пВид       =2;
  пПост      =3;
  пПер       =4;
  пПрСсылки  =5;
  пЗадача    =6;
  пВстрЗадача=7;
  пСвойство  =8;
(*
  родп       | n адр   пост    след     область
  ============================================================================
  пОтдел     | 0                        верх    Отдел
  пОбласть   | 1 нстр                   первпер Область действия
  пВид       | 2                                Именованный вид
  пПост      | 3       val                      Постоянная
  пПер       | 4 адр           next             Переменная или приёмник значения
  пПрСсылки  | 5 vadr          next             Приемник переменной
  пЗадача    | 6 сно   sizes   firstpar область Задача
  пВстрЗадача| 7 fno   sizes                    Встроенная задача
  пСвойство  | 8 off           next             Свойство набора

  <сно> является номером в символьной таблице COFF (если <сно> <= 0, то это - адр для связки заготовок)
*)

                    (* Признаки понятия (нПонятие.признаки). Из ВД. *)
  прОбщедоступная=0;
  прНеизменяемая =1;
  прОбъявлена    =2;
  прВложенная    =3;
  прГоловная     =4;
  прПередаваемая =5;
(*
  прОбщедоступная- действует во всех отделах
  прНеизменяемая - только для чтения
  прОбъявлена    - для полностью объявленных задач
  прВложенная    - для вложенных задач
  прГоловная     - для задачи _Zapusk 
  прПередаваемая - для иноязычных приложений
*)

  (*                        Род видов (нВид.родв). Из ВД.
 Причём:
          вЯчейка <= вЦел8 <= вЗнак <= вЦел16 <= вЦел32 <= вЦел64.
   *)
  вНеопр  =0;
  вЯчейка =1;
  вКлюч   =2;
  вЗнак   =3;
  вЦел8   =4;
  вЦел16  =5;
  вЦел32  =6;
  вЦел64  =7;
  вВещ32  =8;
  вВещ64  =9;
  вМнож   =10;
  вПЦепь  =11;
  вПусто  =12;
  вНет    =13;
  вДоступ =14;
  вЗадача =15;
  вБегунок=16;
  вРяд    =17;
  вОРяд   =18;
  вНабор  =19;
  вКон    =20; (* вКон для ДВ. При изменении вКон нужно 3 преобразования с уборка:=ОТКЛ. *)
(*
  родв    | n          овид      след     вхнотд  адрОВ    текстп
  ===============================================================
  вНеопр  | 0
  вЯчейка | 1
  вКлюч   | 2
  вЗнак   | 3
  вЦел8   | 4
  вЦел16  | 5
  вЦел32  | 6
  вЦел64  | 7
  вВещ32  | 8
  вВещ64  | 9
  вМнож   | 10
  вПЦепь  | 11
  вПусто  | 12
  вНет    | 13
  вДоступ | 14         PBaseTyp           вхнотд           текстп
  вЗадача | 15         ResTyp    params   вхнотд           текстп
  вБегунок| 16 шаг     основание          вхнотд  адрОВ    текстп
  вРяд    | 17 nofel   ElemTyp            вхнотд           текстп
  вОРяд   | 18 dim     ElemTyp            вхнотд  lenoff   текстп
  вНабор  | 19         RBaseTyp  fields   вхнотд  адрОВ    текстп
*)

  множЦел={вЦел8..вЦел64};
  множВещ={вВещ32,вВещ64};

                   (* Род узлов (Узел.роду). Из ПД. *)
  Nvar      = 0;
  Nvarpar   = 1;
  Nfield    = 2;
  Nderef    = 3;
  Nindex    = 4;
  Nguard    = 5;
  Neguard   = 6;
  Nconst    = 7;
  Ntype     = 8;
  Nproc     = 9;
  Nupto     =10;
  Nmop      =11;
  Ndop      =12;
  NcallTuda =13;
  NcallSuda =14;
  Ncall     =15;
  Nif       =16;
  Ncaselse  =17;
  Ncasedo   =18;
  Nenter    =19;
  Nassign   =20;
  Nifelse   =21;
  Ncase     =22;
  Nwhile    =23;
  Nrepeat   =24;
  Nloop     =25;
  Nexit     =26;
  Nreturn   =27;
  Nwith     =28;
  Ntrap     =29;
                   (* Номера задач (нУзел.подроду). Из ПД. *)
  assign    = 0;
  зВЦел     = 1;
  зВШирЦел  = 2;
  зЧет      = 3;
  зВЗнак    = 4;
  зМодуль   = 5;
  зМин      = 6;
  зМакс     = 7;
  зУзк      = 8;
  зУвеличить= 9;
  зУменьшить=10;
  зСтоп     =11;
  зРазмер   =12;
  зДлина    =13;
  зСоздать  =14;
  зСписать  =15;
  зЗадано   =16;
  зПроверить=17;
  зПоставить=18;
  зСместить =19;
  зОбнулить =20; 
  зЦелЧасть =21;
                      (* Номера задач ОБХОД отдела (нУзел.подроду). Из ПД. *)
  зПолучитьАдрес=23;
  зИзПамяти     =24;
  зВПамять      =25;
  зЗначение     =26;
  зОбраз        =27;
  зОУзк         =28;

ПЕР
    слово:ЦЕЛ; (* текущее слово входного текста *)
  уровень:ЦЕЛ;
  уровеньКольца:ЦЕЛ;

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

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

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

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


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


ЗАДАЧА^ ОпределениеВида(видД+:ВД.ДкВиду);
ЗАДАЧА^ Выражение(x+:ПД.ДкУзлу);
ЗАДАЧА^ Сборка(задачи+,указания+:ПД.ДкУзлу; имясборки-:НП.Имя);
ЗАДАЧА^ Выбрать(x+:ПД.ДкУзлу);
ЗАДАЧА^ Тексторез;


(*=рррррррррррррррррррррррр= реализация задач =рррррррррррррррррррррррррррррр=*)


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

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

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

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

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

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

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

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

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

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

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

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

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

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

          ВД.НайтиСвойство(видД.овид,свво);

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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВидОткрРяд(видД+:ВД.ДкВиду);
УКАЗ
                  видД:=ВД.СоздатьВид(вОРяд);
  ОпределениеВида(видД.овид);
  ЕСЛИ            видД.овид.родв = вОРяд
  ТО
                  видД.n:=видД.овид.n+1
  ИНАЧЕ
                  видД.n:=0
  КОН
КОН ВидОткрРяд;

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

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

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

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

                       СОЗДАТЬ(неопрВидД);
                               неопрВидД.имя:=РС.имя;
                               неопрВидД.вид:=видД;

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

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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Переключатель(x+:ПД.ДкУзлу);
ПЕР
  пон:ВД.ДкПонятию;
    y:ПД.ДкУзлу;
УКАЗ
  КОЛЬЦО
    ВЫБРАТЬ слово ИЗ
      СС.лквадр:
        ЧитатьСлово;
        КОЛЬЦО
          ЕСЛИ (x.вид # ПУСТО) И (x.вид.родв = вДоступ) ТО
            ПД.DeRef(x)
          КОН;
          Выражение(y);
          ПД.Index(x,y);
          ЕСЛИ слово # СС.запятая ТО ВЫХОД КОН;
          ЧитатьСлово
        КОН;
        ПропуститьСлово(СС.прквадр)
    | СС.точка:
        БудетСлово(СС.название);
        ЕСЛИ x.вид = ПУСТО ТО
          ОО.Ошибка(ОО.ЭТО_НЕ_ВИД)
        КОН;
        ЕСЛИ x.вид.родв = вДоступ ТО
          ПД.DeRef(x)
        КОН;
        ЕСЛИ x.вид.родв # вНабор ТО
          ОО.Ошибка(ОО.ЭТО_НЕ_НАБОР)
        КОН;
        ВД.НайтиСвойство(x.вид,пон);
        ПД.Field(x,пон);
        ЧитатьСлово
    | СС.стрелка:
        ЧитатьСлово;
        ПД.DeRef(x)
    | СС.лкругл:
        ЕСЛИ (x.роду < Nconst) И (x.вид.родв # вЗадача) ТО
          БудетСлово(СС.название);
          УточнитьНазвание(пон);
          ЕСЛИ пон.родп # пВид ТО
            ОО.Ошибка(ОО.ЭТО_НЕ_ВИД)
          КОН;
          ПД.TypTest(x,пон,ВКЛ);
          ПропуститьСлово(СС.пркругл)
        ИНАЧЕ
          ВЫХОД
        КОН
    ИНАЧЕ
      ВЫХОД
    КОН
  КОН
КОН Переключатель;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВызовВстрЗадачи(прием0+:ПД.ДкУзлу);
ПЕР
  y:ПД.ДкУзлу;
  нз,всегоПр:ЦЕЛ;
УКАЗ
  всегоПр:=0;
  нз:=прием0.пон.адр;
  ПропуститьСлово(СС.лкругл);
  ЕСЛИ слово # СС.пркругл ТО
    КОЛЬЦО
      ЕСЛИ всегоПр = 0 ТО
        Выражение(прием0);
        ПД.StPar0(прием0,нз)
      АЕСЛИ всегоПр = 1 ТО
        Выражение(y);
        ПД.StPar1(прием0,y,нз)
      ИНАЧЕ
        Выражение(y);
        ПД.StParN(прием0,y,нз,всегоПр)
      КОН;
      УВЕЛИЧИТЬ(всегоПр);
      ЕСЛИ слово # СС.запятая ТО ВЫХОД КОН;
      ЧитатьСлово
    КОН
  КОН;
  ПропуститьСлово(СС.пркругл);
  ПД.StFct(прием0,нз,всегоПр)
КОН ВызовВстрЗадачи;

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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Множество(x+:ПД.ДкУзлу);
ПЕР
  y:ПД.ДкУзлу;
УКАЗ
  ЕСЛИ слово # СС.прфигурн ТО
    Элемент(x);
    ПОКА слово = СС.запятая ВЫП
      ЧитатьСлово;
      Элемент(y);
      ПД.Op(СС.плюс,x,y)
    КОН
  ИНАЧЕ
    x:=ПД.EmptySet()
  КОН;
  ПропуститьСлово(СС.прфигурн)
КОН Множество;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Множитель(x+:ПД.ДкУзлу);
ПЕР
  приём,пон:ВД.ДкПонятию;
  исток:ПД.ДкУзлу;
УКАЗ
  ВЫБРАТЬ слово ИЗ
  | СС.название:
      УточнитьНазвание(пон);
      x:=ПД.NewLeaf(пон);
      Переключатель(x);
      ЕСЛИ (x.роду = Nproc) И (x.пон.родп = пВстрЗадача) ТО
        ВызовВстрЗадачи(x)  (* x может быть ПУСТО *)
      АЕСЛИ слово = СС.лкругл ТО
        ЧитатьСлово;
        ПД.PrepCall(x,приём);
        Источники(исток,приём);
        ПД.Call(x,исток,приём);
        ПропуститьСлово(СС.пркругл)
      КОН
  | СС.знак:
      x:=ПД.NewIntConst(РС.целзнач); 
      x.вид:=ВД.знаквид;
      ЧитатьСлово
  | СС.целпост:
      x:=ПД.NewIntConst(РС.целзнач);
      ЧитатьСлово
  | СС.вещпост:
      x:=ПД.NewRealConst(РС.вещзнач,ВД.вещ32вид);
      ЧитатьСлово
  | СС.швещпост:
      x:=ПД.NewRealConst(РС.вещзнач,ВД.вещ64вид);
      ЧитатьСлово
  | СС.цепьпост:
      x:=ПД.NewString(РС.цепь);
      ЧитатьСлово
  | СС.пусто:
      x:=ПД.Nil();
      ЧитатьСлово
  | СС.лкругл:
      ЧитатьСлово;
      Выражение(x);
      ПропуститьСлово(СС.пркругл)
  | СС.лфигурн:
      ЧитатьСлово;
      Множество(x)
  | СС.не:
      ЧитатьСлово;
      Множитель(x);
      ПД.MOp(СС.не,x)
  ИНАЧЕ
    ОО.Ошибка(ОО.НЕВЕРНОЕ_НАЧАЛО_МНОЖИТЕЛЯ)
  КОН
КОН Множитель;

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

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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА
       Выражение(x+:ПД.ДкУзлу);
ПЕР
  y:ПД.ДкУзлу;
  пон:ВД.ДкПонятию;
  действ:ЦЕЛ;
УКАЗ
  ПростоеВыражение(x);
  ВЫБРАТЬ слово ИЗ
    СС.равно..СС.бравно:
      действ:=слово;
      ЧитатьСлово;
      ПростоеВыражение(y);
      ПД.Op(действ,x,y)
  | СС.в:
      ЧитатьСлово;
      ПростоеВыражение(y);
      ПД.In(x,y)
  | СС.является:
      БудетСлово(СС.название);
      УточнитьНазвание(пон);
      ЕСЛИ пон.родп # пВид ТО
        ОО.Ошибка(ОО.ЭТО_НЕ_ВИД)
      КОН;
      ПД.TypTest(x,пон,ОТКЛ)
  ИНАЧЕ
  КОН
КОН Выражение;

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

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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ПередаваемаяЗадача(x+,указания+:ПД.ДкУзлу;
                                  пон :ВД.ДкПонятию);
(*  Цель: создаёт новые приёмники в соответствии с внешними требованиями,
 *        создаёт подзадачу Глагола с первоначальными приёмниками и
 *        организует вызов подзадачи Глагола из первоначальной задачи
 *    До: <x>        - вложенные задачи
 *        <указания> - указания задачи
 *        <пон>      - понятие задачи
 * После: <x>        - подзадача
 *        <указания> - вызов подзадачи *)
ПЕР
  понп:ВД.ДкПонятию;       (* понятие подзадачи *)
  пзадача:ПД.ДкУзлу;       (* узел подзадачи *)
  приёмникиз:ВД.ДкПонятию; (* приёмники задачи *)
  приёмникип:ВД.ДкПонятию; (* приёмники подзадачи *)
  приёмникз:ВД.ДкПонятию;  (* приёмник задачи *)
  источники,источник,конисточник:ПД.ДкУзлу;
УКАЗ
  ЕСЛИ
       (прОбщедоступная В пон.признаки)
      И
       (НП.отдВид = НП.приложение)
  ТО
    ПЗ.ДобавитьПерЗадачу(пон.имя)
  КОН;
  приёмникип:=пон.след;
  (* переписываем задачу в новую подзадачу *)
  понп:=ВД.СоздатьПон();
  понп.родп:=пЗадача;
  понп.след:=приёмникип;
  понп.признаки:={прОбъявлена,прВложенная};
  понп.область:=пон.область;
  понп.вид:=пон.вид;
  понп.пост:=ВД.СоздатьПост();
  (* прицепим подзадачу ниже по правой ветви дерева понятий *)
  понп.имя:=пон.имя;
  понп.право:=пон.право;
  пон.право:=понп;
  (* об области задачи мы ничего не знаем *)
  ВД.ОткрытьОбласть(0);
  пон.область:=ВД.текОбласть;
  ВД.ЗакрытьОбласть;
  (* переписывание приёмников подзадачи в новые приёмники задачи
   * и построение из них обратного списка приёмников задачи и
   * прямого списка источников вызова подзадачи из задачи *)
  источники:=ПУСТО;
  приёмникиз:=ПУСТО;
  ПОКА приёмникип # ПУСТО ВЫП
    (* переписывание приёмника подзадачи в новый приёмник задачи *)
    приёмникз:=ВД.СоздатьПон();
    приёмникз^:=приёмникип^;
    (* добавляем приёмник задачи в начало списка приёмников задачи *)
    приёмникз.след:=приёмникиз;
    приёмникиз:=приёмникз;
    (* добавляем приёмник задачи в конец списка источников вызова подзадачи *)
    источник:=ПД.NewLeaf(приёмникз);
    источник.текстп:=ОО.текПоз;
    ЕСЛИ источники = ПУСТО ТО
      источники:=источник
    ИНАЧЕ
      конисточник.след:=источник
    КОН;
    конисточник:=источник;
    (* следующий приёмник подзадачи *)
    приёмникип:=приёмникип.след
  КОН;
  пон.след:=приёмникиз;
  (* подзадача с указаниями и вложенными задачами задачи *)
  ПД.Enter(x,указания,понп);
  (* вызов подзадачи в новых указаниях задачи *)
  пзадача:=ПД.СоздатьУзел(Nproc);
  пзадача.пон:=понп;
  указания:=ПД.СоздатьУзел(NcallSuda);
  указания.лево:=пзадача;
  указания.право:=источники;
  указания.текстп:=ОО.текПоз
КОН ПередаваемаяЗадача;
  
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ОбъявлениеЗадачи(x+:ПД.ДкУзлу);
ПЕР
  пон,
  загпон:ВД.ДкПонятию;
     имя:НП.Имя;

  признаки:МНОЖ;

  объявлениеЗаготовки,передаваемая:КЛЮЧ;

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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ЭтоКлюч(x+:ПД.ДкУзлу);
УКАЗ
  ЕСЛИ
       (x.роду = Ntype)
      ИЛИ
       (x.роду = Nproc)
  ТО
    ОО.Ошибка(ОО.ЗАДАЧИ_И_ВИДЫ_ЗАПРЕЩЕНЫ)
  АЕСЛИ
        x.вид.родв # вКлюч
  ТО
    ОО.Ошибка(ОО.ОЖИДАЕТСЯ_КЛЮЧ)
  КОН;
КОН ЭтоКлюч;

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

  упрпер,
  указание,
  y, z,
  исток,
  послед,
  последЕсли,
           s: ПД.ДкУзлу;

     поз:ОО.нТекстПоз;
  видпер:ВД.ДкВиду; (* вид переменной до применения ДЛЯ *)

  естьИначе:КЛЮЧ;
УКАЗ
  x:=ПУСТО;
  послед:=ПУСТО;
  КОЛЬЦО
    указание:=ПУСТО;
    ВЫБРАТЬ слово ИЗ
    | СС.название:
        УточнитьНазвание(пер);
        указание:=ПД.NewLeaf(пер);
        Переключатель(указание);
        ЕСЛИ слово = СС.присвоить ТО
          ЧитатьСлово;
          Выражение(y);
          ПД.Assign(указание,y)
        АЕСЛИ (указание.роду = Nproc) И (указание.пон.родп = пВстрЗадача) ТО
          ВызовВстрЗадачи(указание);
          ЕСЛИ (указание # ПУСТО) И (указание.вид # ВД.нетвид) ТО
            ОО.Ошибка(ОО.ОТВЕТ_НЕ_ИСПОЛЬЗОВАН)
          КОН
        ИНАЧЕ
          ПД.PrepCall(указание,приём);
          ЕСЛИ слово = СС.лкругл ТО
            ЧитатьСлово;
            Источники(исток,приём);
            ПропуститьСлово(СС.пркругл)
          ИНАЧЕ
            исток:=ПУСТО;
            ЕСЛИ приём # ПУСТО ТО
              ОО.Ошибка(ОО.МАЛО_ИСТОЧНИКОВ)
            КОН
          КОН;
          ПД.Call(указание,исток,приём);
          ЕСЛИ указание.вид # ВД.нетвид ТО
            ОО.Ошибка(ОО.ОТВЕТ_НЕ_ИСПОЛЬЗОВАН)
          КОН
        КОН;
        поз:=ОО.текПоз
    | СС.если:
        ЧитатьСлово;
        Выражение(указание);
        поз:=ОО.текПоз;
        ЭтоКлюч(указание);
        ПропуститьСлово(СС.то);
        Указания(y);
        ПД.Construct(Nif,указание,y);
        указание.текстп:=поз;
        последЕсли:=указание;
        ПОКА слово = СС.аесли ВЫП
          ЧитатьСлово;
          Выражение(y);
          поз:=ОО.текПоз;
          ЭтоКлюч(y);
          ПропуститьСлово(СС.то);
          Указания(z);
          ПД.Construct(Nif,y,z);
          y.текстп:=поз;
          ПД.Link(указание,последЕсли,y);
        КОН;
        ЕСЛИ слово = СС.иначе ТО
          ЧитатьСлово;
          Указания(y)
        ИНАЧЕ
          y:=ПУСТО
        КОН;
        ПД.Construct(Nifelse,указание,y);
        ПропуститьСлово(СС.кон);
        указание.конСтрока:=ОО.текПоз.строка;
        ПД.OptIf(указание);
        поз:=ОО.текПоз
    | СС.выбрать:
        ЧитатьСлово;
        поз:=ОО.текПоз;
        Выбрать(указание);
        ПропуститьСлово(СС.кон);
        указание.конСтрока:=ОО.текПоз.строка;
    | СС.пока:
        ЧитатьСлово;
        Выражение(указание);
        поз:=ОО.текПоз;
        ЭтоКлюч(указание);
        ПропуститьСлово(СС.вып);
        Указания(y);
        ПД.Construct(Nwhile,указание,y);
        ПропуститьСлово(СС.кон);
        указание.конСтрока:=ОО.текПоз.строка;
    | СС.повторять:
        ЧитатьСлово;
        Указания(указание);
        ПропуститьСлово(СС.до);
        Выражение(y);
        поз:=ОО.текПоз;
        ЭтоКлюч(y);
        ПД.Construct(Nrepeat,указание,y);
        указание.конСтрока:=ОО.текПоз.строка
    | СС.от:
        ЧитатьСлово;
        ТекущееСлово(СС.название);
        УточнитьНазвание(пер);
        упрпер:=ПД.NewLeaf(пер);
        Переключатель(упрпер);
        ЕСЛИ
                 (упрпер.роду >= Nconst)
        ТО
          ОО.Ошибка(ОО.ЭТО_НЕ_ПЕРЕМЕННАЯ)
        АЕСЛИ
              НЕ (упрпер.вид.родв В множЦел)
        ТО
          ОО.Ошибка(ОО.УПР_НЕ_ЦЕЛАЯ)
        АЕСЛИ
                  упрпер.толькочт
        ТО
          ОО.Ошибка(ОО.ПЕР_ДЛЯ_ЧТЕНИЯ)
        КОН;
        ПропуститьСлово(СС.присвоить); 
        Выражение(y); 
        поз:=ОО.текПоз;
        указание:=упрпер; 
        ПД.Assign(указание,y); 
        указание.текстп:=поз;
        ПД.Link(x,послед,указание);
        ПропуститьСлово(СС.до); 
        Выражение(y); 
        поз:=ОО.текПоз;
        ЕСЛИ y.роду # Nconst ТО
          ВД.Вставить("@@",допер); 
          допер.имя:="@до"; (* у всех одно имя *)
          допер.родп:=пПер; 
          допер.вид:=y.вид;
          (* добавляем <допер> к переменным области *)
          перы:=ВД.текОбласть.область;
          ЕСЛИ перы = ПУСТО ТО 
            ВД.текОбласть.область:=допер
          ИНАЧЕ
            ПОКА перы.след # ПУСТО ВЫП
              перы:=перы.след 
            КОН;
            перы.след:=допер
          КОН;
          указание:=ПД.NewLeaf(допер); 
          ПД.Assign(указание,y); 
          указание.текстп:=поз;
          ПД.Link(x,послед,указание);
          y:=ПД.NewLeaf(допер)
        КОН;
        ЕСЛИ слово = СС.по ТО 
          ЧитатьСлово; 
          ПостВыражение(z) 
        ИНАЧЕ 
          z:=ПД.NewIntConst(1) 
        КОН;
        поз:=ОО.текПоз; 
        указание:=упрпер; 
        ЕСЛИ z.пост.цел > 0 ТО 
          ПД.Op(СС.мравно,указание,y)
        АЕСЛИ z.пост.цел < 0 ТО 
          ПД.Op(СС.бравно,указание,y)
        ИНАЧЕ 
          ОО.Ошибка(ОО.НЕВЕРНАЯ_ПОСТОЯННАЯ)
        КОН;
        ПропуститьСлово(СС.вып); 
        Указания(s);
        y:=упрпер; 
        ПД.StPar1(y,z,зУвеличить); 
        y.текстп:=поз;
  (* в конец s вставляем у *)
        ЕСЛИ s = ПУСТО ТО 
          s:=y
        ИНАЧЕ 
          z:=s;
          ПОКА z.след # ПУСТО ВЫП 
            z:=z.след 
          КОН;
          z.след:=y
        КОН;
        ПропуститьСлово(СС.кон); 
        ПД.Construct(Nwhile,указание,s);
        указание.конСтрока:=ОО.текПоз.строка
    | СС.кольцо:
        ЧитатьСлово;
        УВЕЛИЧИТЬ(уровеньКольца);
        Указания(указание);
        УМЕНЬШИТЬ(уровеньКольца);
        ПД.Construct(Nloop,указание,ПУСТО);
        ПропуститьСлово(СС.кон);
        указание.конСтрока:=ОО.текПоз.строка;
        поз:=ОО.текПоз
    | СС.для:
        ЧитатьСлово;
        ТекущееСлово(СС.название);
        УточнитьНазвание(пер);
        видпер:=пер.вид;
        ПропуститьСлово(СС.вида);
        указание:=ПУСТО;
        ПОВТОРЯТЬ
          ЕСЛИ слово = СС.черта ТО ЧитатьСлово КОН;
          ТекущееСлово(СС.название);
          УточнитьНазвание(вид);
          ЕСЛИ вид.родп # пВид ТО
            ОО.Ошибка(ОО.ЭТО_НЕ_ВИД)
          КОН;
          y:=ПД.NewLeaf(пер);
          ПД.TypTest(y,вид,ОТКЛ);
          пер.вид:=вид.вид;
          ПропуститьСлово(СС.двоеточие);
          поз:=ОО.текПоз;
          Указания(s);
          ПД.Construct(Nif,y,s);
          y.текстп:=поз;
          пер.вид:=видпер;
          ЕСЛИ указание = ПУСТО ТО 
            указание:=y; 
            последЕсли:=указание
          ИНАЧЕ 
            ПД.Link(указание,последЕсли,y)
          КОН;
        ДО слово # СС.черта;
        естьИначе:=слово = СС.иначе;
        ЕСЛИ естьИначе ТО 
          ЧитатьСлово;
          Указания(s)
        ИНАЧЕ 
          s:=ПУСТО
        КОН;
        ПД.Construct(Nwith,указание,s);
        указание.толькочт:=естьИначе; (* запоминаем для работы исключений *)
        ПропуститьСлово(СС.кон);
        указание.конСтрока:=ОО.текПоз.строка
    | СС.выход:
        ЕСЛИ уровеньКольца = 0 ТО
          ОО.Ошибка(ОО.ВЫХОД_ВНЕ_КОЛЬЦА)
        КОН;
        ЧитатьСлово;
        ПД.Construct(Nexit,указание,ПУСТО);
        поз:=ОО.текПоз
    | СС.возврат:
        ЧитатьСлово;
        ЕСЛИ
              слово < СС.точкасзап
        ТО
           Выражение(указание)
        КОН;
        ПД.Return(указание,ВД.текОбласть.след);
        поз:=ОО.текПоз
    ИНАЧЕ
    КОН;
    ЕСЛИ
         указание # ПУСТО
    ТО
         указание.текстп:=поз;
      ПД.Link(x,послед,указание)
    КОН;
    ЕСЛИ
         (слово >= СС.черта)
        И
         (слово <= СС.до)
    ТО
      ВЫХОД
    КОН;
    ПропуститьСлово(СС.точкасзап)
  КОН
КОН Указания;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Выбрать(x+:ПД.ДкУзлу);
ПЕР
  рЗначВыбора:РЯД НП.ВсегоВыборов ИЗ НАБОР
                                          от,до:ЦЕЛ
                                     КОН;
  y,
        выборы,
  последвыбор,
  аб           :ПД.ДкУзлу;
          пост :ВД.ДкПост;
  выборов,
     родм :ЦЕЛ;
       от,
       до :ЦЕЛ;

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

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

УКАЗ
  Выражение(x);
  родм:=x.вид.родв;
  ЕСЛИ (x.роду = Ntype) ИЛИ (x.роду = Nproc) ТО
    ОО.Ошибка(ОО.ЗАДАЧИ_И_ВИДЫ_ЗАПРЕЩЕНЫ)
  АЕСЛИ НЕ (родм В множЦел + {вЗнак}) ТО
    ОО.Ошибка(ОО.ВИД_ВЫБОРА)
  КОН;
  ПропуститьСлово(СС.из);
  выборы:=ПУСТО;
  последвыбор:=ПУСТО;
  выборов:=0;
  КОЛЬЦО
    ЕСЛИ слово < СС.черта ТО
      СписокМеток;
      ПропуститьСлово(СС.двоеточие);
      Указания(y);
      ПД.Construct(Ncasedo,аб,y);
      ПД.Link(выборы,последвыбор,аб)
    КОН;
    ЕСЛИ слово # СС.черта ТО ВЫХОД КОН;
    ЧитатьСлово
  КОН;
  ЕСЛИ выборов = 0 ТО
    ОО.Ошибка(ОО.НЕТ_МЕТОК)
  КОН;
  от:=рЗначВыбора[0        ].от;
  до:=рЗначВыбора[выборов-1].до;
  ЕСЛИ
       до-от > НП.РазбросВыборов
  ТО
    ОО.Ошибка(ОО.БОЛЬШОЙ_ВЫБОР)
  КОН;
  пост:=ВД.СоздатьПост();
  пост.цел1:=от;
  пост.цел2:=до;
  ЕСЛИ
       слово = СС.иначе
  ТО
    ЧитатьСлово;
    Указания(y);
    пост.множ:={1}
  ИНАЧЕ
    y:=ПУСТО;
    пост.множ:={}
  КОН;
  ПД.Construct(Ncaselse,выборы,y);
  ПД.Construct(Ncase,x,выборы);
  выборы.пост:=пост
КОН Выбрать;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Сборка(  задачи+,
              указания+ :ПД.ДкУзлу;
             имясборки- :НП.Имя);
ПЕР
  видД  :ВД.ДкВиду;

  пон,
  перв,
  послед:ВД.ДкПонятию;

  y,
  последзадача:ПД.ДкУзлу;

           имя:НП.Имя;
      признаки:МНОЖ;

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

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

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

          ОпределениеВида(пон.вид);

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

                                   (* для обработки ошибок и имён вложенных задач *)
  ВД.текОбласть.адр:=ОО.текПоз.строка;

        задачи:=ПУСТО;
  последзадача:=ПУСТО;
  ПОКА
       слово = СС.задача
  ВЫП
    ЧитатьСлово;
    ОбъявлениеЗадачи(y);
    ЕСЛИ y # ПУСТО ТО
      ЕСЛИ последзадача = ПУСТО ТО
        задачи:=y
      ИНАЧЕ
        последзадача.след:=y
      КОН;
      последзадача:=y
    КОН;
    ПропуститьСлово(СС.точкасзап)
  КОН;

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

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Отдел-(x+:ПД.ДкУзлу);
ПЕР
    запуск:ВД.ДкПонятию;
  указания:ПД.ДкУзлу;
       поз:ОО.нТекстПоз;
    отдВид:ЦЕЛ;
    отдИмя:НП.Имя;
   предИмя:НП.Имя;
   предПуть,
          пустаяЦепьД:ДОСТУП К ЦЕПЬ; (* :Пустой.ДкЦепи; *)
УКАЗ
  СОЗДАТЬ(пустаяЦепьД,"");
  БудетСлово(СС.отдел);
  БудетСлово(СС.название);
  отдИмя:=РС.имя;

  ЧитатьСлово;
  ЕСЛИ
        слово = СС.плюс
  ТО
    отдВид:=НП.приложение;
    ЧитатьСлово
  АЕСЛИ
        слово = СС.минус
  ТО
    отдВид:=НП.описание;
    ЧитатьСлово
  ИНАЧЕ
    отдВид:=НП.отдел
  КОН;
  ПропуститьСлово(СС.точкасзап);

  ВД.УстОтдел(отдИмя);
  ЕСЛИ
       отдВид=НП.приложение
  ТО
    ВД.Использовать("СРЕДА",срдМесто^)
  КОН;
  ЕСЛИ слово = СС.использует ТО
    ПОВТОРЯТЬ
      БудетСлово(СС.название);
      предПуть:=пустаяЦепьД;
           предИмя:=РС.имя;
      ЕСЛИ
            предИмя = "ОБХОД"
      ТО
        ЧитатьСлово
      ИНАЧЕ
        ЧитатьСлово;
        ЕСЛИ
            предИмя = "СРЕДА"
        ТО
          предПуть:=срдМесто;
          ЧитатьСлово
        АЕСЛИ
              слово = СС.из
        ТО
          БудетСлово(СС.цепьпост);
          предПуть:=РС.цепь;
          ЧитатьСлово
        КОН
      КОН;
      ВД.Использовать(предИмя,предПуть^)
    ДО слово # СС.запятая;
    ПропуститьСлово(СС.точкасзап)
  КОН;
  НП.УстОтдел(отдИмя,отдВид);

  уровеньКольца:=0;
  уровень:=0;

  ВД.Вставить(отдИмя,запуск);
  ВД.текОбласть.след:=запуск;
  запуск.область:=ВД.текОбласть;
  запуск.признаки:={прГоловная,прОбъявлена};
  запуск.родп:=пОтдел;
  запуск.вид:=ВД.нетвид;
  запуск.пост:=ВД.СоздатьПост();
  поз:=ОО.текПоз;

  Сборка(x,указания,отдИмя);

  запуск.имя:="_Zapusk";
                                 (* область, в которой будет задача "_Zapusk" *)
  ВД.ОткрытьОбласть(0);
  запуск.область:=ВД.текОбласть;
  ВД.ЗакрытьОбласть;

  ПД.Enter(x,указания,запуск);
  ЕСЛИ
       указания # ПУСТО
  ТО 
    x.текстп:=указания.текстп
  ИНАЧЕ
    x.текстп:=поз
  КОН;
  x.конСтрока:=ОО.текПоз.строка;
  ТекущееСлово(СС.точка);
  ЕСЛИ
       трУровень > 0
  ТО
    ОО.Ошибка(ОО.ТЕКСТОРЕЗ_НЕ_ОКОНЧЕН)
  КОН;
  РС.Завершить
КОН Отдел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       НайтиИспИмена-(отдИмя-:НП.Имя;
                    испИмена+:ЧэргаСлеД.нСписок   (* доступ к списку испИмена *)
                     );
ПЕР
  испИмяД:РВ.ДкИспИмя;        (* доступ к испИмя = телу звена списка испИмена *)
   отдВид:ЦЕЛ;

          пустаяЦепьД:Пустой.ДкЦепи; (* :ДОСТУП К ЦЕПЬ; *)
УКАЗ
  СОЗДАТЬ(пустаяЦепьД,"");

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

  БудетСлово(СС.отдел);
  БудетСлово(СС.название);
  ЕСЛИ 
       отдИмя # РС.имя
  ТО 
    ОО.Отметить(ОО.ОТДЕЛ_ОТЛИЧАЕТСЯ_ОТ_ФАЙЛА,РС.имя)
  КОН;
  ЧитатьСлово;
  ЕСЛИ
        слово = СС.плюс
  ТО
    отдВид:=НП.приложение;
    СОЗДАТЬ(испИмяД);
    испИмяД.имя:="СРЕДА";
    испИмяД.поз:=ОО.текПоз;
    испИмяД.путь:=срдМесто;

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

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

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

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Подготовить-;
УКАЗ
  трРаботает:=ОТКЛ;
  трУровень:=0;
  трСостояние[0]:=трВкл
КОН Подготовить;

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

КОН РВ.
