blob: 5ead5912e61c11a10130698998f52b67351544d7 (
plain)
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
|
package ch.bfh.parser;
import ch.bfh.lexer.CalculatorLexer;
import ch.bfh.lexer.Token;
class TermParser extends ExpressionParser {
public TermParser(CalculatorLexer cl, Token lastToken) {
super(cl, lastToken, false);
}
@Override
protected void parse() {
Token token = lastToken;
lastToken = null;
Parser l = null;
Parser r = null; // left and right expressions
Token op = null; // operation of the current l and right expressions
loop:
while (token != null && token.type != Token.EOL) {
switch (token.type) {
case Token.ADD:
if (op != null) {
lastToken = token;
break loop; // going here on case 'n/+...' or 'n*+...' since '+' would be invalid
}
case Token.SUB:
case Token.NUM:
case Token.ID:
case Token.PAL:
if (l == null) {
l = new FactorParser(cl, token);
this.parsers.add(l);
token = l.lastToken;
continue loop;
} else if (op != null) {
r = new FactorParser(cl, token);
this.parsers.add(r);
token = r.lastToken;
lastToken = token; // in case we finished
continue loop;
} else {
lastToken = token;
break loop; // going here on case 'n+...' or 'n-...' since '+' and '-' are part of the parent expression
}
case Token.MUL:
case Token.DIV:
if (l != null && op == null) { // if the '*' or '/' signs are between two Factors (op)
op = token;
this.ops.add(op);
} else if (l != null && r != null) { // if we already found a 'l op r' we roll
l = r;
r = null;
op = token;
this.ops.add(op);
} else
throw new ParserException("Two '" + token.str + "' in a row were found.");
break;
case Token.PAR: // Going as high as possible --> possibly the end of an expression created by a Factor :)
lastToken = token;
break loop;
case Token.EQU:
case Token.LET:
throw new ParserException("The inputted token '"+token.str+"' can only be placed in a variable declaration context (let var = Expression).");
case Token.END:
throw new ParserException("The keyword 'exit' can only be placed at the beginning of an expression.");
}
token = cl.nextToken();
}
if (op != null && r == null)
throw new ParserException("Missing expression after last operator '" + op.str + "'");
}
@Override
public double getValue() {
double result = 0.0;
if (!this.parsers.isEmpty()) {
result = this.parsers.get(0).getValue();
for (int i = 1; i < this.parsers.size(); i++) {
switch (this.ops.get(i - 1).type) {
case Token.MUL:
result *= this.parsers.get(i).getValue();
break;
case Token.DIV:
result /= this.parsers.get(i).getValue();
break;
}
}
}
return result;
}
}
|