Асемблери. Принципи компіляції програм і методів написання компіляторів (Звіт з лабораторної роботи № 7), страница 3

   {

    if (seg_open_flag) exit(0);

    parsep = parse(lexbuf,parsep);

    if (parsetyp) exit(0);

    goto runscan;

   }

   if (!seg_open_flag) exit(0);

   parsep=parse(lexbuf,parsep);

   if (operandcount[opcode]) /* Проверка на наличие операндов у команды */

    if (parsetyp!=PT_WORD) exit(0);

  /* Анализ первого операнда */

   if(lexbuf)

   if (operandcount[opcode]==1) /* Если команда с одним операндом */

   {

    if (opcode==OP_DEC) op1num=op1num+8;

    offs++;

    if(opcode==OP_JB || opcode==OP_JL) offs++; //new

    goto begin2;

   }

  /* Проверка на наличие второго операнда : если он есть , то ошибка */

   parsep=parse(lexbuf,parsep);

   if (operandcount[opcode]==1)

    if (parsetyp==PT_WORD) exit(0);

    if (parsetyp) /* Проверка на наличие разделителя между операндами*/

    if (lexbuf[0]!=',') exit(0);

  /* Анализ второго операнда */

   parsep=parse(lexbuf,parsep);

  /* Если его нет, то ошибка */

   if (operandcount[opcode==2])

    if (parsetyp!=PT_WORD) exit(0);

   if (0>(op2num=findstr(registers,lexbuf)))

   {

    if (strtoi(lexbuf,&n))

    {

     if (0 > (op2num=find_sym(lexbuf))) exit(0);

     else

     {

      if (strcomp(symtab[op2num].type,sym[2]))

      {

       offs=offs+operandcount[opcode]+2;

       goto begin2;

      }

      if (strcomp(symtab[op2num].type,sym[1]))

      {

       offs=offs+operandcount[opcode]+1;

       goto begin2;

      }

     }

    }

    else

    {

     offs=offs+operandcount[opcode];

     if ((n < 0)||(n > 255))

      offs=offs+1;

     goto begin2;

    }

   }

   if (op1num % 2)

    op2num=op2num+8;

   offs=offs+operandcount[opcode];

   goto begin2;

  }

  while(parsetyp);

 }

runscan:

fseek(F,0L,SEEK_SET);

number=0;

begin:

 while (!feof(F))

 {

  fgets(cmdbuf,MAXSTR,F);

   number++;

  strupcase(cmdbuf);

  if(strconsist("\n",cmdbuf[0]))   /* Если строка пуста */

  {

   fprintf(F1,"\t%10i\n",number);

   printf("\t%10i\n",number);

   goto begin;

  }

  parsep = cmdbuf;

  do

  {

  restart:

   parsep=parse(lexbuf,parsep);

   if (parsetyp==PT_LABEL)       /* Если команда с меткой */

   {

    if (label_flag)

    {

     printf("Line %d:Dublicate label",number);

     exit(0);

    }

    if (strconsist("\n",parsep[0])) /* Расположена ли метка в одной

                                    строке с командой  */

    {

     fprintf(F1,"\t%10d \t%20s",number,cmdbuf);

     printf("\t%10d \t%20s",number,cmdbuf);

     goto begin;

    }

    label_flag=1;

    goto restart;

   }

   if (0>(opcode=findstr(mnemonics,lexbuf))) /* Если это не команда

                         то следующая лексема должна быть директивой  */

   { if( 4== ( op1num=findstr(directives,lexbuf) ) ) goto assume;

    parsep=parse(lexbuf,parsep);

    if (0>(op1num=findstr(directives,lexbuf)))

    {

     printf("\nline %d",number);

     printf(":Wrong mnemonic");

     exit(0);

    }

    else

    {

     /* Формирование листинга по директивам */

     switch (op1num)

    {

assume: case DIR_ASSUME:

         fprintf(F1,"\t%10i %6.4X        \t%-s",number,offs,cmdbuf);

         printf("\t%10i %6.4X        \t%-s",number,offs,cmdbuf);

         break;

      case DIR_SEG:   /* Директива - segment */

       seg_open_flag=1;

       offs=0;

       Seg_Begin=offs;

       fprintf(F1,"\t%10i %6.4X        \t%-s",number,offs,cmdbuf);

       printf("\t%10i %6.4X        \t%-s",number,offs,cmdbuf);

       cmdbuf[0]=0;

      break;

      case DIR_ENDS:  /* Директива - ends */