OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
AbsFileStream.cpp
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2// $RCSfile: AbsFileStream.cpp,v $
3// ------------------------------------------------------------------------
4// $Revision: 1.1.1.1 $
5// ------------------------------------------------------------------------
6// Copyright: see Copyright.readme
7// ------------------------------------------------------------------------
8//
9// Class: AbsFileStream
10// Implements an abstract input buffer for reading from a file.
11//
12// ------------------------------------------------------------------------
13// Class category: Parser
14// ------------------------------------------------------------------------
15//
16// $Date: 2000/03/27 09:32:37 $
17// $Author: fci $
18//
19// ------------------------------------------------------------------------
20
22#include "Parser/Token.h"
24#include <cctype>
25#include <iostream>
26#include <algorithm>
27
28// Class AbsFileStream
29// ------------------------------------------------------------------------
30
33 line("\n"),
34 curr_char(0)
35{}
36
37
39{}
40
41
43 if(put_back_flag) {
44 put_back_flag = false;
45 return put_back;
46 }
47
48 // Skip white space.
49 while(true) {
50 char ch = line[curr_char];
51
52 if(ch == '\n') {
53 // End of line.
54 if(! fillLine()) {
55 // End of file.
57 }
58 } else if(isspace(ch)) {
59 // Skip white space.
60 curr_char++;
61 } else {
62 break;
63 }
64 }
65
66 // First character.
67 char ch = line[curr_char];
68
69 if(ch == '/') {
70 // Skip comments.
71 char ch1 = line[curr_char+1];
72 if(ch1 == '/') {
73 // C++ like comment.
74 if(fillLine()) {
75 return readToken();
76 } else {
78 }
79 } else if(ch1 == '*') {
80 // C like comment.
81 if(skipComments()) {
82 return readToken();
83 } else {
85 "Comment not closed.");
86 }
87 }
88 }
89
90 if(ch == '"' || ch == '\'') {
91 // String token.
92 return readString();
93 } else if(isalpha(ch)) {
94 // Word token.
95 return readWord();
96 } else if(isdigit(ch) ||
97 (ch == '.' && isdigit(line[curr_char+1]))) {
98 // Numeric token.
99 return readNumber();
100 } else {
101 // Delimiter tokens.
102 if(ch == '<' && line[curr_char+1] == '=') {
103 curr_char += 2;
105 } else if(ch == '>' && line[curr_char+1] == '=') {
106 curr_char += 2;
108 } else if(ch == '=' && line[curr_char+1] == '=') {
109 curr_char += 2;
111 } else if(ch == '!' && line[curr_char+1] == '=') {
112 curr_char += 2;
114 } else if(ch == '|' && line[curr_char+1] == '|') {
115 curr_char += 2;
117 } else if(ch == '&' && line[curr_char+1] == '&') {
118 curr_char += 2;
120 } else if(ch == ':' && line[curr_char+1] == '=') {
121 curr_char += 2;
123 } else if(ch == '-' && line[curr_char+1] == '>') {
124 curr_char += 2;
126 } else if(ch == '/' && line[curr_char+1] == '*') {
127 curr_char += 2;
128 if(skipComments()) {
129 return readToken();
130 } else {
132 "Comment not closed.");
133 }
134 } else {
135 curr_char++;
137 }
138 }
139
140 return Token(stream_name, curr_line, Token::IS_ERROR, "ERROR");
141}
142
143
145 bool digit = false;
146 bool eflag = false;
147 double value = 0.0;
148 int expsig = 1;
149 int expval = 0;
150 int places = 0;
151 int lex_pos = curr_char;
152
153 while(isdigit(line[curr_char])) {
154 // Digits preceding decimal point.
155 value = 10.0 * value + double(line[curr_char] - '0');
156 digit = true;
157 curr_char++;
158 }
159
160 if(digit && line[curr_char] != '.' &&
161 toupper(line[curr_char]) != 'E') {
162 // Unsigned integer seen.
163 std::string lexeme(line.data() + lex_pos, curr_char - lex_pos);
164 return Token(stream_name, curr_line, lexeme, int(value + 0.5));
165 }
166
167 // Decimal point.
168 if(line[curr_char] == '.') {
169 curr_char++;
170
171 // Digits following decimal point.
172 while(isdigit(line[curr_char])) {
173 value = 10.0 * value + double(line[curr_char++] - '0');
174 digit = true;
175 places++;
176 }
177 }
178
179 if(! digit) eflag = true;
180
181 // Exponent ?
182 if(toupper(line[curr_char]) == 'E') {
183 curr_char++;
184 digit = false;
185
186 if(line[curr_char] == '+') {
187 curr_char++;
188 } else if(line[curr_char] == '-') {
189 curr_char++;
190 expsig = -1;
191 }
192
193 while(isdigit(line[curr_char])) {
194 expval = 10 * expval + (line[curr_char++] - '0');
195 digit = true;
196 }
197
198 if(! digit) eflag = true;
199
200 // Skip over any non-punctuation characters.
201 char ch = line[curr_char];
202
203 while(! isspace(ch) && ! ispunct(ch)) {
204 eflag = true;
205 curr_char++;
206 ch = line[curr_char];
207 }
208 }
209
210 // Put pieces together.
211 std::string lexeme(line.data() + lex_pos, curr_char - lex_pos);
212
213 if(eflag) {
215 "Invalid numeric token \"" + lexeme + "\".");
216 } else {
217 int power = expsig * expval - places;
218
219 if(power > 0) {
220 for(places = power; places > 0; places--)
221 value *= 10.0;
222 } else {
223 for(places = - power; places > 0; places--)
224 value /= 10.0;
225 }
226
227 return Token(stream_name, curr_line, lexeme, value);
228 }
229}
230
231
233 std::string lexeme;
234
235 if(line[curr_char] == '"' || line[curr_char] == '\'') {
236 char quote = line[curr_char];
237 curr_char++;
238
239 while(true) {
240 if(line[curr_char] == '\n') {
241 return Token(stream_name, curr_line, Token::IS_ERROR, "String \"" +
242 lexeme + "\" not terminated at end of line.");
243 }
244
245 if(line[curr_char] == quote) {
246 curr_char++;
247 if(line[curr_char] != quote) break;
248 } else if(line[curr_char] == '\\') {
249 curr_char++;
250 }
251
252 lexeme += line[curr_char++];
253 }
254 }
255
257}
258
259
261 std::string lexeme;
262 char ch = line[curr_char];
263
264 if(isalpha(line[curr_char])) {
265 lexeme += toupper(ch);
266 char ch = line[++curr_char];
267
268 while(isalnum(ch) || ch == '_' || ch == '.') {
269 lexeme += toupper(ch);
270 ch = line[++curr_char];
271 }
272 }
273
274 return Token(stream_name, curr_line, Token::IS_WORD, lexeme);
275}
276
277
279 curr_char += 2;
280
281 while(true) {
282 while(line[curr_char] != '\n') {
283 if(line[curr_char] == '*' && line[curr_char+1] == '/') {
284 curr_char += 2;
285 return true;
286 } else if(line[curr_char] == '/' && line[curr_char+1] == '*') {
287 skipComments();
288 } else {
289 curr_char++;
290 }
291 }
292
293 // End of line
294 if(! fillLine()) return false;
295 }
296}
const std::string name
std::string line
Definition: AbsFileStream.h:63
virtual bool fillLine()=0
Read next input line.
virtual ~AbsFileStream()
virtual Token readToken()
Read single token from file.
Representation of a single input token.
Definition: Token.h:33
@ IS_STRING
Definition: Token.h:45
@ IS_ERROR
Definition: Token.h:41
@ IS_DELIMITER
Definition: Token.h:39
@ IS_WORD
Definition: Token.h:44
@ IS_EOF
Definition: Token.h:40
Abstract interface for a stream of input tokens.
Definition: TokenStream.h:33
bool put_back_flag
Definition: TokenStream.h:65
std::string stream_name
Definition: TokenStream.h:59
Token put_back
Definition: TokenStream.h:66