1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| double eval_factor(char const* exp, char** end);
double eval_term(char const* exp, char** end);
double eval_exp(char const* exp, char** end);
char* skipws(char const* exp)
{
while (isspace((int)(unsigned char)*exp)) {
exp++;
}
return (char*) exp;
}
double eval_factor(char const* exp, char** end)
{
double result;
exp = skipws(exp);
if (*exp == '(') {
result = eval_exp(exp+1, end);
if (**end != ')') {
error("missing closing parenthesis", *end);
} else {
++*end;
}
} else if (*exp == '+') {
result = eval_factor(exp+1, end);
} else if (*exp == '-') {
result = -eval_factor(exp+1, end);
} else {
result = strtod(exp, end);
if (*end == exp) {
error("invalid number", *end);
}
}
return result;
}
double eval_term(char const* exp, char** end)
{
double result = eval_factor(exp, end);
*end = skipws(*end);
while (**end == '*' || **end == '/') {
char const* op = *end;
double factor = eval_factor(*end+1, end);
if (*op == '*') {
result *= factor;
} else if (factor != 0.0) {
result /= factor;
} else {
error("divide by 0.0", op);
}
}
return result;
}
double eval_exp(char const* exp, char** end)
{
double result = eval_term(exp, end);
*end = skipws(*end);
while (**end == '+' || **end == '-') {
char const* op = *end;
double term = eval_term(*end+1, end);
if (*op == '+') {
result += term;
} else {
result -= term;
}
}
return result;
}
double eval(char const* exp)
{
char* end;
double result = eval_exp(exp, &end);
if (*end != '\0') {
error("trailing data after the expression", end);
}
return result;
} |
Partager