Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- double end_of_expr(double a, double b) { return 0; }
- double last_value(double a, double b) { return 0; }
- double expr_add(double a, double b) { return a + b; }
- double expr_sub(double a, double b) { return a - b; }
- double expr_mul(double a, double b) { return a * b; }
- double expr_div(double a, double b) { return a / b; }
- void error(char *text)
- {
- fprintf(stderr,"error: %s\n",text);
- exit(-2);
- }
- typedef struct PART
- {
- double value;
- double (*operation)(double,double);
- int prior;
- } PART;
- PART eval(PART left, char **expr);
- PART get_part(char **expr)
- {
- char *start;
- PART part = {0,};
- while ( isspace(**expr) ) ++*expr;
- if ( **expr == ')' || !**expr )
- {
- part.operation = end_of_expr;
- if (**expr) ++*expr;
- return part;
- }
- if ( **expr == '(' )
- {
- ++*expr;
- part = eval(get_part(expr),expr);
- }
- else
- {
- start = *expr;
- part.value = strtod(start,expr);
- if ( *expr == start ) error("invalid value");
- }
- while ( isspace(**expr) ) ++*expr;
- if ( **expr == ')' || !**expr )
- {
- part.operation = last_value;
- return part;
- }
- switch ( **expr )
- {
- case '+': part.operation = expr_add; part.prior = 1; break;
- case '-': part.operation = expr_sub; part.prior = 1; break;
- case '*': part.operation = expr_mul; part.prior = 2; break;
- case '/': part.operation = expr_div; part.prior = 2; break;
- default:
- error("invalid operation");
- }
- ++*expr;
- return part;
- }
- PART eval(PART left, char **expr)
- {
- PART right = get_part(expr);
- while ( right.operation != end_of_expr )
- {
- if ( left.prior >= right.prior )
- {
- right.value = left.operation(left.value,right.value);
- left = right;
- right = get_part(expr);
- }
- else
- right = eval(right, expr);
- }
- return left;
- }
- double calc(char *expr)
- {
- char *expr_ptr = expr;
- return eval(get_part(&expr_ptr),&expr_ptr).value;
- }
- int main()
- {
- int exprLen = 0;
- char expr[256];
- double result;
- for(;;)
- {
- fgets(expr,sizeof(expr),stdin);
- exprLen = strlen(expr);
- if ( !exprLen ) exit(0);
- if ( expr[exprLen-1] != '\n' )
- {
- fputs("expression truncated\n",stderr);
- exit(1);
- }
- result = calc(expr);
- printf("=> %f\n",result);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement