Advertisement
Guest User

Untitled

a guest
Apr 27th, 2017
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.52 KB | None | 0 0
  1. /* Синтаксический анализатор рекурсивного спуска
  2. для целочисленных выражений, который содержит
  3. ряд включаемых переменных
  4. */
  5. #include "setjmp.h"
  6. #include "math.h"
  7. #include "ctype.h"
  8. #include "stdlib.h"
  9. #include "stdio.h"
  10. #include <windows.h>
  11. #define  DELIMITER 1
  12. #define  VARIABLE  2
  13. #define  NUMBER    3
  14. #define  COMMAND   4
  15. #define  STRING    5
  16. #define  QUOTE     6
  17. #define  EOL       9
  18. #define  FINISHED  10
  19.  
  20. #define NUM_LAB 100
  21. #define LAB_LEN 10
  22. #define FOR_NEST 25
  23. #define SUB_NEST 25
  24. #define PROG_SIZE 10000
  25.  
  26. #define PRINT 1
  27. #define INPUT 2
  28. #define IF    3
  29. #define THEN  4
  30. #define FOR   5
  31. #define NEXT  6
  32. #define TO    7
  33. #define GOTO  8
  34. #define EOL   9
  35. #define FINISHED 10
  36. #define GOSUB 11
  37. #define RETURN 12
  38. #define END   13
  39. // while modification --------------------------------------------------------
  40. #define WHILE 14
  41. #define DO 15
  42. #define ENDWHILE 16
  43.  
  44.  
  45. char *prog;  /* буфер анализируемого выражения */
  46. jmp_buf e_buf; /* буфер среды функции longjmp() */
  47. variables[26]; /* переменные */
  48. struct commands { /* Просмотр таблицы ключевых слов */
  49.     char command[20];
  50.     char tok;
  51. } table[] = { /* Команда должна вводится прописными */
  52.             "print",PRINT, /* буквами в эту таблицу */
  53.             "input",INPUT,
  54.             "if",IF,
  55.             "then",THEN,
  56.             "goto",GOTO,
  57.             "for",FOR,
  58.             "next",NEXT,
  59.             "to",TO,
  60.             "gosub",GOSUB,
  61.             "return",RETURN,
  62.             "end",END,
  63.             // while modification --------------------------------------------------------
  64.             "while",WHILE,
  65.             "do",DO,
  66.             "endwhile",ENDWHILE,
  67.             "",END  /* Маркер конца таблицы */
  68.             };
  69.  
  70. char token[80]; /* внешнее представление лексемы */
  71. char token_type; /* тип лексемы */
  72. char tok; /* внутреннее представление лексемы */
  73. void get_exp(),level2(),level3(),level4(),level5();
  74. void level6(),primitive(),arith(),unary();
  75. void serror(), putback();
  76.  
  77. /* Точка входа в анализатор. */
  78. void get_exp(result)
  79. int *result;
  80. {
  81. get_token();
  82. if(!*token) {
  83.     serror(2);
  84.     return;
  85. }
  86. level2(result);
  87. putback(); /* возвращает последнюю считаную
  88. лексему обратно во входной поток */
  89. }
  90.  
  91. /* Сложение или вычитание двух термов */
  92. void level2(result)
  93. int *result;
  94. {
  95. register char op;
  96. int hold;
  97.  
  98. level3(result);
  99. while((op=*token) == '+' || op == '-') {
  100.     get_token();
  101.     level3(&hold);
  102.     arith(op,result,&hold);
  103. }
  104. }
  105.  
  106. /* Вычисление произведения или частного двух фвкторов */
  107. void level3(result)
  108. int *result;
  109. {
  110. register char op;
  111. int hold;
  112.  
  113. level4(result);
  114. while((op = *token) == '/' || op == '*' || op == '%') {
  115.     get_token();
  116.     level4(&hold);
  117.     arith(op,result,&hold);
  118. }
  119. }
  120.  
  121. /* Обработка степени числа (целочисленной) */
  122. void level4(result)
  123. int *result;
  124. {
  125. int hold;
  126.  
  127. level5(result);
  128. if(*token== '^') {
  129.     get_token();
  130.     level4(&hold);
  131.     arith('^', result, &hold);
  132. }
  133. }
  134.  
  135. /* Унарный + или - */
  136. void level5(result)
  137. int *result;
  138. {
  139. register char op;
  140.  
  141. op = 0;
  142. if((token_type==DELIMITER) && *token=='+' || *token=='-') {
  143.     op = *token;
  144.     get_token();
  145. }
  146. level6(result);
  147. if(op)
  148.     unary(op, result);
  149. }
  150.  
  151. /* Обработка выражения в круглых скобках */
  152. void level6(result)
  153. int *result;
  154. {
  155. if((*token == '(') && (token_type == DELIMITER)) {
  156.     get_token();
  157.     level2(result);
  158.     if(*token != ')')
  159.     serror(1);
  160.     get_token();
  161. }
  162. else
  163.     primitive(result);
  164. }
  165.  
  166. /* Определение значения переменной по ее имени */
  167. void primitive(result)
  168. int *result;
  169. {
  170. switch(token_type) {
  171.     case VARIABLE:
  172.         *result = find_var(token);
  173.         get_token();
  174.         return;
  175.     case NUMBER:
  176.         *result  = atoi(token);
  177.         get_token();
  178.         return;
  179.     default:
  180.         serror(0);
  181. }
  182. }
  183.  
  184. /* Выполнение специфицированной арифметики */
  185. void arith(o, r, h)
  186. char o;
  187. int *r, *h;
  188. {register int t, ex;
  189.  
  190. switch(o) {
  191.     case '-':
  192.         *r = *r-*h;
  193.         break;
  194.     case '+':
  195.         *r = *r+*h;
  196.         break;
  197.     case '*':
  198.         *r = (*r) * (*h);
  199.         break;
  200.     case '/':
  201.         *r = (*r)/(*h);
  202.         break;
  203.     case '%':
  204.         t = (*r)/(*h);
  205.         *r = *r-(t*(*h));
  206.         break;
  207.     case '^':
  208.         ex =*r;
  209.         if(*h==0) {
  210.             *r = 1;
  211.             break;
  212.         }
  213.         for(t=*h-1; t>0; --t) *r = (*r) * ex;
  214.         break;
  215. }
  216. }
  217.  
  218. /* Изменение знака */
  219. void unary(o, r)
  220. char o;
  221. int *r;
  222. {
  223. if(o=='-') *r = -(*r);
  224. }
  225.  
  226. /* Поиск значения переменной */
  227. int find_var(s)
  228. char *s;
  229. {
  230. if(!isalpha(*s)){
  231.     serror(4); /* не переменная */
  232.     return 0;
  233. }
  234. return variables[toupper(*token)-'A'];
  235. }
  236.  
  237. /* выдать сообщение об ошибке */
  238. void serror(error)
  239. int error;
  240. {
  241. static char *e[]= {
  242.     "Синтаксическая ошибка",
  243.     "Непарные круглые скобки",
  244.     "Это не выражение",
  245.     "Предполагается символ равенства",
  246.     "Не переменная",
  247.     "Таблица меток переполнена",
  248.     "Дублирование меток",
  249.     "Неопределенная метка",
  250.     "Необходим оператор THEN",
  251.     "Необходим оператор TO",
  252.     "Уровень вложенности цикла FOR слишком велик",
  253.     "NEXT не соответствует FOR",
  254.     "Уровень вложенности GOSUB слишком велик",
  255.     "RETURN не соответствует GOSUB",
  256.     // while modification --------------------------------------------------------
  257.     "Необходим оператор DO",
  258.     "Уровень вложенности цикла WHILE слишком велик",
  259.     "ENDWHILE не соответствует WHILE",
  260. };
  261. printf("%s\n",e[error]);
  262. longjmp(e_buf, 1); /* возврат в точку сохранения */
  263. }
  264.  
  265. /* Чтение лексемы. */
  266. get_token()
  267. {
  268.     register char *temp;
  269.     token_type=0; tok=0;
  270.     temp=token;
  271.  
  272.     if(*prog=='\0') { /* Конец файла */
  273.         *token=0;
  274.         tok = FINISHED;
  275.         return(token_type=DELIMITER);
  276.     }
  277.     while(iswhite(*prog)) ++prog; /* пропуск пробелов */
  278.  
  279.     if(*prog=='\r') { /* коней строки программы */
  280.         ++prog; ++prog;
  281.         tok = EOL; *token='\r';
  282.         token[1]='\n'; token[2]=0;
  283.         return (token_type = DELIMITER);
  284.     }
  285.  
  286.     if(strchr("+-^/%=;*(),><", *prog)){ /* разделитель */
  287.         *temp=*prog;
  288.         prog++; /* переход на следующую позицию */
  289.         temp++;
  290.         *temp=0;
  291.         return (token_type=DELIMITER);
  292.     }
  293.  
  294.     if(*prog=='"') { /* строка кавычек */
  295.         prog++;
  296.         while(*prog != '"' && *prog!='\r') *temp++=*prog++;
  297.         if(*prog=='\r') serror(1);
  298.         prog++;*temp=0;
  299.         return(token_type=QUOTE);
  300.     }
  301.  
  302.     if(isdigit(*prog)) { /* число */
  303.         while(!isdelim(*prog)) *temp++=*prog++;
  304.         *temp = '\0';
  305.         return(token_type = NUMBER);
  306.     }
  307.  
  308.     if(isalpha(*prog)) { /* переменная или команда */
  309.         while(!isdelim(*prog)) *temp++=*prog++;
  310.         token_type=STRING;
  311.     }
  312.  
  313.     *temp = '\0';
  314.  
  315.     /* просматривается, если строка - переменная или команда */
  316.     if (token_type==STRING) {
  317.         tok=look_up(token); /* Преобразование во внутренний формат */
  318.         if (!tok) token_type = VARIABLE;
  319.         else token_type = COMMAND; /* это команда */
  320.     }
  321.     return token_type;
  322. }
  323.  
  324. /* Возврат лексемы во входной поток */
  325. void putback()
  326. {
  327.     char *t;
  328.     t = token;
  329.     for(; *t; t++) prog--;
  330. }
  331.  
  332. /* Поиск соответствия внутреннего формата для
  333. текущей лексемы в таблице лексем.
  334. */
  335. look_up(s)
  336. char *s;
  337. {
  338.     register int i,j;
  339.     char *p;
  340.  
  341.     /* преобразование к нижнему регистру */
  342.     p = s;
  343.     while(*p){ *p = tolower(*p); p++; }
  344.  
  345.     /* просматривается, если лексема обнаружена в
  346.     таблице */
  347.     for(i=0; *table[i].command; i++)
  348.     if(!strcmp(table[i].command, s)) return table[i].tok;
  349.     return 0; /* нераспознанная команда */
  350. }
  351.  
  352. /* Возвращает "истину", если "c" разделитель */
  353. isdelim(c)
  354. char c;
  355. {
  356.     if(strchr(" ;,+-<>/*%^=()",c) || c==9 || c=='\r' || c==0)
  357.     return 1;
  358.     return 0;
  359. }
  360.  
  361. /* Возвращает 1, если "с" пробел или табуляция */
  362. iswhite(c)
  363. char c;
  364. {
  365.     if(c==' ' || c=='\t') return 1;
  366.     else return 0;
  367. }
  368.  
  369. int variables[26]= {   /* 26 переменных пользователя A - Z */
  370. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  371. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  372. 0, 0, 0, 0, 0, 0
  373. };
  374.  
  375. struct label {
  376.     char name[LAB_LEN];
  377.     char *p; /*      */
  378. };
  379. struct label label_table[NUM_LAB];
  380.  
  381. char *find_label(), *gpop();
  382.  
  383. struct for_stack {
  384.     int var; /* переменная счетчика */
  385.     int target; /* конечное значение */
  386.     char *loc;
  387. } fstack[FOR_NEST]; /* стек цикла FOR/NEXT */
  388. struct for_stack fpop();
  389. // while modification --------------------------------------------------------
  390. struct while_stack {
  391.     char *loc;
  392. } wstack[FOR_NEST]; /* стек цикла WHILE/ENDWHILE */
  393. struct while_stack wpop();
  394.  
  395. char *gstack[SUB_NEST]; /* стек оператора GOSUB */
  396. int ftos; /* индекс начала стека FOR */
  397. // while modification --------------------------------------------------------
  398. int wtos; /* индекс начала стека WHILE */
  399. int gtos; /* индекс начала стека GOSUB */
  400.  
  401. void print(), scan_labels(), find_eol(),exec_goto();
  402. void exec_if(), exec_for(), next(), fpush(), input();
  403. // while modification --------------------------------------------------------
  404. void exec_while(), exec_endwhile(), wpush();
  405. void gosub(), greturn(), gpush(), label_init();
  406.  
  407. int main(int argc,char * argv[])
  408. {
  409.     SetConsoleOutputCP(1251);
  410.     SetConsoleCP(1251);
  411.     char in[80];
  412.     int answer;
  413.     char *p_buf;
  414.     char *t;
  415.  
  416.     if(argc!=2) {
  417.     printf("Используйте формат: run <filename>\n");
  418.     exit(1);
  419.     }
  420.  
  421.     /* Выделение памяти для программы */
  422.     if (!(p_buf=(char *) malloc(PROG_SIZE))) {
  423.     printf("Ошибка при выделении памяти ");
  424.     exit(1);
  425.     }
  426.  
  427.     /* Загрузка программы для выполнения */
  428.     if(!load_program(p_buf,argv[1])){ exit(1);}
  429.     if(setjmp(e_buf)) exit(1); /* инициализация буфера
  430.     нелокальных переходов */
  431.     prog = p_buf;
  432.     scan_labels(); /* поиск метки в программе */
  433.  
  434.     ftos = 0; /* инициализация индеса стека FOR */
  435.     gtos = 0; /* инициализация индеса стека GOSUB */
  436.     do {
  437.     token_type = get_token();
  438.     /* проверка на оператор присваивания */
  439.     if(token_type==VARIABLE) {
  440.     putback(); /* возврат пер. обратно во входной поток */
  441.     assigment(); /* должен быть оператор присваивания */
  442.     }
  443.     else /* это команда */
  444.         switch(tok) {
  445.             case PRINT:
  446.                 print();
  447.                 break;
  448.             case IF:
  449.                 exec_if();
  450.                 break;
  451.             case FOR:
  452.                 exec_for();
  453.                 break;
  454.             case NEXT:
  455.                 next();
  456.                 break;
  457.             // while modification --------------------------------------------------------
  458.             case WHILE:
  459.                 exec_while();
  460.                 break;
  461.             case ENDWHILE:
  462.                 exec_endwhile();
  463.                 break;
  464.             case INPUT:
  465.                 input();
  466.                 break;
  467.             case GOSUB:
  468.                 gosub();
  469.                 break;
  470.             case RETURN:
  471.                 greturn();
  472.                 break;
  473.             case END:
  474.                 exit(0);
  475.         }
  476.     } while (tok != FINISHED);
  477. }
  478.  
  479. /* Загрузка программы. */
  480. load_program(char * p,char * fname)
  481. {
  482.     FILE *fp;
  483.     int i=0;
  484.     if(!(fp=fopen(fname, "rb"))) return 0;
  485.  
  486.     i = 0;
  487.     do {
  488.         *p = getc(fp);
  489.         p++; i++;
  490.     } while(!feof(fp) && i<PROG_SIZE);
  491.     *(p-2) = '\0'; /* символ конца программы */
  492.     fclose(fp);
  493.     return 1;
  494. }
  495.  
  496. /* Присваивание переменной значения */
  497. assigment()
  498. {
  499.     int var, value;
  500.     /* Получить имя переменной */
  501.     get_token();
  502.     if(!isalpha(*token)) {
  503.         serror(4); /* это не переменная */
  504.         return;
  505.     }
  506.  
  507.     /* вычисление индекса переменной */
  508.     var = toupper(*token)-'A';
  509.  
  510.     /* получить знак равенства */
  511.     get_token();
  512.     if(*token!='=') {
  513.         serror(3);
  514.         return;
  515.     }
  516.  
  517.     /* получить значение, присвоенное переменной */
  518.     get_exp(&value);
  519.  
  520.     /* присвоить это значение */
  521.     variables[var] = value;
  522. }
  523.  
  524. /* Простейшая реализация оператора PRINT */
  525. void print()
  526.     {
  527.     int answer;
  528.     int len=0, spaces;
  529.     char last_delim;
  530.  
  531.     do
  532.     {
  533.         get_token(); /* получить следующий элемент списка  */
  534.         if(tok==EOL || tok==FINISHED) break;
  535.  
  536.         if(token_type==QUOTE)
  537.         { /* это строка */
  538.             printf(token);
  539.             len += strlen(token);
  540.             get_token();
  541.         }
  542.         else
  543.         { /* это выражение */
  544.             putback();
  545.             get_exp(&answer);
  546.             get_token();
  547.             len +=printf("%d", answer);
  548.         }
  549.         last_delim = *token;
  550.  
  551.         if(*token==';')
  552.         {
  553.             /* вычисление числа пробелов при переходе к следующей табуляции*/
  554.             spaces= 8- (len % 8);
  555.             len += spaces; /* включая позицию табуляции  */
  556.             while(spaces) {
  557.             printf(" ");
  558.             spaces--;
  559.         }
  560.         }
  561.         else if(*token==','); /* ничего не делать */
  562.         else if(tok!=EOL && tok!=FINISHED)  { serror(0);}
  563.     } while (*token == ';' || *token == ',');
  564.  
  565.     if(tok==EOL || tok==FINISHED) {
  566.     if(last_delim != ';' && last_delim != ',') printf("\n");
  567.     }
  568.     else { serror(0);} /* отсутствует ',' или ';'  */
  569. }
  570. /* Поиск всех меток */
  571. void scan_labels()
  572. {
  573.     int addr;
  574.     char *temp;
  575.  
  576.     label_init();  /* обнуление всех меток */
  577.     temp = prog; /* сохраним указатель на начало программы*/
  578.     /* Если первая лексема файла есть метка  */
  579.     get_token();
  580.     if(token_type==NUMBER) {
  581.         strcpy(label_table[0].name,token);
  582.         label_table[0].p=prog;
  583.     }
  584.  
  585.     find_eol();
  586.     do {
  587.         get_token();
  588.         if(token_type==NUMBER) {
  589.             addr =get_next_label(token);
  590.             if(addr==-1 || addr==-2) {
  591.                 (addr==-1) ?serror(5):serror(6);
  592.             }
  593.  
  594.             strcpy(label_table[addr].name, token);
  595.             label_table[addr].p = prog; /* текущий указатель программы */
  596.         }
  597.         /* если строка не помечена, то поиск следующей */
  598.         if(tok!=EOL) find_eol();
  599.     } while(tok!=FINISHED);
  600.     prog = temp; /* сохраним оригинал */
  601. }
  602.  
  603. /* Поиск начала следующей строки */
  604. void find_eol()
  605. {
  606.     while(*prog!='\n'  && *prog!='\0') ++prog;
  607.     if(*prog) prog++;
  608. }
  609.  
  610. /* Возвращает индекс на следующую свободную позицию
  611. массива меток. -1, если массив переполнен.
  612. -2, если дублирование меток. */
  613.  
  614. get_next_label(char *s)
  615. {
  616.     register int t;
  617.  
  618.     for(t=0;t<NUM_LAB;++t) {
  619.     if(label_table[t].name[0]==0) return t;
  620.     if(!strcmp(label_table[t].name,s)) return -2; /*дубль*/
  621.     }
  622.  
  623.     return -1;
  624. }
  625.  
  626. /* Поиск строки по известной метке. Значение 0 возвращается,
  627. если метка не найдена; в противном случае возвращается
  628. указатель на помеченную строку программы        */
  629.  
  630. char *find_label(char * s)
  631. {
  632.     register int t;
  633.  
  634.     for(t=0; t<NUM_LAB; ++t)
  635.     if(!strcmp(label_table[t].name,s)) return label_table[t].p;
  636.     return '\0'; /* состояние ошибки */
  637. }
  638.  
  639. /* Реализация оператора GOTO */
  640. void exec_goto()
  641. {
  642.     char *loc;
  643.  
  644.     get_token(); /* получить метку перехода */
  645.     /* Поиск местоположения метки */
  646.     loc = find_label(token);
  647.     if(loc=='\0')
  648.     serror(7);   /* метка не обнаружена  */
  649.     else prog=loc; /* старт программы с указанной точки  */
  650. }
  651.  
  652. /* Инициализация массива хранения меток. По договоренности
  653. нулевое значение метки символизирует пустую ячейку массива */
  654. void label_init()
  655. {
  656.     register int t;
  657.  
  658.     for(t=0; t<NUM_LAB; ++t) label_table[t].name[0]='\0';
  659. }
  660.  
  661. /* Реализация оператора IF  */
  662. void exec_if()
  663. {
  664.     int x , y, cond;
  665.     char op;
  666.     get_exp(&x); /* получить левое выражение */
  667.     get_token(); /* получить оператор */
  668.     if(!strchr("=<>", *token)) {
  669.         serror(0);      /* недопустимый оператор */
  670.         return;
  671.     }
  672.     op=*token;
  673.     get_exp(&y);  /* получить правое выражение */
  674.     /* Определение результата */
  675.     cond=0;
  676.     switch(op) {
  677.         case '=':
  678.             if(x==y) cond=1;
  679.             break;
  680.         case '<':
  681.             if(x<y) cond=1;
  682.             break;
  683.         case '>':
  684.             if(x>y) cond=1;
  685.             break;
  686.     }
  687.     if(cond) {  /* если значение IF "истина"  */
  688.         get_token();
  689.         if(tok!=THEN) {
  690.             serror(8);
  691.             return;
  692.         } /* иначе, программа выполняется со следующей строки */
  693.     }
  694.     else find_eol(); /* поиск точки старта программы */
  695. }
  696.  
  697. /* Реализация цикла FOR */
  698. void exec_for()
  699. {
  700.     struct for_stack i;
  701.     int value;
  702.  
  703.     get_token(); /* получить управляющую переменную */
  704.     if(!isalpha(*token)) {
  705.         serror(4);
  706.         return;
  707.     }
  708.     i.var=toupper(*token)-'A'; /* сохранить ее индекс */
  709.     get_token(); /* получить знак равенства */
  710.     if(*token!='=') {
  711.         serror(3);
  712.         return;
  713.     }
  714.     get_exp(&value); /* получить начальное значение  */
  715.     variables[i.var]=value;
  716.  
  717.     get_token();
  718.     if(tok!=TO) serror(9); /* если нее нашли TO */
  719.     get_exp(&i.target); /* получить конечное значение */
  720.  
  721.     /* Если цикл выполняется последний раз, поместить
  722.     информацию в стек  */
  723.     if(i.target>=variables[i.var]) {
  724.         i.loc = prog;
  725.         fpush(i);
  726.     }
  727.     else /* пропустить весь цикл */
  728.     while(tok!=NEXT) get_token();
  729. }
  730.  
  731. // while modification --------------------------------------------------------
  732. /* Реализация цикла WHILE */
  733. void exec_while()
  734. {
  735.     struct while_stack i;
  736.     i.loc = prog;
  737.     int x , y, cond;
  738.     char op;
  739.     get_exp(&x); /* получить левое выражение */
  740.     get_token(); /* получить оператор */
  741.     if(!strchr("=<>", *token)) {
  742.         serror(0);      /* недопустимый оператор */
  743.         return;
  744.     }
  745.     op=*token;
  746.     get_exp(&y);  /* получить правое выражение */
  747.     /* Определение результата */
  748.     cond=0;
  749.     switch(op) {
  750.         case '=':
  751.             if(x==y) cond=1;
  752.             break;
  753.         case '<':
  754.             if(x<y) cond=1;
  755.             break;
  756.         case '>':
  757.             if(x>y) cond=1;
  758.             break;
  759.     }
  760.     if(cond) {  /* если значение WHILE "истина"  */
  761.         get_token();
  762.         if(tok!=DO) {
  763.             serror(14);
  764.             return;
  765.         } /* иначе, программа выполняется со следующей строки */
  766.         wpush(i);
  767.     }
  768.     else while(tok!=ENDWHILE) get_token();
  769. }
  770.  
  771. /* Реализация оператора NEXT */
  772. void next()
  773. {
  774.     struct for_stack i;
  775.     i = fpop(); /* чтение информации о цикле */
  776.  
  777.     variables[i.var]++; /* увеличение управляющей переменной*/
  778.     if(variables[i.var]>i.target) return; /* конец цикла */
  779.     fpush(i); /* иначе, сохранить информацию в стеке */
  780.     prog = i.loc; /* цикл */
  781. }
  782.  
  783. /* Поместить информацию в стек FOR */
  784. void fpush(struct for_stack i)
  785. {
  786.     if(ftos>FOR_NEST)
  787.         serror(10);
  788.     fstack[ftos]=i;
  789.     ftos++;
  790. }
  791.  
  792. struct for_stack fpop()
  793. {
  794.     ftos--;
  795.     if(ftos<0) serror(11);
  796.     return(fstack[ftos]);
  797. }
  798.  
  799. // while modification --------------------------------------------------------
  800. /* Реализация оператора ENDWHILE */
  801. void exec_endwhile()
  802. {
  803.     struct while_stack i;
  804.     i = wpop(); /* чтение информации о цикле */
  805.  
  806.     prog = i.loc; /* цикл */
  807.     exec_while();
  808. }
  809.  
  810. /* Поместить информацию в стек WHILE */
  811. void wpush(struct while_stack i)
  812. {
  813.     if(wtos>FOR_NEST)
  814.         serror(15);
  815.     wstack[wtos]=i;
  816.     wtos++;
  817. }
  818.  
  819. struct while_stack wpop()
  820. {
  821.     wtos--;
  822.     if(wtos<0) serror(16);
  823.     return(wstack[wtos]);
  824. }
  825.  
  826. /* Реализация оператора INPUT */
  827. void input()
  828. {
  829.     char str[80], var;
  830.     int i;
  831.  
  832.     get_token(); /*просматривается если существует строка символов*/
  833.     if(token_type==QUOTE) {
  834.         printf(token); /* если да, то ее печать и контроль ',' */
  835.         get_token();
  836.         if(*token!=',') serror(1);
  837.         get_token();
  838.     }
  839.     else printf("? "); /* выдача строки по умолчанию */
  840.     var = toupper(*token)-'A'; /* получить индекс имени переменной*/
  841.     scanf("%d",&i);   /* чтение ввода данных */
  842.     variables[var] = i;  /* сохранение данных */
  843. }
  844.  
  845. /* Реализация оператора GOSUB */
  846. void gosub()
  847. {
  848.     char *loc;
  849.  
  850.     get_token();
  851.     /* поиск метки вызова */
  852.     loc = find_label(token);
  853.     if(loc=='\0')
  854.         serror(7); /* метка не определена */
  855.     else {
  856.         gpush(prog); /* запомним место, куда вернемся */
  857.         prog = loc; /* старт программы с указанной точки */
  858.     }
  859. }
  860.  
  861. /* Возврат из подпрограммы, вызванной по GOSUB */
  862. void greturn()
  863. {
  864.     prog = gpop();
  865. }
  866.  
  867. /* Помещает данные в стек GOSUB */
  868. void gpush(char * s)
  869. {
  870.     gtos++;
  871.     if(gtos==SUB_NEST) {
  872.         serror(12);
  873.         return;
  874.     }
  875.     gstack[gtos]=s;
  876. }
  877.  
  878. /*   */
  879. char *gpop()
  880. {
  881.     if(gtos==0) {
  882.         serror(13);
  883.         return;
  884.     }
  885.     return(gstack[gtos--]);
  886. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement