-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheval.c
84 lines (73 loc) · 1.97 KB
/
eval.c
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
80
81
82
83
84
#include "eval.h"
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
static double parseexpr(char** expression);
static double parseterm(char** expression);
static double parsefact(char** expression);
static void skipspaces(char** expression);
void skipspaces(char** expression) {
while (**expression && isspace(**expression))
(*expression)++;
}
double parsefact(char** expression) {
skipspaces(expression);
double result;
if (**expression == '(') {
(*expression)++;
result = parseexpr(expression);
if(**expression != ')') {
printf("Expected a ')'.\n");
return 0.0f;
}
(*expression)++;
} else {
char* endptr;
result = strtod(*expression, &endptr);
if(*expression == endptr) {
printf("Expected a number.\n");
return 0.0f;
}
*expression = endptr;
}
return result;
}
double parseterm(char** expression) {
double result = parsefact(expression);
skipspaces(expression);
while (**expression == '*' || **expression == '/') {
char op = **expression;
(*expression)++;
double next = parsefact(expression);
if (op == '*')
result *= next;
else if (next != 0)
result /= next;
else {
printf("Division by zero.\n");
return 0.0f;
}
skipspaces(expression);
}
return result;
}
double parseexpr(char** expression) {
double result = parseterm(expression);
skipspaces(expression);
while (**expression == '+' || **expression == '-') {
char op = **expression;
(*expression)++;
double nextTerm = parseterm(expression);
if (op == '+')
result += nextTerm;
else
result -= nextTerm;
skipspaces(expression);
}
return result;
}
double evalexpr(char* expression) {
return parseexpr(&expression);
}