-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpr.cpp
104 lines (98 loc) · 2.3 KB
/
expr.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
#include "expr.hpp"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <cstdlib>
#include <iostream>
Expression * parse(const char ** strp);
void skipSpace(const char ** strp) {
while (isspace(**strp)) {
*strp = *strp + 1;
}
}
Expression * makeExpr(char op, Expression * lhs, Expression * rhs) {
switch (op) {
case '+':
return new PlusExpression(lhs, rhs);
case '-':
case '*':
case '/':
std::cerr << op << " will be implemented in the future!\n";
default:
std::cerr << "Impossible op char: " << op << "\n";
abort();
}
}
bool isValidOp(char c) {
return strchr("+-*/", c) != NULL;
}
Expression * parseOp(const char ** strp) {
skipSpace(strp);
char op = **strp;
if (!isValidOp(op)) {
std::cerr << "Invalid op: " << op << "\n";
return NULL;
}
*strp = *strp + 1;
Expression * lhs = parse(strp);
if (lhs == NULL) {
return NULL;
}
Expression * rhs = parse(strp);
if (rhs == NULL) {
delete lhs;
return NULL;
}
skipSpace(strp);
if (**strp == ')') {
*strp = *strp + 1;
return makeExpr(op, lhs, rhs);
}
std::cerr << "Expected ) but found " << *strp << "\n";
delete lhs;
delete rhs;
return NULL;
}
Expression * parse(const char ** strp) {
skipSpace(strp);
if (**strp == '\0') {
std::cerr << "End of line found mid expression!\n";
return NULL;
}
else if (**strp == '(') {
// (op E E)
*strp = *strp + 1;
return parseOp(strp);
}
else {
//number
char * endp;
long num = strtol(*strp, &endp, 10);
if (endp == *strp) {
std::cerr << "Expected a number, but found " << *strp << "\n";
return NULL;
}
*strp = endp;
return new NumExpression(num);
}
}
int main(void) {
char * line = NULL;
size_t sz;
while (getline(&line, &sz, stdin) != -1) {
const char * temp = line;
std::cout << "Read expression: " << line;
Expression * expr = parse(&temp);
if (expr != NULL) {
std::cout << "Parsed expression to: " << expr->toString() << "\n";
//std::cout << "Evaluated expression to: " << expr->evaluate() << "\n";
std::cout << "(evaluation will be done in the future)\n";
delete expr;
}
else {
std::cout << "Could not parse expression, please try again.\n";
}
}
free(line);
return EXIT_SUCCESS;
}