-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc.cpp
113 lines (106 loc) · 1.88 KB
/
calc.cpp
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <cstdio>
#include <cstdlib>
enum PARSE_ERR { NO_ERR, PARENTHESIS, WRONG_CHAR, DIV_ZERO };
int parent_count{0};
PARSE_ERR err{NO_ERR};
int parse_add_sub(char*& eval);
int parse_char(char*& eval) {
while (*eval == ' ') {
++eval;
}
bool negative = false;
if (*eval == '-') {
negative = true;
++eval;
}
if (*eval == '+') {
++eval;
}
if (*eval == '(') {
++eval;
++parent_count;
int res = parse_add_sub(eval);
if (*eval != ')') {
err = PARENTHESIS;
return 0;
}
++eval;
--parent_count;
if (negative) {
return -res;
} else {
return res;
}
}
char* end_str;
int res = std::strtod(eval, &end_str);
if (end_str == eval) {
err = WRONG_CHAR;
return 0;
}
eval = end_str;
if (negative) {
return -res;
} else {
return res;
}
}
int parse_mul_div(char*& eval) {
int num1 = parse_char(eval);
for (;;) {
while (*eval == ' ') {
++eval;
}
char op = *eval;
if (op != '/' && op != '*') {
return num1;
}
++eval;
int num2 = parse_char(eval);
if (op == '/') {
if (num2 == 0) {
err = DIV_ZERO;
return 0;
}
num1 /= num2;
} else {
num1 *= num2;
}
}
}
int parse_add_sub(char*& eval) {
int num1 = parse_mul_div(eval);
for (;;) {
while (*eval == ' ') {
++eval;
}
char op = *eval;
if (op != '-' && op != '+') {
return num1;
}
++eval;
int num2 = parse_mul_div(eval);
if (op == '-') {
num1 -= num2;
} else {
num1 += num2;
}
}
}
int eval(char* eval) {
int res = parse_add_sub(eval);
if (parent_count != 0 || *eval == ')') {
err = PARENTHESIS;
return 0;
}
if (*eval != '\0') {
err = WRONG_CHAR;
return 0;
}
return res;
}
int main(int argc, char** argv) {
int res = eval(argv[1]);
printf("%d", res);
return err;
}