Advertisement
Guest User

Untitled

a guest
Jan 29th, 2015
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.51 KB | None | 0 0
  1. #include<stdio.h>  // 3 ЛАБА
  2. #include<malloc.h>
  3. #include<stdlib.h>
  4. #include<ctype.h>
  5. #include<math.h>
  6. #include<string.h>
  7.  
  8. const char *ERRORS[] =  {
  9.     "File '%s' doesn`t exist or can`t be open!\n",
  10.     "Memory error! %s\n",
  11.     "Empty stack! %s\n",
  12.     "Can`t divide by zero! %s\n",
  13.     "Empty file! %s\n",
  14.     "Base hasn`t this number! %s\n",
  15.     "`}` was found, but comment hasn`t yet been closed! %s\n"
  16. } ;
  17.  
  18. void push(struct stack**, int);
  19. int top(struct stack*);
  20. void pop(struct stack**);
  21. int prioritet(char);
  22. void Error(int, char*);
  23. void intToStr(int, int, char*);
  24. int strToInt(char*, int);
  25. int calc(int, int, char);
  26.  
  27. struct stack {
  28.     int data;
  29.     struct stack *next;
  30. };
  31.  
  32. FILE *fIn = NULL, *fOut = NULL;
  33.  
  34. void main(int argc, char *argv[]) {
  35.     struct stack *st = NULL, *stNum = NULL;
  36.     char c, c_ = ' ', mbuf[BUFSIZ], *mb = mbuf, buf[33], *b = buf, *sIn = "data.in", *ssIn = sIn, *sOut = "data.out";
  37.     int base = 10, i, num1, num2, reg[26], tr = 1, comment = 0, k;
  38.     for (i = 0; i < argc; i++)
  39.         if (strstr(argv[i], "tr="))
  40.             if (strstr(argv[i], "false"))
  41.                 tr = 0;
  42.     /*if(strstr(argv[i], "if="))
  43.     strcpy(sIn, argv[i] + 3) ;
  44.     if(strstr(argv[i], "of="))
  45.     strcpy(sOut, argv[i] + 3) ;*/
  46.     if (!(fIn = fopen(sIn, "r")))
  47.         Error(0, sIn);
  48.     if (!(fOut = fopen(sOut, "w")))
  49.         fclose(fIn), Error(0, sOut);
  50.     push(&st, '(');
  51.     while (!feof(fIn)) {
  52.         fgets(mb, BUFSIZ, fIn);
  53.         if ((int)*mb == -52)
  54.             Error(4, "");
  55.         if (strstr(mb, "#"))
  56.             *strstr(mb, "#") = 0;
  57.         if (strstr(mb, "{"))
  58.             *strstr(mb, "{") = 0, comment = 1;
  59.         if (strstr(mb, "}")) {
  60.             if(comment)
  61.                 mb = strstr(mb, "}") + 1, comment = 0;
  62.             else
  63.                 Error(6, "") ;
  64.         } ;
  65.         if (!strcmp(mb, "\n") || !strcmp(mb, ""))
  66.             continue;
  67.         if (comment == 1)
  68.             continue;
  69.         if (strstr(mb, "sys")) {
  70.             mb[strlen(mb) - 1] = 0; //убираем символ конца строки
  71.             base = strToInt(mb + 4, 10);
  72.             continue;
  73.         }
  74.         else if (toupper(*mb) >= 'A' && toupper(*mb) <= 'Z' && *(mb + 1) == '=') {
  75.             mb[strlen(mb) - 1] = 0;  // убираем символ конца строки
  76.             reg[toupper(*mb) - 'A'] = strToInt(mb + 2, base); // заносим в массив регистров число
  77.             continue;
  78.         };
  79.         if (strstr(mb, "\n"))
  80.             *strstr(mb, "\n") = 0;
  81.         fprintf(fOut, "%s = ", mb);
  82.         for (i = 0; i < strlen(mb); i++) {
  83.             c = mb[i];
  84.             if (isalpha(c)) {
  85.                 push(&stNum, reg[toupper(c) - 'A']);
  86.                 if (tr)
  87.                     fprintf(fOut, "%d ", reg[toupper(c) - 'A']);
  88.             }
  89.             else if (isdigit(c) || c == '~')
  90.                 *b++ = c;
  91.             else if (isdigit(c_)) {
  92.                 *b = 0;
  93.                 b = buf; //ставим на начало указатель
  94.                 push(&stNum, strToInt(b, base));
  95.                 if (tr)
  96.                     fprintf(fOut, "%s ", b);
  97.             };
  98.             if (c == '(')
  99.                 push(&st, '(');
  100.             else if (c == ')') {
  101.                 while (top(st) != '(') {
  102.                     if (tr)
  103.                         fprintf(fOut, "%c ", top(st));
  104.                     num2 = top(stNum);
  105.                     pop(&stNum);
  106.                     num1 = top(stNum);
  107.                     pop(&stNum);
  108.                     push(&stNum, calc(num1, num2, top(st)));
  109.                     pop(&st);
  110.                 };
  111.                 pop(&st);
  112.             }
  113.             else if (prioritet(c)) {
  114.                 while (prioritet(c) <= prioritet(top(st))) {
  115.                     if (tr)
  116.                         fprintf(fOut, "%c ", top(st));
  117.                     num2 = top(stNum);
  118.                     pop(&stNum);
  119.                     num1 = top(stNum);
  120.                     pop(&stNum);
  121.                     push(&stNum, calc(num1, num2, top(st)));
  122.                     pop(&st);
  123.                 };
  124.                 push(&st, c);
  125.             };
  126.             c_ = c;
  127.         };
  128.         if (isdigit(c_)) {
  129.             *b = 0;
  130.             b = buf;
  131.             push(&stNum, strToInt(b, base));
  132.             if (tr)
  133.                 fprintf(fOut, "%s ", b);
  134.         };
  135.         while (top(st) != '(') {
  136.             if (tr)
  137.                 fprintf(fOut, "%c ", top(st));
  138.             num2 = top(stNum);
  139.             pop(&stNum);
  140.             num1 = top(stNum);
  141.             pop(&stNum);
  142.             push(&stNum, calc(num1, num2, top(st)));
  143.             pop(&st);
  144.         };
  145.         intToStr(top(stNum), base, b);
  146.         if (tr)
  147.             fprintf(fOut, "= ");
  148.         fprintf(fOut, "%s\n", b);
  149.         pop(&stNum);
  150.     };
  151.     pop(&st) ;
  152.     fclose(fIn) ;
  153.     fclose(fOut) ;
  154. }
  155.  
  156. void push(struct stack **st, int c) {
  157.     struct stack *newS;
  158.     newS = (struct stack*) malloc(sizeof(struct stack));
  159.     if (!newS)
  160.         Error(1, "");
  161.     newS->data = c;
  162.     newS->next = *st;
  163.     *st = newS;
  164. }
  165.  
  166. void pop(struct stack **st) {
  167.     struct stack *oldS = *st;
  168.     if (!oldS)
  169.         Error(2, "");
  170.     *st = (*st)->next;
  171.     free(oldS);
  172. }
  173.  
  174. int top(struct stack *st) {
  175.     return st->data;
  176. }
  177.  
  178. int prioritet(char op) {
  179.     return (op == '^') ? 3 : (op == '+' || op == '-') ? 1 : (op == '*' || op == '/') ? 2 : 0;
  180. }
  181.  
  182. void Error(int nErr, char *s) {
  183.     printf("Error #%d! ", nErr + 1);
  184.     printf(ERRORS[nErr], s);
  185.     if (nErr != 1)
  186.         fclose(fIn), fclose(fOut);
  187.     exit(nErr + 1);
  188. }
  189.  
  190. void intToStr(int num, int base, char *convertNum) {
  191.     int rest, k = 0, addMinus = 0;
  192.     unsigned number;
  193.     char n[BUFSIZ], *nu = n + BUFSIZ - 1;
  194.     *nu-- = 0;
  195.     if (num < 0) {
  196.         number = -num;
  197.         addMinus = 1;
  198.     }
  199.     else
  200.         number = num;
  201.     while (number)
  202.         *nu-- = ((rest = number % base) < 10) ? rest + '0' : rest + 'A' - 10, number /= base;
  203.     if (addMinus)
  204.         *convertNum++ = '-';
  205.     while (*nu++)
  206.         *convertNum++ = *nu;
  207. }
  208.  
  209. int strToInt(char *num, int base) {
  210.     int res = 0, addMinus = 0;
  211.     char *s = num;
  212.     if (*s == '~')
  213.         s++;
  214.     while (*s)
  215.         if (*s++ - '0' >= base)
  216.             Error(5, "");
  217.     if (*num == '~')
  218.         addMinus = 1;
  219.     else
  220.         num--;
  221.     while (*++num)
  222.         res = res * base + (isdigit(*num) ? *num - '0' : toupper(*num) - 'A' + 10);
  223.     return addMinus ? -res : res;
  224. }
  225.  
  226. int calc(int a, int b, char op) {
  227.     switch (op) {
  228.     case '+': return a + b;
  229.     case '-': return a - b;
  230.     case '*': return a * b;
  231.     case '/': {
  232.         if (b != 0)
  233.             return a / b;
  234.         else
  235.             Error(3, "");
  236.     };
  237.     case '^': return pow((double)a, b);
  238.     };
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement