/
MathTokenizer.java
149 lines (117 loc) · 3.43 KB
/
MathTokenizer.java
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package org.isk.jvmhardcore.math.parser;
import org.isk.jvmhardcore.math.parser.core.Reader;
import org.isk.jvmhardcore.math.parser.core.Tokenizer;
import org.isk.jvmhardcore.math.parser.core.util.Ascii;
import org.isk.jvmhardcore.math.parser.core.util.StringGenerator;
public class MathTokenizer extends Tokenizer {
final private StringGenerator generator;
public MathTokenizer(String filename, Reader reader) {
super(filename, reader);
this.generator = new StringGenerator();
}
public Integer getInteger() {
this.fillWithDigits();
if (!generator.isEmpty()) {
this.rewind();
return Integer.valueOf(generator.toString());
} else {
throw new ParserException("Expected: At least one Digit [0-9].");
}
}
public Double getFloat() {
int character = this.fillWithDigits();
// getFloat() is called after isFloat()
// therefore we are not supposed to check if it's a dot or not
generator.appendChar(character);
while (isDigit(character = this.next())) {
generator.appendChar(character);
}
this.rewind();
return Double.valueOf(generator.toString());
}
private int fillWithDigits() {
int character = this.next();
if (character == Ascii.PLUS_SIGN) {
// Ignore
} else if (character == Ascii.HYPHEN) {
generator.appendChar(character);
} else {
this.rewind();
}
while (isDigit(character = this.next())) {
generator.appendChar(character);
}
return character;
}
public ParsingOperator getOperator() {
int character = this.next();
if (this.isOperator(character)) {
return ParsingOperator.get(character);
} else {
throw new ParserException("Expected: '+' or '-' or '*' or '/'.");
}
}
public ParsingOperator getParenthesis() {
int character = this.next();
return ParsingOperator.get(character);
}
public boolean isFloat() {
this.mark();
int character = this.next();
// Ignore the sign
if (character != Ascii.PLUS_SIGN && character != Ascii.HYPHEN) {
this.rewind();
}
// number of digits
int counter = 0;
// Check the part before the period
while (isDigit(character = this.next())) {
counter++;
}
// Check is the next character is a period
if (Ascii.PERIOD != character) {
this.reset();
return false;
}
// There are digits before the period we don't need to continue
// it's a float
if (counter > 0) {
this.reset();
return true;
}
// Check the part after the period
while (isDigit(character = this.next())) {
counter++;
}
// There are digits after the period
// it's a float
if (counter > 0) {
this.reset();
return true;
}
// There is no character before and after the period
this.reset();
return false;
}
public boolean isOperator(int character) {
return character == Ascii.PLUS_SIGN
|| character == Ascii.HYPHEN
|| character == Ascii.ASTERISK
|| character == Ascii.SLASH;
}
public boolean isOperator() {
final int character = this.next();
this.rewind();
return isOperator(character);
}
public boolean isLeftParenthesis() {
final int character = this.next();
this.rewind();
return character == Ascii.LEFT_PARENTHESIS;
}
public boolean isRightParenthesis() {
final int character = this.next();
this.rewind();
return character == Ascii.RIGHT_PARENTHESIS;
}
}