OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
StringStream.cpp
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2// $RCSfile: StringStream.cpp,v $
3// ------------------------------------------------------------------------
4// $Revision: 1.1.1.1 $
5// ------------------------------------------------------------------------
6// Copyright: see Copyright.readme
7// ------------------------------------------------------------------------
8//
9// Class: StringStream
10// Implements an input buffer for reading from a string.
11// This string is intended for storing valid OPALX expressions,
12// it must not contain comments.
13//
14// ------------------------------------------------------------------------
15// Class category: Parser
16// ------------------------------------------------------------------------
17//
18// $Date: 2000/03/27 09:32:37 $
19// $Author: fci $
20//
21// ------------------------------------------------------------------------
22
24#include <cctype>
25#include "OpalParser/Token.h"
27
28// Class StringStream
29// ------------------------------------------------------------------------
30
31StringStream::StringStream(const std::string& str)
32 : TokenStream("expression"), line_m(str + '\n'), currentChar_m(0) {}
33
35
37 if (put_back_flag) {
38 put_back_flag = false;
39 return put_back;
40 }
41
42 while (true) {
43 if (currentChar_m >= line_m.length() || line_m[currentChar_m] == '\n') {
44 return Token("string", 1, Token::IS_EOF, "EOF");
45 } else if (isspace(line_m[currentChar_m])) {
47 } else {
48 break;
49 }
50 }
51
52 // First character.
53 char ch = line_m[currentChar_m];
54
55 if (ch == '"' || ch == '\'') {
56 // String token.
57 return readString();
58 } else if (isalpha(ch)) {
59 // Word token.
60 return readWord();
61 } else if (isdigit(ch) || (ch == '.' && isdigit(line_m[currentChar_m + 1]))) {
62 // Numeric token.
63 return readNumber();
64 } else {
65 // Delimiter tokens.
66 if (ch == '<' && line_m[currentChar_m + 1] == '=') {
67 currentChar_m += 2;
68 return Token("string", 1, Token::IS_DELIMITER, "<=");
69 } else if (ch == '>' && line_m[currentChar_m + 1] == '=') {
70 currentChar_m += 2;
71 return Token("string", 1, Token::IS_DELIMITER, ">=");
72 } else if (ch == '=' && line_m[currentChar_m + 1] == '=') {
73 currentChar_m += 2;
74 return Token("string", 1, Token::IS_DELIMITER, "==");
75 } else if (ch == '!' && line_m[currentChar_m + 1] == '=') {
76 currentChar_m += 2;
77 return Token("string", 1, Token::IS_DELIMITER, "!=");
78 } else if (ch == '|' && line_m[currentChar_m + 1] == '|') {
79 currentChar_m += 2;
80 return Token("string", 1, Token::IS_DELIMITER, "||");
81 } else if (ch == '&' && line_m[currentChar_m + 1] == '&') {
82 currentChar_m += 2;
83 return Token("string", 1, Token::IS_DELIMITER, "&&");
84 } else if (ch == ':' && line_m[currentChar_m + 1] == '=') {
85 currentChar_m += 2;
86 return Token("string", 1, Token::IS_DELIMITER, ":=");
87 } else if (ch == '-' && line_m[currentChar_m + 1] == '>') {
88 currentChar_m += 2;
89 return Token("string", 1, Token::IS_DELIMITER, "->");
90 } else {
92 return Token("string", 1, Token::IS_DELIMITER, ch);
93 }
94 }
95
96 return Token(stream_name, curr_line, Token::IS_ERROR, "ERROR");
97}
98
100 bool digit = false;
101 bool eflag = false;
102 double value = 0.0;
103 int expsig = 1;
104 int expval = 0;
105 int places = 0;
106 int lex_pos = currentChar_m;
107
108 while (isdigit(line_m[currentChar_m])) {
109 // Digits preceding decimal point.
110 value = 10.0 * value + double(line_m[currentChar_m] - '0');
111 digit = true;
113 }
114
115 if (digit && line_m[currentChar_m] != '.' && toupper(line_m[currentChar_m]) != 'E') {
116 // Unsigned integer seen.
117 std::string lexeme(line_m.data() + lex_pos, currentChar_m - lex_pos);
118 return Token("string", 1, lexeme, int(value + 0.5));
119 }
120
121 // Decimal point.
122 if (line_m[currentChar_m] == '.') {
124
125 // Digits following decimal point.
126 while (isdigit(line_m[currentChar_m])) {
127 value = 10.0 * value + double(line_m[currentChar_m++] - '0');
128 digit = true;
129 places++;
130 }
131 }
132
133 if (!digit) eflag = true;
134
135 // Exponent ?
136 if (toupper(line_m[currentChar_m]) == 'E') {
138 digit = false;
139
140 if (line_m[currentChar_m] == '+') {
142 } else if (line_m[currentChar_m] == '-') {
144 expsig = -1;
145 }
146
147 while (isdigit(line_m[currentChar_m])) {
148 expval = 10 * expval + (line_m[currentChar_m++] - '0');
149 digit = true;
150 }
151
152 if (!digit) eflag = true;
153
154 // Skip over any non-punctuation characters.
155 char ch = line_m[currentChar_m];
156
157 while (!isspace(ch) && !ispunct(ch)) {
158 eflag = true;
160 ch = line_m[currentChar_m];
161 }
162 }
163
164 // Put pieces together.
165 std::string lexeme(line_m.data() + lex_pos, currentChar_m - lex_pos);
166
167 if (eflag) {
168 return Token("string", 1, Token::IS_ERROR, "Invalid numeric token \"" + lexeme + "\".");
169 } else {
170 int power = expsig * expval - places;
171
172 if (power > 0) {
173 for (places = power; places > 0; places--)
174 value *= 10.0;
175 } else {
176 for (places = -power; places > 0; places--)
177 value /= 10.0;
178 }
179
180 return Token("string", 1, lexeme, value);
181 }
182}
183
185 std::string lexeme;
186
187 if (line_m[currentChar_m] == '"' || line_m[currentChar_m] == '\'') {
188 char quote = line_m[currentChar_m];
190
191 while (true) {
192 if (currentChar_m >= line_m.length()) {
193 throw FormatError("StringStream::readString()", "String not terminated.");
194 }
195
196 if (line_m[currentChar_m] == quote) {
198 if (line_m[currentChar_m] != quote) break;
199 } else if (line_m[currentChar_m] == '\\') {
201 }
202
203 lexeme += line_m[currentChar_m++];
204 }
205 }
206
207 return Token("string", 1, Token::IS_STRING, lexeme);
208}
209
211 std::string lexeme;
212 char ch = line_m[currentChar_m];
213
214 if (isalpha(line_m[currentChar_m])) {
215 lexeme += toupper(ch);
216 char ch = line_m[++currentChar_m];
217
218 while (isalnum(ch) || ch == '_' || ch == '.' || ch == '\'') {
219 lexeme += toupper(ch);
220 ch = line_m[++currentChar_m];
221 }
222 }
223
224 return Token("string", 1, Token::IS_WORD, lexeme);
225}
Format error exception.
Definition FormatError.h:32
virtual ~StringStream()
std::string::size_type currentChar_m
const std::string line_m
virtual Token readToken()
Read single token from file.
Token readNumber()
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