Advertisement
Guest User

Untitled

a guest
Jan 7th, 2014
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.28 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. double end_of_expr(double a, double b) { return 0; }
  7. double last_value(double a, double b) { return 0; }
  8. double expr_add(double a, double b) { return a + b; }
  9. double expr_sub(double a, double b) { return a - b; }
  10. double expr_mul(double a, double b) { return a * b; }
  11. double expr_div(double a, double b) { return a / b; }
  12.  
  13. void error(char *text)
  14. {
  15.     fprintf(stderr,"error: %s\n",text);
  16.     exit(-2);
  17. }
  18.  
  19. typedef struct PART
  20. {
  21.     double value;
  22.     double (*operation)(double,double);
  23.     int prior;
  24. } PART;
  25.  
  26. PART eval(PART left, char **expr);
  27. PART get_part(char **expr)
  28. {
  29.     char *start;
  30.     PART part = {0,};
  31.    
  32.     while ( isspace(**expr) ) ++*expr;
  33.    
  34.     if ( **expr == ')' || !**expr )
  35.     {
  36.         part.operation = end_of_expr;
  37.         if (**expr) ++*expr;
  38.         return part;
  39.     }
  40.  
  41.     if ( **expr == '(' )
  42.     {
  43.         ++*expr;
  44.         part = eval(get_part(expr),expr);
  45.     }
  46.     else
  47.     {  
  48.         start = *expr;
  49.         part.value = strtod(start,expr);
  50.         if ( *expr == start ) error("invalid value");
  51.     }
  52.  
  53.     while ( isspace(**expr) ) ++*expr;
  54.  
  55.     if ( **expr == ')' || !**expr )
  56.     {
  57.         part.operation = last_value;
  58.         return part;
  59.     }
  60.  
  61.     switch ( **expr )
  62.     {
  63.         case '+': part.operation = expr_add; part.prior = 1; break;
  64.         case '-': part.operation = expr_sub; part.prior = 1; break;
  65.         case '*': part.operation = expr_mul; part.prior = 2; break;
  66.         case '/': part.operation = expr_div; part.prior = 2; break;
  67.         default:
  68.             error("invalid operation");
  69.     }
  70.     ++*expr;
  71.     return part;
  72. }
  73.  
  74. PART eval(PART left, char **expr)
  75. {
  76.     PART right = get_part(expr);
  77.     while ( right.operation != end_of_expr )
  78.     {
  79.         if ( left.prior >= right.prior )
  80.         {
  81.             right.value = left.operation(left.value,right.value);
  82.             left = right;
  83.             right = get_part(expr);
  84.         }
  85.         else
  86.             right = eval(right, expr);
  87.     }
  88.     return left;
  89. }
  90.  
  91. double calc(char *expr)
  92. {
  93.     char *expr_ptr = expr;
  94.     return eval(get_part(&expr_ptr),&expr_ptr).value;
  95. }
  96.  
  97. int main()
  98. {
  99.     int exprLen = 0;
  100.     char expr[256];
  101.     double result;
  102.  
  103.     for(;;)
  104.     {
  105.         fgets(expr,sizeof(expr),stdin);
  106.         exprLen = strlen(expr);
  107.        
  108.         if ( !exprLen ) exit(0);
  109.         if ( expr[exprLen-1] != '\n' )
  110.         {
  111.             fputs("expression truncated\n",stderr);
  112.             exit(1);
  113.         }
  114.  
  115.         result = calc(expr);
  116.         printf("=> %f\n",result);
  117.     }
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement