/* eval.c: evaluate arith expr as double
P ---> E '$'
E ---> T { ( '+' | '-' ) T }
T ---> S { ( '*' | '/' ) S }
S ---> F '^' S | F
F ---> '(' E ')' | digit
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h> /* 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);
int main() {
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;
}
}
|