OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
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 <algorithm>
23#include <cctype>
24#include <iostream>
25#include "OpalParser/Token.h"
27
28// Class AbsFileStream
29// ------------------------------------------------------------------------
30
31AbsFileStream::AbsFileStream(const std::string& name)
32 : TokenStream(name), line("\n"), curr_char(0) {}
33
35
37 if (put_back_flag) {
38 put_back_flag = false;
39 return put_back;
40 }
41
42 // Skip white space.
43 while (true) {
44 char ch = line[curr_char];
45
46 if (ch == '\n') {
47 // End of line.
48 if (!fillLine()) {
49 // End of file.
51 }
52 } else if (isspace(ch)) {
53 // Skip white space.
54 curr_char++;
55 } else {
56 break;
57 }
58 }
59
60 // First character.
61 char ch = line[curr_char];
62
63 if (ch == '/') {
64 // Skip comments.
65 char ch1 = line[curr_char + 1];
66 if (ch1 == '/') {
67 // C++ like comment.
68 if (fillLine()) {
69 return readToken();
70 } else {
72 }
73 } else if (ch1 == '*') {
74 // C like comment.
75 if (skipComments()) {
76 return readToken();
77 } else {
78 return Token(stream_name, curr_line, Token::IS_ERROR, "Comment not closed.");
79 }
80 }
81 }
82
83 if (ch == '"' || ch == '\'') {
84 // String token.
85 return readString();
86 } else if (isalpha(ch)) {
87 // Word token.
88 return readWord();
89 } else if (isdigit(ch) || (ch == '.' && isdigit(line[curr_char + 1]))) {
90 // Numeric token.
91 return readNumber();
92 } else {
93 // Delimiter tokens.
94 if (ch == '<' && line[curr_char + 1] == '=') {
95 curr_char += 2;
97 } else if (ch == '>' && line[curr_char + 1] == '=') {
98 curr_char += 2;
100 } else if (ch == '=' && line[curr_char + 1] == '=') {
101 curr_char += 2;
103 } else if (ch == '!' && line[curr_char + 1] == '=') {
104 curr_char += 2;
106 } else if (ch == '|' && line[curr_char + 1] == '|') {
107 curr_char += 2;
109 } else if (ch == '&' && line[curr_char + 1] == '&') {
110 curr_char += 2;
112 } else if (ch == ':' && line[curr_char + 1] == '=') {
113 curr_char += 2;
115 } else if (ch == '-' && line[curr_char + 1] == '>') {
116 curr_char += 2;
118 } else if (ch == '/' && line[curr_char + 1] == '*') {
119 curr_char += 2;
120 if (skipComments()) {
121 return readToken();
122 } else {
123 return Token(stream_name, curr_line, Token::IS_ERROR, "Comment not closed.");
124 }
125 } else {
126 curr_char++;
128 }
129 }
130
131 return Token(stream_name, curr_line, Token::IS_ERROR, "ERROR");
132}
133
135 bool digit = false;
136 bool eflag = false;
137 double value = 0.0;
138 int expsig = 1;
139 int expval = 0;
140 int places = 0;
141 int lex_pos = curr_char;
142
143 while (isdigit(line[curr_char])) {
144 // Digits preceding decimal point.
145 value = 10.0 * value + double(line[curr_char] - '0');
146 digit = true;
147 curr_char++;
148 }
149
150 if (digit && line[curr_char] != '.' && toupper(line[curr_char]) != 'E') {
151 // Unsigned integer seen.
152 std::string lexeme(line.data() + lex_pos, curr_char - lex_pos);
153 return Token(stream_name, curr_line, lexeme, int(value + 0.5));
154 }
155
156 // Decimal point.
157 if (line[curr_char] == '.') {
158 curr_char++;
159
160 // Digits following decimal point.
161 while (isdigit(line[curr_char])) {
162 value = 10.0 * value + double(line[curr_char++] - '0');
163 digit = true;
164 places++;
165 }
166 }
167
168 if (!digit) eflag = true;
169
170 // Exponent ?
171 if (toupper(line[curr_char]) == 'E') {
172 curr_char++;
173 digit = false;
174
175 if (line[curr_char] == '+') {
176 curr_char++;
177 } else if (line[curr_char] == '-') {
178 curr_char++;
179 expsig = -1;
180 }
181
182 while (isdigit(line[curr_char])) {
183 expval = 10 * expval + (line[curr_char++] - '0');
184 digit = true;
185 }
186
187 if (!digit) eflag = true;
188
189 // Skip over any non-punctuation characters.
190 char ch = line[curr_char];
191
192 while (!isspace(ch) && !ispunct(ch)) {
193 eflag = true;
194 curr_char++;
195 ch = line[curr_char];
196 }
197 }
198
199 // Put pieces together.
200 std::string lexeme(line.data() + lex_pos, curr_char - lex_pos);
201
202 if (eflag) {
203 return Token(
205 "Invalid numeric token \"" + lexeme + "\".");
206 } else {
207 int power = expsig * expval - places;
208
209 if (power > 0) {
210 for (places = power; places > 0; places--)
211 value *= 10.0;
212 } else {
213 for (places = -power; places > 0; places--)
214 value /= 10.0;
215 }
216
217 return Token(stream_name, curr_line, lexeme, value);
218 }
219}
220
222 std::string lexeme;
223
224 if (line[curr_char] == '"' || line[curr_char] == '\'') {
225 char quote = line[curr_char];
226 curr_char++;
227
228 while (true) {
229 if (line[curr_char] == '\n') {
230 return Token(
232 "String \"" + lexeme + "\" not terminated at end of line.");
233 }
234
235 if (line[curr_char] == quote) {
236 curr_char++;
237 if (line[curr_char] != quote) break;
238 } else if (line[curr_char] == '\\') {
239 curr_char++;
240 }
241
242 lexeme += line[curr_char++];
243 }
244 }
245
247}
248
250 std::string lexeme;
251 char ch = line[curr_char];
252
253 if (isalpha(line[curr_char])) {
254 lexeme += toupper(ch);
255 char ch = line[++curr_char];
256
257 while (isalnum(ch) || ch == '_' || ch == '.') {
258 lexeme += toupper(ch);
259 ch = line[++curr_char];
260 }
261 }
262
263 return Token(stream_name, curr_line, Token::IS_WORD, lexeme);
264}
265
267 curr_char += 2;
268
269 while (true) {
270 while (line[curr_char] != '\n') {
271 if (line[curr_char] == '*' && line[curr_char + 1] == '/') {
272 curr_char += 2;
273 return true;
274 } else if (line[curr_char] == '/' && line[curr_char + 1] == '*') {
275 skipComments();
276 } else {
277 curr_char++;
278 }
279 }
280
281 // End of line
282 if (!fillLine()) return false;
283 }
284}
std::string line
virtual bool fillLine()=0
Read next input line.
virtual ~AbsFileStream()
virtual Token readToken()
Read single token from file.
Abstract interface for a stream of input tokens.
Definition TokenStream.h:30
bool put_back_flag
Definition TokenStream.h:59
std::string stream_name
Definition TokenStream.h:53
Token put_back
Definition TokenStream.h:60
Representation of a single input token.
Definition Token.h:32
@ IS_STRING
Definition Token.h:35
@ IS_ERROR
Definition Token.h:35
@ IS_DELIMITER
Definition Token.h:35
@ IS_WORD
Definition Token.h:35
@ IS_EOF
Definition Token.h:35