Advertisement
Ae_Mc

Syscall's calc

Dec 10th, 2019
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.94 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <ctype.h>
  5. #include <string.h>
  6.  
  7. typedef enum operation_type{
  8.     plus, minus,
  9.     times, divide
  10. } operation_type;
  11.  
  12. typedef struct operation{
  13.     operation_type type;
  14.     double *lnum, *rnum;
  15.     int priority;
  16.     struct operation *next;
  17. } operation;
  18.  
  19. double evop(operation_type type, double lnum, double rnum){
  20.     switch(type){
  21.         case plus:
  22.             return lnum + rnum;
  23.         case minus:
  24.             return lnum - rnum;
  25.         case times:
  26.             return lnum * rnum;
  27.         case divide:
  28.             return lnum / rnum;
  29.     }
  30. }
  31.  
  32. void ev(operation **root){
  33.     if((*root) -> next && (*root) -> next -> priority > (*root) -> priority)
  34.         ev(&(*root) -> next);
  35.     * (*root) -> lnum = evop((*root) -> type, * (*root) -> lnum, * (*root) -> rnum);
  36.     free((*root) -> rnum);
  37.     if((*root) -> next){
  38.         (*root) -> next -> lnum = (*root) -> lnum;
  39.         (*root) = (*root) -> next;
  40.         ev(root);
  41.         free(root);
  42.     }
  43. }
  44.  
  45. int main(){
  46.     char *exprMem = malloc(sizeof(char)), *expr = exprMem;
  47.     assert(scanf("%100[^\n]", &expr));
  48.     char *end = strlen(expr) + expr;
  49.     double result;
  50.     operation *opptr, *root = malloc(sizeof(operation));
  51.     opptr = root;
  52.     root -> lnum = &result;
  53.     int adpr = 0;   //Additional priority
  54.     while(expr <= end && (isspace(*expr) || *expr == '(')){
  55.         if(*expr == '(') adpr += 2;
  56.     }
  57.     sscanf(expr, "%lf", root -> lnum);
  58.     while(expr <= end){
  59.         expr += strspn(expr, ".0123456789");
  60.         opptr -> next = malloc(sizeof(operation));
  61.         opptr -> next -> lnum = opptr -> rnum;
  62.         opptr = opptr -> next;
  63.         opptr -> next = NULL;
  64.         opptr -> rnum = malloc(sizeof(double));
  65.         while(expr <= end && (isspace(*expr) || *expr == ')')){
  66.             if(*expr == ')') adpr -= 2;
  67.         }
  68.         char op;
  69.         expr += sscanf(expr, "%c", &op); //symbol is 1 byte long, so if pattern was read, there was only one byte
  70.         switch(op){
  71.             case '+':
  72.                 opptr -> type = plus;
  73.                 opptr -> priority = 0 + adpr;
  74.                 break;
  75.             case '-':
  76.                 opptr -> type = minus;
  77.                 opptr -> priority = 0 + adpr;
  78.                 break;
  79.             case '*':
  80.                 opptr -> type = times;
  81.                 opptr -> priority = 1 + adpr;
  82.                 break;
  83.             case ':':
  84.             case '/':
  85.                 opptr -> type = divide;
  86.                 opptr -> priority = 1 + adpr;
  87.                 break;
  88.             default:
  89.                 fprintf(stderr, "Error, operation %c is not allowed!", op);
  90.         }
  91.         while(expr <= end && (isspace(*expr) || *expr == '(')){
  92.             if(*expr == '(') adpr += 2;
  93.         }
  94.         expr += sscanf(expr, "%lf", opptr -> rnum);
  95.     }
  96.     ev(&root);
  97.     free(root);
  98.     free(exprMem);
  99.     printf("=%lf\n", result);
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement