Skip to content

Commit dc523d2

Browse files
authored
Update TokenStream.java
replacing with my implementation for TokenStream
1 parent 08b1dc3 commit dc523d2

File tree

1 file changed

+82
-45
lines changed

1 file changed

+82
-45
lines changed

src/main/java/com/scanner/project/TokenStream.java

Lines changed: 82 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,13 @@
33

44
// Implementation of the Scanner for KAY
55

6-
// This code DOES NOT implement a scanner for KAY yet. You have to complete
7-
// the code and also make sure it implements a scanner for KAY - not something
8-
// else, not more and not less
9-
106
import java.io.BufferedReader;
117
import java.io.FileNotFoundException;
128
import java.io.FileReader;
139
import java.io.IOException;
1410

1511
public class TokenStream {
1612

17-
// READ THE COMPLETE FILE FIRST
18-
// You will need to adapt it to KAY, NOT JAY
19-
2013
// Instance variables
2114
private boolean isEof = false; // is end of file
2215
private char nextChar = ' '; // next character in input stream
@@ -34,16 +27,14 @@ public TokenStream(String fileName) {
3427
input = new BufferedReader(new FileReader(fileName));
3528
} catch (FileNotFoundException e) {
3629
System.out.println("File not found: " + fileName);
37-
// System.exit(1); // Removed to allow ScannerDemo to continue
38-
// running after the input file is not found.
3930
isEof = true;
4031
}
4132
}
4233

4334
public Token nextToken() { // Main function of the scanner
44-
// Return next token with its type and value.
35+
// Return next token type and value.
4536
Token t = new Token();
46-
t.setType("Other"); // For now it is Other. You will update it in the code
37+
t.setType("Other"); // For now it is Other
4738
t.setValue("");
4839

4940
// First check for whitespaces and bypass them
@@ -52,12 +43,14 @@ public Token nextToken() { // Main function of the scanner
5243
// Then check for a comment, and bypass it
5344
// but remember that / may also be a division operator.
5445
while (nextChar == '/') {
55-
// The use of while (instead of if) prevents the 2nd line to be printed when
56-
// there are two comment lines in a row.
5746
nextChar = readChar();
5847
if (nextChar == '/') { // If / is followed by another /
5948
// skip rest of line - it's a comment.
60-
// TODO TO BE COMPLETED
49+
// look for <cr>, <lf>, <ff>
50+
while (!isEof && !isEndOfLine(nextChar)) {
51+
nextChar = readChar();
52+
}
53+
skipWhiteSpace();
6154
} else {
6255
// A slash followed by anything else must be an operator.
6356
t.setValue("/");
@@ -72,17 +65,49 @@ public Token nextToken() { // Main function of the scanner
7265
t.setType("Operator");
7366
t.setValue(t.getValue() + nextChar);
7467
switch (nextChar) {
75-
// TODO TO BE COMPLETED OR CHANGED WHERE NEEDED TO IMPLEMENT KAY
7668
case '<':
77-
// <=
69+
// <= or <>
70+
nextChar = readChar();
71+
if (nextChar == '=' || nextChar == '>') {
72+
t.setValue(t.getValue() + nextChar);
73+
nextChar = readChar();
74+
}
75+
return t;
7876
case '>':
7977
// >=
78+
nextChar = readChar();
79+
if (nextChar == '=') {
80+
t.setValue(t.getValue() + nextChar);
81+
nextChar = readChar();
82+
}
83+
return t;
8084
case '=':
8185
// ==
86+
nextChar = readChar();
87+
if (nextChar == '=') {
88+
t.setValue(t.getValue() + nextChar);
89+
nextChar = readChar();
90+
}
91+
return t;
8292
case '!':
8393
// !=
8494
nextChar = readChar();
95+
if (nextChar == '=') {
96+
t.setValue(t.getValue() + nextChar);
97+
nextChar = readChar();
98+
}
8599
return t;
100+
case ':':
101+
// := (assignment operator in KAY)
102+
nextChar = readChar();
103+
if (nextChar == '=') {
104+
t.setValue(t.getValue() + nextChar);
105+
nextChar = readChar();
106+
return t;
107+
} else {
108+
t.setType("Other");
109+
return t;
110+
}
86111
case '|':
87112
// Look for ||
88113
nextChar = readChar();
@@ -94,6 +119,7 @@ public Token nextToken() { // Main function of the scanner
94119
t.setType("Other");
95120
}
96121
return t;
122+
97123
case '&':
98124
// Look for &&
99125
nextChar = readChar();
@@ -104,9 +130,9 @@ public Token nextToken() { // Main function of the scanner
104130
} else {
105131
t.setType("Other");
106132
}
107-
108133
return t;
109-
default: // all other operators
134+
135+
default: // all other operators: +, -, *, /
110136
nextChar = readChar();
111137
return t;
112138
}
@@ -115,22 +141,24 @@ public Token nextToken() { // Main function of the scanner
115141
// Then check for a separator
116142
if (isSeparator(nextChar)) {
117143
t.setType("Separator");
118-
// TODO TO BE COMPLETED
144+
t.setValue(t.getValue() + nextChar);
145+
nextChar = readChar();
119146
return t;
120147
}
121148

122-
// Then check for an identifier, keyword, or literal (True or False).
149+
// Then check for an identifier, keyword, or literal.
123150
if (isLetter(nextChar)) {
124151
// Set to an identifier
125152
t.setType("Identifier");
126153
while ((isLetter(nextChar) || isDigit(nextChar))) {
127154
t.setValue(t.getValue() + nextChar);
128155
nextChar = readChar();
129156
}
130-
// Now see if this is a keyword
157+
// now see if this is a keyword
131158
if (isKeyword(t.getValue())) {
132159
t.setType("Keyword");
133160
} else if (t.getValue().equals("True") || t.getValue().equals("False")) {
161+
// In KAY, True and False are uppercased literals
134162
t.setType("Literal");
135163
}
136164
if (isEndOfToken(nextChar)) { // If token is valid, returns.
@@ -187,30 +215,12 @@ private char readChar() {
187215
}
188216

189217
private boolean isKeyword(String s) {
190-
// TODO TO BE COMPLETED
191-
return false;
218+
// Keywords in KAY: main, if, else, while, integer, bool
219+
// Note: void is NOT a keyword in KAY
220+
return s.equals("main") || s.equals("if") || s.equals("else") ||
221+
s.equals("while") || s.equals("integer") || s.equals("bool");
192222
}
193223

194-
private boolean isSeparator(char c) {
195-
// TODO TO BE COMPLETED
196-
return false;
197-
}
198-
199-
private boolean isOperator(char c) {
200-
// Checks for characters that start operators
201-
// TODO TO BE COMPLETED
202-
return false;
203-
}
204-
205-
private boolean isLetter(char c) {
206-
return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
207-
}
208-
209-
private boolean isDigit(char c) {
210-
// TODO TO BE COMPLETED
211-
return false;
212-
}
213-
214224
private boolean isWhiteSpace(char c) {
215225
return (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f');
216226
}
@@ -219,7 +229,7 @@ private boolean isEndOfLine(char c) {
219229
return (c == '\r' || c == '\n' || c == '\f');
220230
}
221231

222-
private boolean isEndOfToken(char c) { // Is the value a seperate token?
232+
private boolean isEndOfToken(char c) { // Is the value a separate token?
223233
return (isWhiteSpace(nextChar) || isOperator(nextChar) || isSeparator(nextChar) || isEof);
224234
}
225235

@@ -230,7 +240,34 @@ private void skipWhiteSpace() {
230240
}
231241
}
232242

243+
private boolean isSeparator(char c) {
244+
// Separators in KAY: { } ; ( )
245+
return (c == '{' || c == '}' || c == ';' || c == '(' || c == ')');
246+
}
247+
248+
private boolean isOperator(char c) {
249+
// Checks for characters that start operators
250+
// Operators in KAY: + - * / < <= > >= == != && || ! :=
251+
return (c == '+' || c == '-' || c == '*' || c == '/' ||
252+
c == '<' || c == '>' || c == '=' || c == '!' ||
253+
c == '&' || c == '|' || c == ':');
254+
}
255+
256+
private boolean isLetter(char c) {
257+
return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
258+
}
259+
260+
private boolean isDigit(char c) {
261+
return (c >= '0' && c <= '9');
262+
}
263+
264+
public boolean isEndofFile() {
265+
return isEof;
266+
}
267+
}
268+
233269
public boolean isEndofFile() {
234270
return isEof;
235271
}
236-
}
272+
273+
}

0 commit comments

Comments
 (0)