-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathScanner.cpp
100 lines (87 loc) · 1.94 KB
/
Scanner.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
/**
* Implementation of Scanner for rational numerber calculator
* CSE 374, 18sp, HP+MW
*/
#include "Scanner.h"
#include <cctype>
#include <cstdlib>
#include <string>
namespace rational374 {
void Scanner::scan() {
if (nextTok_.kind == EOL) {
return;
}
// Skip whitespace.
while (pos_ < line_.size() && isspace(line_[pos_])) {
pos_++;
}
// Skipped leading whitespace. Either past end of line, or
// next character is not blank. Return if past end of line.
if (pos_ >= line_.size()) {
nextTok_.kind = EOL;
return;
}
// Declared here to get rid of a g++ warning
std::string::size_type nextPos;
// Next character is not blank. Classify and return next token.
switch (line_[pos_]) {
// Single-character tokens
case '+':
nextTok_.kind = PLUS;
pos_++;
return;
case '-':
nextTok_.kind = MINUS;
pos_++;
return;
case '*':
nextTok_.kind = TIMES;
pos_++;
return;
case '%':
nextTok_.kind = DIV;
pos_++;
return;
case '/':
nextTok_.kind = SLASH;
pos_++;
return;
case '(':
nextTok_.kind = LPAREN;
pos_++;
return;
case ')':
nextTok_.kind = RPAREN;
pos_++;
return;
// Integer tokens
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
// line_[pos_] is a digit.
// Find last digit in the integer.
nextPos = pos_ + 1;
while (nextPos < line_.size() && isdigit(line_[nextPos])) {
nextPos++;
}
// line_[pos_..nextPos-1] holds the integer characters
nextTok_.kind = INT;
nextTok_.ival = atoi(line_.substr(pos_, nextPos - pos_).c_str());
pos_ = nextPos;
return;
// Unknown character in input
default:
nextTok_.kind = UNKNOWN;
pos_++;
return;
}
}
void Scanner::setInput(std::string newLine) {
line_ = newLine;
pos_ = 0;
nextTok_.kind = UNKNOWN;
scan();
}
Token Scanner::token() {
return nextTok_;
}
} // namespace rational374