/* arith.c: simple parser -- bold evaluates */ #include #include #include #include /* for pow */ char next; double E(void); double T(void); double S(void); double F(void); void error(void); void scan(void); double evaluate(double arg1, char op, double arg2); void main(void) { double res; scan(); res = E(); if (next != '#') error(); else printf("Result is: %.16f\n", res); } double E(void) { char save; double res, arg1, arg2; res = T(); while (next == '+' || next == '-') { save = next; arg1 = res; scan(); arg2 = T(); res = evaluate(arg1, save, arg2); } return res; } double T(void) { char save; double res, arg1, arg2; res = S(); while (next == '*' || next == '/') { save = next; arg1 = res; scan(); arg2 = S(); res = evaluate(arg1, save, arg2); } return res; } double S(void) { char save; double res, arg1, arg2; res = F(); if (next == '^') { save = next; arg1 = res; scan(); arg2 = S(); res = evaluate(arg1, save, arg2); } return res; } double F(void) { char save; double res; if (isdigit(next)) { save = next; scan(); return (double)(save - '0'); } else if (next == '(') { scan(); res = E(); if (next == ')') scan(); else error(); return res; } else { error(); return 0; } } void scan(void) { while (isspace(next = getchar())) ; } void error(void) { printf("\n*** ERROR ***\n"); exit(1); } double evaluate(double arg1, char op, double arg2) { switch (op) { case '+': return arg1 + arg2; case '-': return arg1 - arg2; case '*': return arg1 * arg2; case '/': return arg1 / arg2; case '^': return pow(arg1, arg2); default: error(); return 0; } }