Program SkanAnaliz;
 Uses
  Crt;
 Const
  Number : Set of Char = ['0'..'9'];
  Letter : Set of Char = ['a'..'z'];
  Symbol : Set of Char = ['(',')','[',']','{','}',':',';',','
                         ,'+','-','=','*','/','<','>','"',#39];
  KolCom = 30;
  KolSymT= 200;
  KolRuS = 50;
  Com    : Array [1..KolCom] of String[15]=('var','byte','integer','char',
           'word','array','begin','end','for','if','then','else','write',
           'endfor','endif','to','do','and','or','xor','read','writeln',
           'beginc','case','endc','endcase','endelse','of','endvar',
           'equal');
 Type
  Ident  = Record
            NameI  : String[25];
            ArrT   : 0..1;
            KolArr : 1..100;
            Tip    : 1..4;
           End;

 Var
  FName, FNameSk, FNameCom : String;
  PrFile, SkFile           : Text;
  ComFile                  : File of Byte;
  StrF, Str1               : String;
  SymStrF                  : Char;
  TabRuS                   : Array [1..KolRuS] of String;
  NRuS                     : 0..KolRuS;
  TabN                     : Array [1..KolSymT] of LongInt;
  TabTN                    : Array [1..KolSymT] of 1..4;
  TabI                     : Array [1..KolSymT] of Ident;
  NN, NI, N                : 0..KolSymT;
  N2Byte                   : Integer;
  N2Str                    : Integer;
  j, x                     : Byte;
  Ch1, Ch2                 : Char;
  FObjav, FTelo            : Boolean;
  FEndVar                  : Boolean;
  FIf                      : Boolean;
  Min                      : Boolean;
  StrX                     : String;
  TVyr, T                  : 1..4;
  Zn                       : Char;
  AddrI                    : Array [1..KolSymT] of Word;
  AddrK                    : Array [1..KolRuS] of Word;
{-------------------- Skaner ------------------}
 Procedure PreobrN;
  Var
   StrN  : String[15];
   i     : Byte;
   NCh   : 1..KolSymT;
   Ch    : Integer;
   Code  : Integer;
   FlTab : Boolean;
  Begin
   FlTab:=False;
   i:=1;
   StrN:='';
   While (StrF[1] in Number) and (StrF<>'') do
    Begin
     StrN:=StrN+StrF[1];
     i:=i+1;
     Delete(StrF,1,1);
    End;
   Val(StrN,Ch,Code);
   For i:=1 to NN do
    If TabN[i]=Ch
     then begin
           FlTab:=True;
           NCh:=i;
          end;
   If FlTab=False
    then begin
          NN:=NN+1;
          NCh:=NN;
          TabN[NCh]:=Ch;
         end;
   StrN:='';
   Write(SkFile, 'n',Chr(NCh));
  End;
 Procedure Error(kk : Integer); Forward;
 Procedure PreobrL;
  Var
   StrL    : String[15];
   Ss, Sss : String[25];
   i, j    : Byte;
   NCh     : 1..KolSymT;
   FlTab   : Boolean;
   FlArr   : Boolean;
  Begin
   FlArr:=False;
   FlTab:=False;
   i:=1;
   StrL:='';
   Ss:='.........................';
   Sss:='.........................';
   While ((StrF[1] in Letter) or (StrF[1] in Number))
         and (StrF<>'') do
    Begin
     StrL:=StrL+StrF[1];
     i:=i+1;
     Delete(StrF,1,1);
    End;
   For i:=1 to NI do
    If TabI[i].NameI=StrL
     then begin
           FlTab:=True;
           NCh:=i;
           Write(SkFile, 'i',Chr(NCh));
          end;
   If FlTab=False
    then begin
          For i:=1 to KolCom do
           If StrL=Com[i]
            then begin
                  FlTab:=True;
                  NCh:=i;
                  Write(SkFile, 'c',Chr(NCh));
                  i:=KolCom;
                  If StrL=Com[29] then FEndVar:=True;
                 end;
         end;
   If FlTab=False
    then begin
          NI:=NI+1;
          NCh:=NI;
          TabI[NCh].NameI:=StrL;
          Write(SkFile, 'i',Chr(NCh));
          If not FEndVar then
           begin
            Ss:=StrF;
            While Length(Ss)>0 do
             If Ss[1]=':'
              then begin
               While not (Ss[1] in Letter) do
                Delete(Ss,1,1);
               j:=1;
               While (Length(Ss)>0) and (Ss[1]<>';') do
                If Ss[1]<>' '
                 then begin
                  Sss[j]:=Ss[1];
                  Delete(Ss,1,1);
                  j:=j+1;
                 end
                 else If Ss[2]='['
                       then begin
                        TabI[NCh].ArrT:=1;
                        Sss[j]:=Ss[1];
                        Delete(Ss,1,1);
                        j:=j+1;
                        FlArr:=True;
                       end
                       else If Ss[2] in Letter
                             then If FlArr
                                   then begin
                                    Sss[j]:=Ss[1];
                                    Delete(Ss,1,1);
                                    j:=j+1;
                                   end
                                   else Error(0);
               Delete(Sss,j,Length(Sss)-j+1);
              end
              else Delete(Ss,1,1);
           end;
         end;
   StrL:='';
  End;
 Procedure PreobrS;
  Var
   StrRuS : String;
   i      : Byte;
   FlS    : Boolean;
  Begin
   i:=1;
   StrRuS:='';
   While (StrF[1] in Symbol) and (StrF<>'') do
    Begin
     If StrF[1]='"'
      then begin
       Write(SkFile, 's',StrF[1]);
       Delete(StrF,1,1);
       While (StrF[1]<>'"') and (StrF<>'') do
        begin
         StrRuS:=StrRuS+StrF[1];
         Delete(StrF,1,1);
        end;
       NRuS:=NRuS+1;
       TabRuS[NRuS]:=StrRuS;
       N2Str:=N2Str+Length(StrRuS)+1;
       StrRuS:='';
       i:=1;
       Write(SkFile, 'k',Chr(NRuS))
      end;
     If StrF[1]=';'
      then Delete(StrF,2,Length(StrF)-1);
     Write(SkFile, 's',StrF[1]);
     Delete(StrF,1,1);
    End;
  End;
{-------------------- Errors ------------------}
 Procedure Error(kk : Integer);
  Var
   j : Byte;
  Begin
   TextColor(LightGray);
   Case kk of
    0 : Begin
         WriteLn('Ошибка : Неизвестный символ');
         For j:=1 to Length(Str1) do
          If Str1[j]<>StrF[1]
           then Write(Str1[j])
           else begin
            TextColor(Yellow);
            Write(Str1[j]);
            TextColor(LightGray);
           end;
        End;
    1 : WriteLn('Ошибка : Где var ?');
    2 : WriteLn('Ошибка : Где begin ?');
    3 : WriteLn('Ошибка : Где Ваши переменные ?');
    4 : WriteLn('Ошибка : Объявление переменных !');
    5 : WriteLn('Ошибка : Где тип данных ?');
    6 : WriteLn('Ошибка : Поставьте ; !');
    7 : WriteLn('Ошибка : Поставьте [ !');
    8 : WriteLn('Ошибка : Укажите размер массива !');
    9 : WriteLn('Ошибка : Поставьте ] !');
    10: WriteLn('Ошибка : Поставьте of !');
    11: WriteLn('Ошибка : Где операторы ?');
    12: WriteLn('Ошибка : Где переменная ?');
    13: WriteLn('Ошибка : Поставьте = !');
    14: WriteLn('Ошибка : Поставьте { !');
    15: WriteLn('Ошибка : Поставьте to !');
    16: WriteLn('Ошибка : Поставьте do !');
    17: WriteLn('Ошибка : Поставьте ( !');
    18: WriteLn('Ошибка : Поставьте { (выражение) или " (строка) !');
    19: WriteLn('Ошибка : Поставьте " !');
    20: WriteLn('Ошибка : Поставьте ) !');
    21: WriteLn('Ошибка : Поставьте : !');
    22: WriteLn('Ошибка : Поставьте , !');
    23: WriteLn('Ошибка : Где знак сравнения ?');
    24: WriteLn('Ошибка : Где логическая функция или endif ?');
    25: WriteLn('Ошибка : Где if ?');
    26: WriteLn('Ошибка : Несоответствие типов !');
    27: WriteLn('Ошибка : Это не выражение !');
    28: WriteLn('Ошибка : Поставьте число !');
    29: WriteLn('Ошибка : Поставьте ) !');
    30: WriteLn('Ошибка : Поставьте + или - !');
    31: WriteLn('Ошибка : Поставьте * или / !');
    32: WriteLn('Ошибка : Структура слишком большая !');
   End;
   j:=0;
   TextColor(Yellow);
   While (not EOF(SkFile)) and (j<10) do
    begin
     Case Ch1 of
      'c' : Write(Com[Ord(Ch2)],' ');
      's' : Write(Ch2);
      'i' : Write(TabI[Ord(Ch2)].NameI);
      'n' : Write(TabN[Ord(Ch2)]);
      'k' : Write(TabRuS[Ord(Ch2)]);
     End;
     Read(SkFile, Ch1, Ch2);
     j:=j+1;
    end;
   GoToXY(1,2);
   TextColor(LightGray);
   Halt;
  End;
{------------------- Analiz -------------------}
Procedure Type1;
 Begin
 If (Ch1='c') and
    ((Ch2=Chr(2)) or (Ch2=Chr(3)) or (Ch2=Chr(4)) or (Ch2=Chr(5)))
   then begin
    Case Ord(Ch2) of
     2 : TabI[N].Tip:=1;
     3 : TabI[N].Tip:=2;
     4 : TabI[N].Tip:=4;
     5 : TabI[N].Tip:=3;
    End;
    Read(SkFile, Ch1, Ch2);
    If (Ch2<>';')
     then Error(6)
     else begin
      Read(SkFile, Ch1, Ch2);
      If Ch1<>'c'
       then If Ch1='i'
             then N:=Ord(Ch2)
             else Error(3);
     end;
   end
   else Error(5);
 End;
Procedure Type0;
 Begin
  If Ch2=Chr(6)
   then begin
    TabI[N].ArrT:=1;
    Read(SkFile, Ch1, Ch2);
    If (Ch2<>'[')
     then Error(7)
     else Read(SkFile, Ch1, Ch2);
    If Ch1<>'n'
     then Error(8)
     else begin
      TabI[N].KolArr:=TabN[Ord(Ch2)];
      AddrI[N]:=N2Byte+$100+12;
      N2Byte:=N2Byte+TabN[Ord(Ch2)]*2;
      Read(SkFile, Ch1, Ch2);
     end;
    If (Ch2<>']')
     then Error(9)
     else Read(SkFile, Ch1, Ch2);
    If (Ch1<>'c') or (Ch2<>Chr(28))
     then Error(10)
     else Read(SkFile, Ch1, Ch2);
    Type1;
   end
   else begin
    AddrI[N]:=N2Byte+$100+12;
    N2Byte:=N2Byte+2;
    Type1;
   end;
 End;
Procedure Perem;
 Begin
  While (Ch1<>'c') and (Ch2<>Chr(29)) do
   begin
    Read(SkFile, Ch1, Ch2);
    If (Ch2<>':')
     then Error(4);
    Read(SkFile, Ch1, Ch2);
    If Ch1<>'c'
     then Error(5)
     else Type0;
   end;
 End;
Procedure Objavlenie;
 Begin
  Read(SkFile, Ch1, Ch2);
  If Ch1<>'i'
   then Error(3)
   else begin
    N:=Ord(Ch2);
    Perem;
   end;
 End;
Procedure OpredTyp;
 Begin
  If Ch1='n'
   then begin
    If (TabN[Ord(Ch2)]>=0) and (TabN[Ord(Ch2)]<=255)
     then TabTN[Ord(Ch2)]:=1
     else If (TabN[Ord(Ch2)]>=0) and (TabN[Ord(Ch2)]<=65535)
           then TabTN[Ord(Ch2)]:=3
           else If (TabN[Ord(Ch2)]>=-32768) and (TabN[Ord(Ch2)]<=32767)
                 then TabTN[Ord(Ch2)]:=2
                 else Error(32);
    If (TabTN[Ord(Ch2)]=3) and (TabN[Ord(Ch2)]<32767)
     then Min:=True;
   end;
 End;
Procedure Vyrazhenie; ForWard;
Procedure ImYach;
 Begin
  OpredTyp;
  If Ch1='i' then
   If TabI[Ord(Ch2)].ArrT=1
    then begin
     Read(SkFile, Ch1, Ch2);
     If Ch2<>'['
      then Error(7);
     Read(SkFile, Ch1, Ch2);
     If Ch2<>'{'
      then Error(14);
     Vyrazhenie;
     Read(SkFile, Ch1, Ch2);
     If Ch2<>']'
      then Error(9);
    end;
 End;
Procedure PrZU;
 Begin
  If (StrX[x]='*') or (StrX[x]='/')
   then x:=x+1
   else Error(31);
  If StrX[x-1]<>'}' then Zn:=StrX[x-1];
 End;
Procedure PrZS;
 Begin
  If (StrX[x]='+') or (StrX[x]='-')
   then x:=x+1
   else Error(30);
  If StrX[x-1]<>'}' then Zn:=StrX[x-1];
 End;
Procedure PrE; Forward;
Procedure PrF;
 Var
  B      : Byte;
  LR, HR : Byte;
 Begin
  If StrX[x]='('
   then begin
    x:=x+1;
    PrE;
    If StrX[x]=')'
     then x:=x+1
     else Error(28);
   end
   else If (StrX[x]='i') or (StrX[x]='n')
         then begin
          x:=x+2;
          If StrX[x-2]='i'
           then begin
            B:=$BB;          {Mov   Ax, [i]}
            Write(ComFile, B);
            LR:=Lo(AddrI[Ord(StrX[x-1])]);
            HR:=Hi(AddrI[Ord(StrX[x-1])]);
            Write(ComFile, LR, HR);
            B:=$8B;
            Write(ComFile, B);
            B:=$07;
            Write(ComFile, B);
           end
           else If StrX[x-2]='n' then begin
            B:=$B8;          {Mov   Ax, i}
            Write(ComFile, B);
            LR:=Lo(TabN[Ord(StrX[x-1])]);
            HR:=Hi(TabN[Ord(StrX[x-1])]);
            Write(ComFile, LR, HR);
           end;
         end
         else If StrX[x]='-'
               then begin
                If TVyr<>2
                 then Error(26)
                 else begin
                  x:=x+1;
                  If StrX[x]='i'
                   then begin
                    If TabI[Ord(x+1)].Tip<>2
                     then Error(26);
                   end
                   else
                    If StrX[x]='n'
                     then If TabN[Ord(x+1)]>32768
                           then Error(26);
                  PrF;
                  LR:=$F7;
                  HR:=$D8;
                  Write(ComFile, LR, HR);          {<--!!!}
                  x:=x+2;
                 end;
               end
               else If StrX[x]='c'
                     then x:=x+1
                     else Error(29);
 End;
Procedure PrT;
 Var
  B, B1 : Byte;
 Begin
  PrF;
  B:=$50;       {Push  AX}
  Write(ComFile, B);
  While (StrX[x]<>'+') and (StrX[x]<>'-') and (StrX[x]<>'}')
        and (StrX[x]<>')') do
   begin
    PrZU;
    PrF;
    B:=$5B;     {Pop   BX}
    Write(ComFile, B);
    Case Zn of
     '*' : begin
            Case TVyr of
             1 : begin
                  B:=$F6;
                  B1:=$E3;
                 end;
             2 : begin
                  B:=$F7;
                  B1:=$E3;
                 end;
             3 : begin
                  B:=$F7;
                  B1:=$EB;
                 end;
            End;
            Write(ComFile, B, B1);
           end;
     '/' : begin
            B:=$53;
            Write(ComFile, B);
            B:=$8B;
            Write(ComFile, B);
            B:=$D8;
            Write(ComFile, B);
            B:=$58;
            Write(ComFile, B);
            Case TVyr of
             1 : begin
                  B:=$F6;
                  B1:=$F3;
                  Write(ComFile, B, B1);
                  B:=$B4;
                  Write(ComFile, B);
                  B:=$00;
                  Write(ComFile, B);
                 end;
             3 : begin
                  B:=$BA;
                  B1:=$00;
                  Write(ComFile, B, B1, B1);
                  B:=$F7;
                  B1:=$F3;
                  Write(ComFile, B, B1);
                 end;
             2 : begin
                  B:=$3D;
                  Write(ComFile, B);
                  B:=$00;
                  B1:=$80;
                  Write(ComFile, B, B1);
                  B:=$72;
                  B1:=$05;
                  Write(ComFile, B, B1);
                  B:=$BA;
                  B1:=$00;
                  Write(ComFile, B, B1, B1);
                  B:=$EB;
                  B1:=$03;
                  Write(ComFile, B, B1);
                  B:=$BA;
                  B1:=$FF;
                  Write(ComFile, B, B1, B1);
                  B:=$F7;
                  B1:=$FB;
                  Write(ComFile, B, B1);
                 end;
            End;
           end;
    End;
    B:=$50;     {Push  AX}
    Write(ComFile, B);
   end;
    B:=$58;       {Pop   AX}
    Write(ComFile, B);
 End;
Procedure PrE;
 Var
  B, B1 : Byte;
 Begin
  PrT;
  B:=$50;       {Push  AX}
  Write(ComFile, B);
  While (StrX[x]<>'}') and (StrX[x]<>')') do
   begin
    PrZS;
    PrT;
    B:=$5B;     {Pop   BX}
    Write(ComFile, B);
    Case Zn of
     '+' : B:=$03;       {Add   AX, BX}
     '-' : B:=$2B;       {Sub   AX, BX}
    End;
    Write(ComFile, B);
    B:=$C3;
    Write(ComFile, B);
    B:=$50;     {Push  AX}
    Write(ComFile, B);
   end;
    B:=$58;       {Pop   AX}
    Write(ComFile, B);
 End;
Procedure Vyrazhenie;
 Var
  Flag : Boolean;
  Z    : String[4];
  TEl  : 0..4;
  B    : Byte;
 Begin
  B:=$B8;           {Mov   AX, 0000}                    {!!!!}
  Write(ComFile, B);
  B:=$00;
  Write(ComFile, B);
  Write(ComFile, B);
  x:=0;
  TEl:=0;
  Flag:=False;
  Repeat
   Read(SkFile, Ch1, Ch2);
   If Ch1='i'
    then begin
     If TabI[Ord(Ch2)].Tip>3
      then Error(26);
     If not Flag
      then begin
       Flag:=True;
       TVyr:=TabI[Ord(Ch2)].Tip;
      end;
     TEl:=TabI[Ord(Ch2)].Tip;
     x:=x+1;
     StrX[x]:=Ch1;
     x:=x+1;
     StrX[x]:=Ch2;
    end;
   If Ch1='n'
    then begin
     ImYach;
     If TabTN[Ord(Ch2)]>3
      then Error(26);
     If not Flag
      then begin
       Flag:=True;
       TVyr:=TabTN[Ord(Ch2)];
      end;
     TEl:=TabTN[Ord(Ch2)];
     x:=x+1;
     StrX[x]:=Ch1;
     x:=x+1;
     StrX[x]:=Ch2;
    end;
   If Ch1='s'
    then begin
     x:=x+1;
     If Ch2='['
      then begin
       While Ch2<>']' do
        Read(SkFile, Ch1, Ch2);
       StrX[x]:='i';
       x:=x+1;
       StrX[x]:=Ch2;
      end
      else If (Ch2='-') or (Ch2='+') or
              (Ch2='*') or (Ch2='/')
            then begin
             StrX[x]:=Ch2;
             If not Flag
              then begin
               Flag:=True;
               If Ch2='-' then TVyr:=2;
              end;
            end
            else If Ch2=#39
                  then begin
                   Read(SkFile, Ch1, Ch2);
                   StrX[x]:='c';
                   Read(SkFile, Ch1, Ch2);
                   If not Flag
                    then begin
                     Flag:=True;
                     TVyr:=4;
                    end;
                   TEl:=4;
                  end
                  else If Ch2='}'
                        then StrX[x]:='}'
                        else If (Ch2='(') or (Ch2=')')
                             then StrX[x]:=Ch2;
    end;
   If (TEl<>0) and (TEl>TVyr) then Error(26);
  Until Ch2='}';
  Delete(Str1,x+1,Length(Str1)-x);
  x:=1;
  PrE;
 End;
Function CheckT:Boolean;
 Begin
  CheckT:=False;
  Case TVyr of
   1 : If (T=1) or (T=2) or (T=3) then CheckT:=True;
   2 : If T=2 then CheckT:=True;
   3 : If (T=3) or ((T=2) and (Min)) then CheckT:=True;
   4 : If T=4 then CheckT:=True;
  End;
  Min:=False;
 End;
Procedure Operator;
 Var
  g      : 1..3;
  Ch     : Char;
  B      : Byte;
  LR, HR : Byte;
  Metka  : Word;
  FlK    : Boolean;
 Begin
  Case Ch2 of
   Chr(9) :{for}
           Begin
            Read(SkFile, Ch1, Ch2);
            If Ch1<>'i'
             then Error(12);
            OpredTyp;
            T:=TabI[Ord(Ch2)].Tip;
            Read(SkFile, Ch1, Ch2);
            If (Ch2<>'=')
             then Error(13);
            Read(SkFile, Ch1, Ch2);
            If (Ch2<>'{')
             then Error(14);
            Vyrazhenie;
            If not CheckT
             then Error(26);
            Read(SkFile, Ch1, Ch2);
            If (Ch1<>'c') or (Ch2<>Chr(16))
             then Error(15);
            Read(SkFile, Ch1, Ch2);
            If (Ch2<>'{')
             then Error(14);
            Vyrazhenie;
            If not CheckT
             then Error(26);
            Read(SkFile, Ch1, Ch2);
            If (Ch1<>'c') or (Ch2<>Chr(17))
             then Error(16);
            Read(SkFile, Ch1, Ch2);
            If Ch1<>'c'
             then Error(11);
            Repeat
             Operator;
             Read(SkFile, Ch1, Ch2);
            Until (Ch1='c') and (Ch2=Chr(14));
           End;
   Chr(10):{if}
           Begin
            Read(SkFile, Ch1, Ch2);
            While (Ch2<>Chr(11)) do
             begin
              If Ch2<>'{'
               then Error(14);
              Vyrazhenie;
              T:=TVyr;
              Read(SkFile, Ch1, Ch2);
              If (Ch2='=') or (Ch2='<') or (Ch2='>') then
               Case Ch2 of
                '>': begin
                      Read(SkFile, Ch1, Ch2);
                      If (Ch2='=') or (Ch2='<')
                       then begin
                        Read(SkFile, Ch1, Ch2);
                        If Ch2='{'
                         then begin
                          Vyrazhenie;
                          If not CheckT
                           then Error(26);
                         end
                         else Error(14);
                       end
                       else
                        If Ch2='{'
                         then begin
                          Vyrazhenie;
                          If not CheckT
                           then Error(26);
                         end
                         else Error(14);
                     end;
                '<': begin
                      Read(SkFile, Ch1, Ch2);
                      If (Ch2='=') or (Ch2='>')
                       then begin
                        Read(SkFile, Ch1, Ch2);
                        If Ch2='{'
                         then begin
                          Vyrazhenie;
                          If not CheckT
                           then Error(26);
                         end
                         else Error(14);
                       end
                       else
                        If Ch2='{'
                         then begin
                          Vyrazhenie;
                          If not CheckT
                           then Error(26);
                         end
                         else Error(14);
                     end;
                '=': begin
                      Read(SkFile, Ch1, Ch2);
                      If Ch2='{'
                       then begin
                        Vyrazhenie;
                        If not CheckT
                         then Error(26);
                       end
                       else Error(14);
                     end;
               End
               else Error(23);
              Read(SkFile, Ch1, Ch2);
              If not ((Ch1='c') and
                 ((Ch2=Chr(18)) or (Ch2=Chr(19)) or (Ch2=Chr(20))
                 or (Ch2=Chr(11))))
               then Error(24);
              If not ((Ch1='c') and (Ch2=Chr(11)))
               then Read(SkFile, Ch1, Ch2);
             end;
            Read(SkFile, Ch1, Ch2);
            Repeat
             Operator;
             Read(SkFile, Ch1, Ch2);
            Until (Ch1='c') and (Ch2=Chr(15));
            FIf:=True;
           End;
   Chr(12):{else}
           Begin
            If not FIf
             then Error(25);
            Read(SkFile, Ch1, Ch2);
            Repeat
             Operator;
             Read(SkFile, Ch1, Ch2);
            Until (Ch1='c') and (Ch2=Chr(27));
            FIf:=False;
           End;
   Chr(13):{write}
           Begin
            FlK:=False;
            Read(SkFile, Ch1, Ch2);
            If Ch2<>'('
             then Error(17);
            Read(SkFile, Ch1, Ch2);
            If Ch2='{'
             then Vyrazhenie
             else If Ch2='"'
                   then begin
                    Read(SkFile, Ch1, Ch2);
                    Ch:=Ch2;
                    FlK:=True;
                    Read(SkFile, Ch1, Ch2);
                    If Ch2<>'"'
                     then Error(19);
                   end
                   else Error(18);
            Read(SkFile, Ch1, Ch2);
            If Ch2<>')'
             then Error(20);
            If FlK
             then begin
              B:=$B4;
              Write(ComFile, B);
              B:=$09;
              Write(ComFile, B);
              B:=$BA;
              Write(ComFile, B);
              LR:=Lo(AddrK[Ord(Ch)]);
              HR:=Hi(AddrK[Ord(Ch)]);
              Write(ComFile, LR, HR);
              B:=$CD;
              Write(ComFile, B);
              B:=$21;
              Write(ComFile, B);
             end
             else begin
              B:=$B9;
              Write(ComFile, B);
              LR:=$05;
              HR:=$00;
              Write(ComFile, LR,HR);
              B:=$BA;
              Write(ComFile, B);
              B:=$00;
              Write(ComFile, B, B);
              B:=$BB;
              Write(ComFile, B);
              LR:=$0A;
              HR:=$00;
              Write(ComFile, LR,HR);
              LR:=$F7;
              HR:=$F3;
              Write(ComFile, LR,HR);
              LR:=$83;
              HR:=$C2;
              Write(ComFile, LR,HR);
              B:=$30;
              Write(ComFile, B);
              B:=$52;
              Write(ComFile, B);
              LR:=$E2;
              HR:=$F2;
              Write(ComFile, LR,HR);
              B:=$B9;
              Write(ComFile, B);
              LR:=$05;
              HR:=$00;
              Write(ComFile, LR,HR);
              B:=$5A;
              Write(ComFile, B);
              B:=$B4;
              Write(ComFile, B);
              B:=$02;
              Write(ComFile, B);
              B:=$CD;
              Write(ComFile, B);
              B:=$21;
              Write(ComFile, B);
              LR:=$E2;
              HR:=$F9;
              Write(ComFile, LR,HR);
             end;
           End;
   Chr(21):{read}
           Begin
            Read(SkFile, Ch1, Ch2);
            If Ch2<>'('
             then Error(17);
            Read(SkFile, Ch1, Ch2);
            If Ch1<>'i'
             then Error(12);
            ImYach;
            Read(SkFile, Ch1, Ch2);
            If Ch2<>')'
             then Error(20);
           End;
   Chr(22):{writeln}
           Begin
            Read(SkFile, Ch1, Ch2);
            If Ch2<>'('
             then Error(17);
            Read(SkFile, Ch1, Ch2);
            If Ch2='{'
             then Vyrazhenie
             else If Ch2='"'
                   then begin
                    Read(SkFile, Ch1, Ch2);
                    Read(SkFile, Ch1, Ch2);
                    If Ch2<>'"'
                     then Error(19);
                   end
                   else Error(18);
            Read(SkFile, Ch1, Ch2);
            If Ch2<>')'
             then Error(20);
           End;
   Chr(24):{case}
           Begin
            Read(SkFile, Ch1, Ch2);
            Repeat
             If Ch1<>'i'
              then Error(12);
             Ch:=Ch2;
             ImYach;
             T:=TabI[Ord(Ch)].Tip;
             Read(SkFile, Ch1, Ch2);
             If (Ch1<>'c') or ((Ch1='c') and (Ch2<>Chr(28)))
              then Error(10);
             Read(SkFile, Ch1, Ch2);
             For g:=1 to 3 do
              If T=g
               then If Ch1='n'
                     then begin
                      OpredTyp;
                      If TabTN[Ord(Ch2)]<>g
                       then Error(26);
                     end
                     else If Ch1='i'
                           then If TabI[Ord(Ch2)].Tip<>g
                                 then Error(26);
             If T=4
              then If (Ch1='s') and (Ch2=#39)
                    then begin
                     Read(SkFile, Ch1, Ch2);
                     Read(SkFile, Ch1, Ch2);
                     If Ch2<>#39
                      then Error(26);
                    end
                    else If (Ch1='s') and (Ch2<>#39)
                          then Error(26)
                          else If Ch1='i'
                                then begin
                                 If TabI[Ord(Ch2)].Tip<>4
                                  then Error(26);
                                end
                                else Error(26);
             Read(SkFile, Ch1, Ch2);
             If Ch2<>':'
              then Error(21);
             Repeat
              Operator;
              Read(SkFile, Ch1, Ch2);
             Until (Ch1='c') and (Ch2=Chr(25));
             Read(SkFile, Ch1, Ch2);
            Until (Ch1='c') and (Ch2=Chr(26));
           End;
   Chr(30):{equal}
           Begin
            Read(SkFile, Ch1, Ch2);
            If Ch2<>':'
             then Error(21);
            Read(SkFile, Ch1, Ch2);
            If Ch1<>'i'
             then Error(12);
            Ch:=Ch2;
            ImYach;
            T:=TabI[Ord(Ch)].Tip;
            Read(SkFile, Ch1, Ch2);
            If Ch2<>','
             then Error(22);
            Read(SkFile, Ch1, Ch2);
            If Ch2<>'{'
             then Error(14);
            Vyrazhenie;
            If not CheckT
             then Error(26);
            LR:=Lo(AddrI[Ord(Ch)]);
            HR:=Hi(AddrI[Ord(Ch)]);
            B:=$BB;
            Write(ComFile, B, LR, HR);
            B:=$89;
            Write(ComFile, B);
            B:=$07;
            Write(ComFile, B);
           End;
  End;
  Read(SkFile, Ch1, Ch2);
  If (Ch2<>';')
   then Error(6);
 End;
Procedure ClosePr; Forward;
Procedure Telo;
 Begin
  Read(SkFile, Ch1, Ch2);
  If Ch1<>'c'
    then Error(11);
  Repeat
   Operator;
   Read(SkFile, Ch1, Ch2);
  Until (Ch1='c') and (Ch2=Chr(8));
  ClosePr;
 End;
 {------------------Code-------------------}
Procedure ClosePr;
 Var
  B     : Byte;
 Begin
  B:=$CD;           {Int   20h}
  Write(ComFile, B);
  B:=$20;
  Write(ComFile, B);
  B:=$C3;           {Ret      }
  Write(ComFile, B);
 End;
Procedure InitPr;
 Var
  B         : Byte;
  LR, HR    : Byte;
  i, h      : Byte;
  NB        : Integer;
 Begin
  B:=$1E;           {Push  DS}
  Write(ComFile, B);
  B:=$B8;           {Mov   AX, 0000}
  Write(ComFile, B);
  B:=$00;
  Write(ComFile, B);
  Write(ComFile, B);
  B:=$50;           {Push  AX}
  Write(ComFile, B);
  B:=$8C;           {Mov   AX, CS}
  Write(ComFile, B);
  B:=$C8;
  Write(ComFile, B);
  B:=$8E;           {Mov   DS, AX}
  Write(ComFile, B);
  B:=$D8;
  Write(ComFile, B);
  B:=$E9;           {Jmp     }
  Write(ComFile, B);
  LR:=Lo(N2Byte+N2Str);
  HR:=Hi(N2Byte+N2Str);
  Write(ComFile, LR, HR);
  B:=$00;
  For i:=1 to N2Byte do
   Write(ComFile, B);
  NB:=0;
  If NRus<>0 then
   For i:=1 to NRuS do
    begin
     AddrK[i]:=N2Byte+$100+12+NB;
     For h:=1 to Length(TabRuS[i]) do
      begin
       B:=Ord(TabRuS[i,h]);
       Write(ComFile, B);
      end;
     B:=Ord('$');
     Write(ComFile, B);
     NB:=NB+Length(TabRuS[i])+1;
    end;
  Write(ComFile, B);
 End;

 Begin
  ClrScr;
  FEndVar:=False;
  FIf:=False;
  NRuS:=0;
  Min:=False;
  NN:=0;
  NI:=0;
  Write('Введите имя файла : ');
  Read(FName);
{  FName:='c:\ann\pr1.ann';}
  FNameSk:=FName;
  Delete(FNameSk,Length(FNameSk)-3,4);
  FNameCom:=FNameSk;
  FNameSk:=FNameSk+'.skn';
  FNameCom:=FNameCom+'.com';
  Assign(PrFile, FName);
  Assign(SkFile, FNameSk);
  Assign(ComFile, FNameCom);
  Reset(PrFile);
  ReWrite(SkFile);
  ReWrite(ComFile);
  While not EOF(PrFile) do
   Begin
    j:=1;
    ReadLn(PrFile, StrF);
    Str1:=StrF;
    While StrF<>'' do
     Begin
      If StrF[1] in Number
       then PreobrN
       else If StrF[1] in Letter
             then PreobrL
             else If StrF[1] in Symbol
                   then PreobrS
                   else If StrF[1]=' '
                         then Delete(StrF,1,1)
                         else Error(0);
     End;
{    Write(SkFile, #10,#13);}
   End;
  Close(PrFile);
  Close(SkFile);
  FObjav:=False;
  FTelo:=False;
  Reset(SkFile);
  Read(SkFile, Ch1, Ch2);
  If Ch1='c'
   then Begin
         If not FObjav
          then If Ch2=Chr(1)
                then begin
                      Objavlenie;
                      FObjav:=True;
                     end
                else Error(1);
          If not FTelo
           then begin
            Read(SkFile, Ch1, Ch2);
            If Ch2=Chr(7)
             then begin
                   InitPr;
                   Telo;
                   FTelo:=True;
                  end
             else Error(2);
           end;
        End
   else Error(1);
  Close(SkFile);
 End.