Advertisement
Guest User

RPN.C

a guest
Jan 31st, 2014
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.75 KB | None | 0 0
  1. /* rpn.c - implementation reverse polish notation */
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <stdlib.h>
  5. #include <stdbool.h>
  6. #include <errno.h>
  7.  
  8. #define STACK_DEPTH 16
  9.  
  10. // operations
  11. #define ADD 0
  12. #define SUB 1
  13. #define MUL 2
  14. #define DIV 3
  15.  
  16.  
  17.  
  18. // *ups*)
  19. #define UNDEF_V   -1 // undefined value
  20. #define STACK_OF  -2 // stack overflow
  21. #define STACK_NEO -3 // not enough operands in stack
  22.  
  23. void   print_help();
  24. double calculate(char *expr);
  25. double gettok(char **expr);
  26.  
  27. void o_add(double *st, int *top);
  28. void o_sub(double *st, int *top);
  29. void o_mul(double *st, int *top);
  30. void o_div(double *st, int *top);
  31.  
  32. void (*operations[])(double *st, int *top) = { o_add, o_sub, o_mul, o_div };
  33. bool is_end_expr = false;
  34. bool is_value; // for calculate(). if true,
  35.                // then gettok() return value, otherwise operation
  36.  
  37. int main(int argc, char **argv) {
  38.     if (argc >= 3 || argc == 1) {
  39.         print_help();
  40.         return 0;
  41.     }
  42.  
  43.     double res = calculate(argv[1]);
  44.  
  45.     if (errno == UNDEF_V) {
  46.         printf("ERROR: Undefined value!\n");
  47.         return UNDEF_V;
  48.     }
  49.     else if (errno == STACK_NEO) {
  50.         printf("ERROR: Not enough operands for operation\n");
  51.         return STACK_NEO;
  52.     }
  53.     else if (errno == STACK_OF) {
  54.         printf("ERROR: Stack overflow(max %d)\n", STACK_DEPTH);
  55.         return STACK_OF;
  56.     }
  57.  
  58.     printf("Result: ");
  59.     if ((int)res == res)
  60.         printf("%d\n", (int)res);
  61.     else
  62.         printf("%.3f\n", res);
  63.  
  64.     return 0;
  65. }
  66.  
  67. void print_help() {
  68.     printf("Usage: rpn \"rpn_expression\"\n");
  69. }
  70.  
  71. double calculate(char *expr) {
  72.     double stack[STACK_DEPTH];
  73.     int top = -1;
  74.     double tok;
  75.  
  76.     do {
  77.         tok = gettok(&expr);
  78.         if (is_value) {
  79.             if (top + 1 >= STACK_DEPTH) {
  80.                 errno = STACK_OF;
  81.                 return -1;
  82.             }
  83.             stack[++top] = tok;
  84.         }
  85.         else {
  86.             int op = tok;
  87.             switch (op) {
  88.                 case ADD:
  89.                 case SUB:
  90.                 case MUL:
  91.                 case DIV:
  92.                     if (top + 1 < 2) {
  93.                         errno = STACK_NEO;
  94.                         return -1;
  95.                     }
  96.                     operations[op](stack, &top);
  97.                 break;
  98.                 case UNDEF_V:
  99.                     errno = UNDEF_V;
  100.                     return -1;
  101.                 break;
  102.             }
  103.  
  104.         }
  105.  
  106.     } while (!is_end_expr);
  107.  
  108.     return stack[top];
  109. }
  110.  
  111. double gettok(char **expr) {
  112.     char *next_tok = NULL;
  113.     double res = strtod(*expr, &next_tok);
  114.  
  115.     /* it's bad idea, because value '0'
  116.         will be considered as UNDEF_V */
  117.     if (res == 0.0) {
  118.         is_value = false;
  119.         switch (**expr) {
  120.             case '+':
  121.                 res = ADD;
  122.             break;
  123.             case '-':
  124.                 res = SUB;
  125.             break;
  126.             case 'x':
  127.             case '*':
  128.                 res = MUL;
  129.             break;
  130.             case '/':
  131.                 res = DIV;
  132.             break;
  133.             case '\0':
  134.                 is_end_expr = true;
  135.             break;
  136.             default:
  137.                 res = UNDEF_V;
  138.         }
  139.         (*expr)++;
  140.     }
  141.     else {
  142.         is_value = true;
  143.         *expr = next_tok;
  144.     }
  145.  
  146.     // skip spaces
  147.     while (isspace(**expr)) (*expr)++;
  148.  
  149.     return res;
  150. }
  151.  
  152. void o_add(double *stack, int *top) {
  153.     stack[*top - 1] += stack[*top];
  154.     (*top)--;
  155. }
  156.  
  157. void o_sub(double *stack, int *top) {
  158.     stack[*top - 1] -= stack[*top];
  159.     (*top)--;
  160. }
  161.  
  162. void o_mul(double *stack, int *top) {
  163.     stack[*top - 1] *= stack[*top];
  164.     (*top)--;
  165. }
  166.  
  167. void o_div(double *stack, int *top) {
  168.     stack[*top - 1] /= stack[*top];
  169.     (*top)--;
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement