-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCalculator.java
More file actions
124 lines (109 loc) · 3.36 KB
/
Copy pathCalculator.java
File metadata and controls
124 lines (109 loc) · 3.36 KB
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
114
115
116
117
118
119
120
121
122
123
124
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
import lexer.*;
public class Calculator{
private Lexer lexer;
public boolean printTokens;
private ListIterator<Token> iterator;
private LinkedList<Token> input;
public Calculator(){
this.lexer = new Lexer();
this.printTokens = false;
}
public Calculator(boolean printTokens){
this.lexer = new Lexer();
this.printTokens = printTokens;
}
/*
// Grammar
S -> S + M | S - M | M
M -> M * D | M \ D | D
D -> num | ( S ) | D ^ D | D r D
*/
public double s() throws Exception{
double result=m();
while(iterator.hasNext()){
Token curr = iterator.next();
if(curr.isSum()){
result += m();
} else if(curr.isSub()){
result -= m();
} else{
break;
}
}
return result;
}
public double m() throws Exception{
double result = d();
// Lookahead for the next Multiplier
if (!iterator.hasNext())
return result; //edge case (so it detects the last missing parentheses)
while(iterator.hasNext()){
// loakahead
Token lookahead = iterator.next();
if (lookahead.isMul()){
result*=d();
} else if (lookahead.isDiv()){
result/=d();
} else{
break;
}
}
iterator.previous(); //stop lookahead
return result;
}
private double d() throws Exception{
Token token = iterator.next();
double ret = 0;
if (token.isNum()){
ret = token.getValue();
} else if (token.isLPar()){
double result = s();
if(iterator.previous().isRPar()){
iterator.next();
ret = result;
}else{
throw new Exception("invalid expression: missing \')\'.");
}
}else{
return iterator.next().getValue();
}
while(iterator.hasNext()){
// loakahead
Token lookahead = iterator.next();
if (lookahead.isPow()){
ret=Math.pow(ret,d());
}
else if (lookahead.isRoot()){
double rootDegree = d(), toRoot = ret;
ret=Math.pow(ret,1/rootDegree);
// calc doesn't support complex numbers (negative roots of some degrees are not allowed)
//if (Double.isNaN(ret)){
// throw new Exception("Math ERROR: ("+rootDegree+")_root of NUM("+toRoot+").");
//}
}else {
iterator.previous();
break;
}
}
return ret;
}
private void set(String expr) throws Exception{
this.input = lexer.tokenize(expr);
if (this.printTokens){
Iterator<Token> itr = input.iterator();
while (itr.hasNext())
System.out.print(itr.next().toString());
System.out.println("\n");
}
this.iterator = this.input.listIterator();
}
public double calculate(String expr) throws Exception{
// Convert expr String into Token's List
set(expr);
// Computer expression
return s();
}
}