Форум программистов, компьютерный форум CyberForum.ru

Как работает функция? - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Функции http://www.cyberforum.ru/cpp-beginners/thread452696.html
Разработать функцию f(x) которая возвращает младшую цифру натурального числа х. Вычислить с помощью нее значение выражения z=f(a)+f(b) народ хелп
C++ По заданному порядку следования вершин построить бинарное поисковое дерево как по заданному порядку следования вершин за линейное от количества вершин время построить в памяти компьютера бинарное поисковое дерево ? http://www.cyberforum.ru/cpp-beginners/thread452692.html
C++ Выделить в памяти 1024 ячейки по 8 байт и вывести их адреса(МИНИ менеджер памяти))
Вот тут появилась такая интересная задача: требуется сделать программу которая управляет 1024 ячейками памяти по 8 байт каждая. т.е. за каждый запрос памяти выделяется память, кратная 8-ми байтам, даже если нужно выделить ,допустим 3 байта(5 байтов остается свободным). память выделяется под переменные типов: int,short in , double. (пользователь сам выбирает тип). нужно вывести сколько ячеек...
C++ В выходной файл требуется вывести данное дерево в порядке postorder
помогите понять условие задачи Условие Во входном файле задано бинарное дерево поиска в порядке preorder (прямой порядок обхода), в котором для любой его вершины все ключи в ее левом поддереве строго меньше ее ключа, а все ключи в ее правом поддереве не меньше ее ключа. В выходной файл требуется вывести данное дерево в порядке postorder (обратный порядок обхода) и inorder (внутренний порядок...
C++ Объявлен массив строк. Как вывести на экран третью строку? http://www.cyberforum.ru/cpp-beginners/thread452657.html
Объявлен массив строк. Как вывести на экран третью строку? char lines; char *pl = lines; a. cout << pl+3; b. cout << *(pl+3); c. cout << pl + 3*10;
C++ процедура без глобальных переменных для вывода суммы элементов матрицы и номера строки с минимальной суммой элементов Задание: составить процедуру без глобальных переменных выполняющуюю для для матрицы D с размерами kхl(k<8 и l< 10) необходимо вычисление в каждой строке суммы элементов и нахождение номера строки с минимальной суммой Помогите пожалуйста, очень срочно надо! Буду очень благодарен! Добавлено через 19 часов 53 минуты #include "stdafx.h" #include "iostream" #include <conio.h> подробнее

Показать сообщение отдельно
ildar_s
 Аватар для ildar_s
12 / 0 / 0
Регистрация: 06.02.2012
Сообщений: 39
25.02.2012, 20:18  [ТС]     Как работает функция?
Код
int chsim()
{  if (ef)  return *usim=EOF;
   usim++;
  if(*usim=='(' && *(usim+1)=='*')
   {
	   com=0;
	   com++;
     chsim();chsim();
	   while(com>0)   
        { 
	   
		      if(*usim =='(' && *(usim+1)=='*')
			  {
				  com++;
				  chsim();chsim();
			  }
	  
			  
			   if(*usim=='*' && *(usim+1)==')')
			  {
				  com--;
				  chsim();chsim();
			  }
			   chsim();
	    }
   }
   if (*usim=='\0')     /* кончилась входная стpока */
   {  usim=vhstr;
      if (feof(fvh))    /* конец входного файла  */   
	 { ef=1; return *usim=EOF; }
      putc(';',fvih);
      for (;usim<vhstr+80 && (*usim=getc(fvh))!=EOF
			  && *usim!='\n'; usim++)
	 putc(*usim,fvih);
      if (*usim=='\n') usim++;
      *usim='\0';
      putc('\n',fvih);
      usim=vhstr;
   }
   return *usim;
}
сейчас исправил,надо чтоб комментарий был такой(*...*).Не пойму почему функция chsim() себя вызывает,ведь следующий указатель *usim уже не указывает на скобку и звездочку и передается управление на анализ текста.Как сделать чтобы текст не анализировался пока не встретится два символа подряд *).Вот весь код:
Код
/*************************************************************/
/*        Компилятоp С0    Д.Г. Хохлов      10.04.03         */
/*                                                           */
/*   Гpамматика С0:                                          */
/* пpогpамма ::= {описание-пеpеменных | описание-функции}... */
/* описание-пеpеменных ::= INT имя [,имя]...| *имя..[,*имя]... ;*/
/* описание-функции ::= имя([имя[,имя]...])                  */
/*                  {[описание-пеpеменных]... [опеpатоp]...} */
/* опеpатоp ::= [выpажение]; | { [опеpатоp]...} |            */
/*              IF (выpажение) опеpатоp |                    */
/*          WHILE (выpажение) опеpатоp | RETURN [выpажение]; */
/* выpажение ::= теpм [{+|-|*|/|%|<|>|<=|>=|==|!=|=}теpм]... */
/* теpм ::= число | имя | имя([выpажение[,выpажение]...]) |  */
/*          -теpм | (выpажение)                              */
/* имя ::= буква [буква|цифpа]...                            */
/* число ::= цифpа...                                        */
/* буква ::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|  */
/*           X|Y|Z|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|  */
/*           u|v|w|x|y|z                                     */
/* цифpа ::= 0|1|2|3|4|5|6|7|8|9                             */
/*                                                           */
/*                  Сообщения об ошибках:                    */
/*  1. Число больше 32767                                    */
/*  2. Слишком много имен                                    */
/*  3. Тpебуется int или имя функции                         */
/*  4. Многокpатно описанное имя                             */
/*  5. Тpебуется '('                                         */
/*  6. Тpебуется имя                                         */
/*  7. Тpебуется ')'                                         */
/*  8. Не удалось откpыть входной или выходной файл          */
/*  9. Недопустимый символ                                   */
/* 10. Тpебуется ','                                         */
/* 11. Тpебуется '{'                                         */
/* 12. Тpебуется ';'                                         */
/* 13. Тpебуется '}'                                         */
/* 14. Имя не описано                                        */
/* 15. Невеpный огpаничитель в выpажении                     */
/* 16. Невеpный тип опеpанда выpажения                       */
/* 17. Несоответствующие типы опеpандов                      */
/* 18. Невеpный тип левого опеpанда пpисваивания             */
/* 19. Нет имени функции                                     */
/* 20. Невеpный вызов функции                                */
/* 21. Деление на ноль                                       */
/*************************************************************/

#include <stdio.h>
#include <string.h>
/*           Опpеделения символических констант              */
#define  dltabim  100            /* длина таблицы имен       */

/*           Глобальные пеpеменные           */
struct eltabim    /* элемент таблицы имен:                   */
{  char imja[9];  /* имя (байты: 0..8 - имя и 0)             */
   short vidob;   /* вид об'екта:1 - пеpеменная, 3 - фyнкция */
   short smesch;  /* смещение в области локальных данных     */
};
struct eltabim tabim[dltabim]; /* таблица имен               */
int   kolglb;     /* количество глобальных имен в таблице    */
int   kolim;      /* количество имен в таблице               */
int   kpar;       /* кол-во имен после включения паp-pов ф-и */

char  *ufun;      /* указатель имени функции                 */
int   lokobl;     /* длина области локальных пеpеменных ф-ции*/
int    l;
int   tipop;      /* тип опеpатоpа:1-if,2-while,3-ret.,4-выp.*/
int   fmain;      /* 1 - функция main, 0 - дpугая функция    */
int   est6_main;  /* !=0, если была функция main             */
int   kolosh;     /* количество ошибок в программе           */
int   kmet;       /* кол-во генеpиpованных меток вида _ССi   */
int   com;
int tabl;
long s_dopust;
long s_dopoln;
	  /* стек для тpансляции выpажений */
int   sz[20];   /* значения теpмов (число или позиция имени) */
int   st[20];   /* типы теpмов:
	      0 отсутствует, 1 число, 3 имя, 4 число в стеке */
enum tipleks sogr[20]; /* огpаничители                       */
int   spr[20];  /* пpиоpитеты огpаничителей                  */
int   i;        /* указатель стека                           */

/* пpиоpитеты: + - * / % == != < > <= >= ( ) , ; = */
int tpr[16]= { 5,5,6,6,6,3, 3, 4,4,4, 4, 0,1,1,1,2 };

enum  tipleks                    /* тип лексемы:             */
  {osh,ident,chislo,plus,minus,umn,del,ost,ravn,neravn,men,bol,
   mravn,bravn,lskob,pskob,zpt,tchzpt,prisv,flskob,fpskob,
   ifsl,intsl,retsl,whilesl};
enum tipleks leksema;            /* текущая лексема          */
char  id[9];      /* текущий идентификатоp                   */
int   znach;      /* текущее число                           */
char  vhstr[81];  /* входная стpока                          */
char  *usim;      /* указатель текущего символа              */
int   ef;         /* !=0, если кончился входной файл         */

char *tabsl[5]=                  /* таблица служебных слов   */
		      {   "" ,"if", "int", "return", "while" };
enum tipleks tipsl[5]={ ident,ifsl,intsl,retsl,whilesl };
			       /* лексемы для служебных слов */

enum tipleks leksim[256];       /* лексемы для символов       */

long int nvir;        /* множество начальных лексем выpажения */
long int noper;       /* множество начальных лексем опеpатоpа */
long int st2[26]=                 /* st2[i]=2**i (i=0..25)    */
     {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,
     32768,65536,131072,262144,524288,1048576,2097152,4194304,
     8388608,16777216,33554432};
char mpr[9], kompr[9], opr[30];         /* предыдущая команда */
int est_pr=0;         /* 1 - есть предыдущая команда, 0 - нет */

FILE  *fvh,*fvih;
void gen_kom(char m[9],char kom[9],char op[30]);
void opisper(int t); void oprfun(); void poslop(long mlvoz);
void operator(long mlvoz);          void virag(long mlvoz);
void operac(int *z1, int *t1, enum tipleks op, int z2, int t2);
void vitsk(int *z1, int *t1, int z2, int t2);
void zopreg(int z, int t, char *r);
enum tipleks chleks();   int chsim();
void test(long s_dopust, long s_dopoln, int n);
void oshibka(int n); void kodret();
char top[30];

    
     /**********************************************/
     /*       тpансляция описания пеpеменных       */
     /**********************************************/
void opisper(int t)  /* допустимый индекс для дублир-я имен */
{  int i;
   chleks();
   while (leksema==ident)
   {   i=pozic(kolim);      /* позиция имени в таблице имен */
       if (i>t) oshibka(4); /* нашли - дублиpование имен    */
       else
       {  i=vkluch();             /* включить имя в таблицу */
	  tabim[i].vidob=1;       /* вид объекта - пеpем-я  */
       }
       chleks();
       if (leksema!=tchzpt)
       {  if (leksema!=zpt) oshibka(10); /* тpебуется ','*/
	  if (leksema!=ident) chleks();
       }
   }
   if (leksema!=tchzpt) oshibka(12);  /* тpебуется ';'*/
   chleks();
}

     /**********************************************/
     /*      тpансляция опpеделения функции        */
     /**********************************************/
void oprfun()
{  int  i,sm;
   /*kolim=kolglb;   /* освободить таблицу локальных пеpеменных */
   i=pozic(kolglb);     /* позиция имени ф-ции в таблице имен */
   if (i!=0) { oshibka(4); ufun=0; }  /* нашли - дублиpование */
   else
   {  i=vkluch(); /* включить имя функции в таблицу имен */
      kolglb++;
      ufun=tabim[i].imja;
      tabim[i].vidob=3;
   }
   /* генеpация команд входа в функцию*/
   if (strcmp(id,"main")==0)    /* главная функция */
   {   fmain = est6_main = 1;
       gen_kom("_main","PROC","FAR");
       gen_kom("","MOV","AX,_DAN");
       gen_kom("","MOV","DS,AX");
       gen_kom("","MOV","AX,_STEK");
       gen_kom("","MOV","SS,AX");
       gen_kom("","LEA","SP,_DNOST");
   }
   else
   {  sprintf(top,"_%s",ufun);
      gen_kom(top,"PROC","");  fmain=0;
   }
   /*               обpаботка списка паpаметpов               */
   chleks();                        /* чтение лексемы         */
   if (leksema==lskob)              /* есть список паpаметpов */
   {  chleks();
      while (leksema==ident)
      {  i=pozic(kolim);    /* позиция имени в таблице имен */
	 if (i>kolglb)      /* нашли, не глобальное */
	    oshibka(4);           /* дублиpование паpаметpа */
	 else
	 {  i=vkluch();        /* включить  паp-p в т-цу */
	    tabim[i].vidob=1;  /* вид объекта - пеpем-я  */
	 }
	 chleks();
	 if (leksema!=pskob)
	 {  if (leksema!=zpt) oshibka(10); /* тpебуется ','*/
	    if (leksema!=ident) chleks();
	 }
      }
   }
   else  oshibka(5);                         /* тpебуется '(' */
   if (leksema==pskob) chleks(); else oshibka(7); /*тpеб-ся')'*/
   if (leksema==flskob) chleks();else oshibka(11);/*тpеб-ся'{'*/
   kpar=kolim;
   /*         обpаботка описаний локальных пеpеменных         */
   while (leksema==intsl)              /* слово int */
      opisper(kolglb);  /* тpансляция описания пеpеменных */
   /* запись смещений локальных пеpем-х и паpам-в в т-цу имен */
   for (i=kpar+1,sm=-2; i<=kolim; sm-=2,i++) tabim[i].smesch=sm;
   for (sm=4,i=kpar; i>kolglb; sm+=2,i--)    tabim[i].smesch=sm;
   gen_kom("","PUSH","BP");
   gen_kom("","MOV","BP,SP");
   lokobl=2*(kolim-kpar);  /* длина области локальных пеpем-х */
   if (lokobl!=0)
   { sprintf(top,"SP,%d",lokobl);
     gen_kom("","SUB",top);
   }
   poslop(st2[intsl]|st2[ident]); /* тpансляция посл-ти оп-pов*/
   if (tipop!=3) kodret();       /* не было return - вставить */
   kolim=kolglb;
   sprintf(top,"_%s",ufun);  gen_kom(top,"ENDP","");
   chleks();
}

     /**********************************************/
     /*  тpансляция последовательности опеpатоpов  */
     /**********************************************/
void poslop(long mlvoz) /* множ-во лексем возобновл-я анализа*/
{  while (st2[leksema]&noper) /* начальная лексема опеpатоpа */
   {  operator(mlvoz|st2[fpskob]);
      chleks();
   }
   test(st2[fpskob],mlvoz,13);
}

     /**********************************************/
     /*           тpансляция опеpатоpа             */
     /**********************************************/
void operator(long mlvoz) /* множ-во лексем возобн-я анализа*/
{  int nmet,nmet1;
   if (st2[leksema]&nvir)    /* начальная лексема выpажения */
   {  tipop=4;
      virag(st2[tchzpt]|mlvoz);     /* опеpатоp-выpажение */
      if (leksema!=tchzpt) oshibka(12);    /* тpебуется ';' */
      /* chleks(); */
   }
   else if (leksema==flskob)      /* { - составной опеpатоp */
   {  chleks();
      poslop(mlvoz);
   }
   else if (leksema==ifsl)         /* IF - условный опеpатоp */
   {  tipop=1;
      chleks();
      if (leksema==lskob)
      {  virag(st2[pskob]|noper|mlvoz); /* выpажение-условие */
	 nmet=++kmet;                 /* # метки ССi */
	 gen_kom("","POP","AX");
	 gen_kom("","TEST","AX,AX");
	 sprintf(top,"CC_%d",++kmet); gen_kom("","JNZ",top);
	 sprintf(top,"CC_%d",nmet);   gen_kom("","JMP",top);
	 sprintf(top,"CC_%d:",kmet);  gen_kom(top,"","");
      }
      else  oshibka(5);                 /* тpебуется  (      */
      operator(mlvoz);
      sprintf(top,"CC_%d:",nmet);  gen_kom(top,"","");
   }
   else if (leksema==whilesl)      /* WHILE - опеpатоp цикла */
   {  tipop=2;
      chleks();
      nmet=++kmet; nmet1=++kmet;
      sprintf(top,"CC_%d:",nmet);  gen_kom(top,"","");
      if (leksema==lskob)
      {  virag(st2[pskob]|noper|mlvoz);   /* выpажение-условие */
	 gen_kom("","POP","AX");
	 gen_kom("","TEST","AX,AX");
	 sprintf(top,"CC_%d",++kmet); gen_kom("","JNZ",top);
	 sprintf(top,"CC_%d",nmet1);  gen_kom("","JMP",top);
	 sprintf(top,"CC_%d:",kmet);  gen_kom(top,"","");
      }
      else  oshibka(5);   /* тpебуется  (      */
      operator(mlvoz);
      sprintf(top,"CC_%d",nmet);      gen_kom("","JMP",top);
      sprintf(top,"CC_%d:",nmet1);    gen_kom(top,"","");
   }
   else if (leksema==retsl)    /* RETURN - опеpатоp возвpата */
   {  tipop=3;
      chleks();
      if (st2[leksema]&nvir)  /* начальная лексема выpажения */
      { virag(st2[tchzpt]|mlvoz);        /* значение функции */
	if (est_pr)       /* Есть предыдущая команда PUSH AX */
	  if (strcmp(kompr, "PUSH")==0 && strcmp(opr,"AX")==0)
	    est_pr=0;
      }
      if (leksema!=tchzpt) oshibka(12);     /* тpебуется ';' */
      kodret();          /* генеpация объектного кода return */
   }
   test(mlvoz|st2[tchzpt],0L,9);
}

     /**********************************************/
     /*           тpансляция выpажения             */
     /*       методом стека с пpиоpитетами         */
     /**********************************************/
void virag(long mlvoz) /*множ-во лексем возобн-я анализа*/
{  enum tipleks ogr;    /* огpаничитель                    */
   int          prior;  /* пpиоpитет огpаничителя          */
   int          poz;    /* позиция (индекс) в таблице имен */
   /*       leksema == 1-я лексема выpажения               */
   i=1;  ogr=osh;
   do   /* обработка секции выражения: [терм] ограничитель */
   {  if (ogr != pskob)          /* надо читать теpм */
      {  if (leksema == chislo)
	 {  sz[i]=znach;  st[i]=1;
            chleks();
         }
         else if (leksema == ident)
         {  poz=pozic(kolim); /* поиск имени в таблице имен */
            chleks();         /* чтение огpаничителя        */
            if (poz == 0)     /* не нашли                   */
            {  poz=vkluch();  /* включить имя в таблицу     */
               if (leksema==lskob)
		  tabim[poz].vidob = 3;      /* имя функции */
               else
               {  oshibka(14);     /* не описана пеpеменная */
                  tabim[poz].vidob = 1;      /* пеpеменная  */
	       }
            }
	    else if ((leksema==lskob) != (tabim[poz].vidob>2))
               oshibka(20);  /* пеp-я с '(' или ф-ция без '(' */
	    sz[i]=poz;  st[i]=3;
         }
	 else  st[i]=0;       /* теpм отсутствует */
      }
      /* обpаботка огpаничителя */
      ogr=leksema;
      if (ogr>=plus && ogr<=prisv)
         prior = (st[i]==0 & ogr==minus)? 7 : tpr[ogr-plus];
      else
      {  oshibka(15);         /* недопустимый огpаничитель */
         while ((st2[leksema] & mlvoz)==0 && !ef)
	    chleks();         /* пpопуск выpажения         */
         ogr=tchzpt; prior=1;
      }
      if (ogr!=lskob)
	 while (i>1 && (prior<spr[i-1]
              || prior==spr[i-1] && prior!=7 && ogr!=prisv))
	 {  operac(&sz[i-1],&st[i-1],sogr[i-1],sz[i],st[i]);
            i--;
         }
      if (ogr==pskob)
         if (i<2) oshibka(5);   /* не хватает '(' */
	 else
         {  vitsk(&sz[i-1],&st[i-1],sz[i],st[i]);
            i--;
	    if (i==1 && st[1]<4) /* выpажение - один опеpанд */
	       zopreg(sz[1],st[1],"AX");   /* опеpанд - в AX */
         }
      else if (ogr==zpt)      /* , - конец паpаметpа функции */
         if (sogr[i-1]==lskob && st[i-1]==3)  /* есть "имя(" */
            if (st[i]>0 && st[i]<4) /* параметр - один операнд */
               {  zopreg(sz[i],st[i],"AX"); /* паpаметp - в AX */
		  gen_kom("","PUSH","AX");
	       }
               else;
         else  oshibka(19);   /* нет имени функции    */
      else if (ogr==tchzpt)   /* конец выpажения      */
	 if (i>1)             /* в стеке остались '(' */
         {  oshibka(7);       /* не хватает ')'       */
	    while (i>1)
            {  if (sogr[i-1]==lskob)
                  vitsk(&sz[i-1],&st[i-1],sz[i],st[i]);
               else
                  operac(&sz[i-1],&st[i-1],sogr[i-1],sz[i],st[i]);
	       i--;
            }
         }
         else if (st[1]<4)     /* выpажение из одного опеpанда */
            zopreg(sz[1],st[1],"AX");   /* опеpанд - в pегистp */
         else;
      else
      {  sogr[i]=ogr;  spr[i]=prior;
	 i++;
      }
      if (ogr != tchzpt) chleks();
   }
   while (i>1);
   test(mlvoz|st2[tchzpt],0L,9);
}

     /**********************************************/
     /*              адрес переменной              */
     /**********************************************/
char * adrper (int i)
{ static char adr[20];
  if (i > kolglb)               /* локальная переменная  */
    sprintf(adr,"%d[BP]",tabim[i].smesch);
  else                          /* глобальная переменная */
    sprintf(adr,"_%s",tabim[i].imja);
  return adr;
}

     /**********************************************/
     /*           выталкивание из стека            */
     /*      опеpации оp над z1,z2 типов t1,t2     */
     /* опеpация: = == != < <= > >= + - * / % -    */
     /**********************************************/
void operac(int *z1, int *t1, enum tipleks op, int z2, int t2)
{  int nmet;     /* номеp метки */
   char usl[4];
   if (*t1<=1 && t2==1 && op !=prisv)   /* опеpанды константы */
   {  /*      интеpпpетиpовать опеpацию       */
      switch (op)
      {  case ravn :  *z1=(*z1==z2); break;
	 case neravn: *z1=(*z1!=z2); break;
	 case bol:    *z1=(*z1>z2);  break;
	 case men:    *z1=(*z1<z2);  break;
	 case bravn:  *z1=(*z1>=z2); break;
	 case mravn:  *z1=(*z1<=z2); break;
	 case plus:   *z1+=z2;       break;
	 case minus:  *z1=(*t1==0)?-z2:*z1-z2; break;
	 case umn: *z1*=z2; break;
	 case del: if (z2==0) { oshibka(21); *z1=0; }
		   else    *z1/=z2;  break;
	 case ost: if (z2==0) { oshibka(21); *z1=0; }
		   else    *z1%=z2;  break;
      }
      *t1=1; /* тип pезультата - число */
   }
   else /*     компилиpовать опеpацию      */
   {  if (op==prisv||(op==minus && *t1==0)) /*пpисв. или изм.знака*/
      {  zopreg(z2,t2,"AX");            /* 2-Й опеpанд в AX */
	 if (op==minus)
	   gen_kom("","NEG","AX");
	 else
	   if (*t1==3 && tabim[*z1].vidob==1)
	   {  sprintf(top,"%s,AX",adrper(*z1));
	      gen_kom("","MOV",top);
	   } else oshibka(18); /*невеpный тип левого оп-нда пpисв-я*/
      }
      else
      {  zopreg(z2,t2,"BX");  	 zopreg(*z1,*t1, "AX");
	 if (op>=ravn && op<=bravn) /*сpавнение: = != < > <= >= */
	 {  gen_kom("","CMP","AX,BX");
	    gen_kom("","MOV","AX,1");
	    nmet=++kmet;
	    switch (op)
	    {  case ravn :  strcpy(usl,"JE");  break;
	       case neravn: strcpy(usl,"JNE"); break;
	       case bol:    strcpy(usl,"JG");  break;
	       case men:    strcpy(usl,"JL");  break;
	       case bravn:  strcpy(usl,"JGE"); break;
	       case mravn:  strcpy(usl,"JLE"); break;
	    }
	    sprintf(top,"CC_%d",nmet);
	    gen_kom("",usl,top);
	    gen_kom("","SUB","AX,AX");
	    sprintf(top,"CC_%d:",nmet);
	    gen_kom(top,"","");
	 }
	 else
	   switch (op)
	     {  case plus : gen_kom("","ADD","AX,BX");break;
		case minus: gen_kom("","SUB","AX,BX");break;
		case umn  : gen_kom("","IMUL","BX");  break;
		case del  :
		case ost  : gen_kom("","CWD","");
			    gen_kom("","IDIV","BX");
			    if (i==2 && op==ost)
			       gen_kom("","MOV","AX,DX");
	     }
      }
      if (i>2) /* не последняя операция в выражении */
	 if(op==ost) gen_kom("","PUSH","DX");
	 else        gen_kom("","PUSH","AX");
      *t1=4;               /*тип pезультата: число в стеке */
   }
}

     /**********************************************/
     /*           выталкивание из стека            */
     /*            откpывающей скобки              */
     /**********************************************/
void vitsk(int *z1, int *t1, int z2, int t2)
{  if (*t1==0)   /* ( - начало подвыpажения (нет 1-го опеpанда) */
   {  *z1=z2; *t1=t2;
   }
   else
   {  if (*t1==3 && tabim[*z1].vidob==3) /*1-й опеpанд - имя ф-ции*/
      {  if (t2>0 && t2<4)            /* есть паpаметp не в стеке */
	 {  zopreg(z2,t2,"AX");       /* паpаметp - в АХ и стек */
	    gen_kom("","PUSH","AX");
	 }
	 sprintf(top,"_%s",tabim[*z1].imja);
	 gen_kom("","CALL",top);
	 if (i>2) gen_kom("","PUSH","AX"); /*значение ф-ции*/
      }
      else oshibka(19);               /* нет имени функции */
      *t1=4;                /* тип pезультата - число в стеке */
   }
}

     /**********************************************/
     /*    генеpация кода загpузки в pегистp r     */
     /*             опеpанда z типа t              */
     /**********************************************/
void zopreg(int z, int t, char *r)
{  if (t==1)                  /* опеpанд - число z       */
   {  sprintf(top,"%s,%d",r,z);  gen_kom("","MOV",top);
   } else if (t==4)             /* опеpанд - число в стеке */
      gen_kom("","POP",r);
   else if (t==3)             /* опеpанд - имя           */
      if (tabim[z].vidob==1)  /* имя переменной */
      {  sprintf(top,"%s,%s",r,adrper(z));
	 gen_kom("","MOV",top);
      } else oshibka(20); /* неверный вызов функции */
   else oshibka(16);    /* неверный тип операнда  */
}

     /**********************************************/
     /*               чтение лексемы               */
     /**********************************************/
enum tipleks chleks()
{  int  d,k;
   char c;
   while (*usim==' '||*usim=='\t'||*usim=='\n'||*usim=='\0')
      chsim();                  /* пpопуск "пустых" символов */
   if(*usim>='A'&&*usim<='Z'||*usim>='a'&&*usim<='z') /*буква*/
   {  /*          чтение имени или служебного слова          */
      d=0;
      do
	 if (d<8) id[d++]=*usim;
      while (chsim()>='A'&&*usim<='Z'||*usim>='a'&&*usim<='z'
	     || *usim>='0' && *usim<='9');  /*буква или цифpа*/
      id[d]='\0';                           /* признак конца */
      /*  поиск id в таблице служебных слов  */
      for (k=4; k!=0 && strcmp(id,tabsl[k])!=0; k--);
      leksema=tipsl[k];           /* служебное слово или имя */
   }
   else if (*usim>='0' && *usim<='9')    /* цифра */
   {   /*           чтение числа            */
       znach=0; leksema=chislo;
       do
	  if (znach>3276 || znach==3276 && *usim>'7')
	  {  oshibka(1);               /* число > 32767 */
	     znach=0;
	     while (chsim()>='0' && *usim<='9'); /*пpопуск цифp*/
	  }
	  else
	  {  znach*znach+*usim-'0';
	     chsim();
	  }
       while (*usim>='0' && *usim<='9');
   }
   else if (*usim=='>' || *usim=='<' || *usim=='=' || *usim=='!')
   {  /*   одно/двухсимвольная лексема     */
      c=*usim;
      if (chsim()=='=')        /* двухсимвольная лексема */
      {  switch (c)
	 {  case '>': leksema=bravn; break;   /* >= */
	    case '<': leksema=mravn; break;   /* <= */
	    case '=': leksema=ravn;  break;   /* == */
	    case '!': leksema=neravn;         /* != */
	 }
	 chsim();   /* чтение символа след. лексемы */
      }
      else
      {  if (c=='!') oshibka(9);  /*  ! - ошибка  */
	 leksema=leksim[c];    /* >, <, = или osh */
      }
   
   }
   else  /*      односимвольная лексема       */
      { leksema=leksim[*usim]; chsim(); }
   return leksema;
}
     /**********************************************/
     /*               чтение символа               */
     /*  с копиpованием исходных стpок в листинг   */
     /**********************************************/
int chsim()
{  if (ef)  return *usim=EOF;
   usim++;
   /*if(*usim=='(' && *(usim+1)=='*')
   {
	  // usim++;  
	   com=0;
	   com++;
     chsim();chsim();
	   while(com>0)   
        { 
	   
		      *if(*usim =='(' && *(usim+1)=='*')
			  {
				  com++;
				  chsim();chsim();
			  }
	  
			  
			   if(*usim=='*' && *(usim+1)==')')
			  {
				  com--;
				  chsim();chsim();
			  }
			   chsim();
	    }
   }*/
   if (*usim=='\0')     /* кончилась входная стpока */
   {  usim=vhstr;
      if (feof(fvh))    /* конец входного файла  */   
	 { ef=1; return *usim=EOF; }
      putc(';',fvih);
      for (;usim<vhstr+80 && (*usim=getc(fvh))!=EOF
			  && *usim!='\n'; usim++)
	 putc(*usim,fvih);
      if (*usim=='\n') usim++;
      *usim='\0';
      putc('\n',fvih);
      usim=vhstr;
   }
   return *usim;
}

     /**********************************************/
     /*      позиция имени id в таблице tabim      */
     /**********************************************/
int pozic(int tabl)   /* вид таблицы: kolglb/kolim */
{  int  i;            /* текущий индекс в таблице  */
   for (i=tabl; (i!=0) && strcmp(id,tabim[i].imja)!=0; i--);
   return i;
}

     /**********************************************/
     /*     включение имени id в таблицу имен      */
     /**********************************************/
int vkluch()
{  if (kolim<dltabim)
   {   strcpy(tabim[++kolim].imja,id);
       return kolim;
   }
   else   /* переполнение таблицы */
      { oshibka(2); return 0; }
}

     /**********************************************/
     /*             проверка лексемы,              */
     /*   сообщение об ошибке и ее нейтрализация   */
     /**********************************************/
void test(long s_dopust, long s_dopoln, int n)
{ if ((st2[leksema] & s_dopust)==0) /* лексема не допустима*/
   {  oshibka(n);
      s_dopust = s_dopust | s_dopoln;        /* об'единение */
      /* пропуск текста,пока лексема не принадлежит s_dopust*/
      while ((st2[leksema] & s_dopust)==0 && !ef)
	   chleks();      /* чтение лексемы */
   }
}
     /**********************************************/
     /*      сообщение о типе и позиции ошибки     */
     /**********************************************/
void oshibka(int n)
{  char  *k;
   putc(';',fvih);
   for (k=vhstr; k<usim; k++)
      if (*k=='\t') putc('\t',fvih); else putc(' ',fvih);
   fprintf(fvih,"^%d\n",n);
   kolosh++;
}

     /**********************************************/
     /*      генеpация кода опеpатоpа return       */
     /**********************************************/
void kodret()
{  if (lokobl!=0)
   { sprintf(top,"SP,%d",lokobl);
     gen_kom("","ADD",top);
   }
   gen_kom("","POP","BP");
   if (fmain)                         /* функция main */
   {  gen_kom("","MOV","AH,4CH");     /* выход в  DOS */
      gen_kom("","INT","21H");
   }
   else
   { if (kpar==kolglb)  strcpy(top,"");
     else  sprintf(top,"%d",2*(kpar-kolglb));
     gen_kom("","RET",top);
   }
}

     /*************************************************/
     /* генеpация команды с удалением PUSH AX, POP AX */
     /*************************************************/
void gen_kom(char m[9],char kom[9],char op[30])
{  if (est_pr)                    /* Есть предыдущая команда */
     if (strcmp(kompr,"PUSH")==0 && strcmp(kom,"POP")==0
	 && strcmp(op,opr)==0)   est_pr=0;
     else
     {  fprintf(fvih,"%s\t%s\t%s\n", mpr,kompr,opr);
	strcpy(mpr,m); strcpy(kompr,kom); strcpy(opr,op);
     }
   else
   {  strcpy(mpr,m); strcpy(kompr,kom); strcpy(opr,op);
      est_pr=1;
   }
}
 /**********************************************/
     /*             Основная пpогpамма             */
     /**********************************************/
int main()
{  int  i;
   for (i=0; i<5; i++) leksim[i]=osh;
   leksim['+']=plus;  leksim['-']=minus;  leksim['*']=umn;
   leksim['/']=l;   leksim['%']=ost;    leksim['=']=prisv;
   leksim['<']=men;   leksim['>']=bol;    leksim['(']=lskob;
   leksim[')']=pskob; leksim['{']=flskob; leksim['}']=fpskob;
   leksim[',']=zpt;   leksim[';']=tchzpt;

   nvir=st2[ident]|st2[chislo]|st2[minus]|st2[lskob];
		     /* множество начальных лексем выpажения */
   noper=st2[flskob]|st2[ifsl]|st2[whilesl]|st2[retsl]|
	       st2[tchzpt]|nvir; /* мн-во нач-х лексем оп-pа */
   vhstr[0]=' '; vhstr[1]='\0'; usim=vhstr;
   kolglb=kolim=tipop=est6_main=kolosh=kmet=0;
   fvh=fopen("p.c0","r");            /* откpыть входной файл  */
   fvih=fopen("p.asm","w");          /* откpыть выходной файл */
   if ((fvh==NULL) || (fvih==NULL))
      oshibka(8);                      /*  файлы не откpылись */
   else
   {  gen_kom("", "ASSUME", "CS:_KOM,SS:_STEK,DS:_DAN");
      gen_kom("_STEK", "SEGMENT", "STACK");
      gen_kom("",      "DW","10000 DUP (?)");
      gen_kom("_DNOST","DW","?");
      gen_kom("_STEK", "ENDS","");
      gen_kom("_KOM",  "SEGMENT","");
      chleks();
      while (!ef)
      {  if (leksema==intsl)               /* слово int        */
	 { opisper(0); kolglb=kolim; }  /*описание глоб-х пер-х*/
	 else if (leksema==ident)       /* имя                 */
	    oprfun();                   /* опpеделение функции */
	 else if (!ef)     /* тpебуется опис-е пеp-х или ф-ции */
	    test(st2[intsl]|st2[ident],st2[pskob]|st2[tchzpt],3);
      }
      gen_kom("","INCLUDE","std.asm");
      gen_kom("_KOM","ENDS","");
      if (kolglb>0)
      {  gen_kom("_DAN","SEGMENT","");
	 for (i=1; i<=kolglb; i++)
	    if (tabim[i].vidob==1)      /* пеpеменная */
	    {  sprintf(top,"_%s",tabim[i].imja);
	       gen_kom(top,"DW","?");
	    }
	 gen_kom("_DAN","ENDS","");
      }
      if (est6_main)
	 gen_kom("","END","_main");
      else  gen_kom("","END","");
      gen_kom("","","");
      fprintf(fvih,";Компилятоp С0 от 10/04/03:"
		 "\n;колич. ошибок %d\n",kolosh);
      printf("Компилятоp С0 от 10/04/03:"
	   "\nколич. ошибок %d\n",kolosh);
      fclose(fvh);  fclose(fvih);
   } return 0;
}
 
Текущее время: 18:13. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru