Line | Branch | Exec | Source |
---|---|---|---|
1 | #include "lexer.h" | ||
2 | #include "unlex.h" | ||
3 | #include "utilities/strings.h" | ||
4 | |||
5 | namespace lython { | ||
6 | |||
7 | Dict<String, OpConfig> const& default_precedence() { | ||
8 | // clang-format off | ||
9 | static Dict<String, OpConfig> val = { | ||
10 | // Predecence, Left Associative, is_binary, is_bool, can_be_unary, kind | ||
11 | // Arithmetic | ||
12 | {"+", {20, true , tok_operator, BinaryOperator::Add, UnaryOperator::UAdd}}, | ||
13 | {"-", {20, true , tok_operator, BinaryOperator::Sub, UnaryOperator::USub}}, | ||
14 | {"%", {10, true , tok_operator, BinaryOperator::Mod}}, | ||
15 | {"*", {30, true , tok_operator, BinaryOperator::Mult}}, | ||
16 | {"**", {40, true , tok_operator, BinaryOperator::Pow}}, | ||
17 | {"/", {30, true , tok_operator, BinaryOperator::Div}}, | ||
18 | {"//", {30, true , tok_operator, BinaryOperator::FloorDiv}}, | ||
19 | {".*", {20, true , tok_operator, BinaryOperator::EltMult}}, | ||
20 | {"./", {20, true , tok_operator, BinaryOperator::EltDiv}}, | ||
21 | //*/ Shorthand | ||
22 | {"+=", {50, true , tok_augassign, BinaryOperator::Add}}, | ||
23 | {"-=", {50, true , tok_augassign, BinaryOperator::Sub}}, | ||
24 | {"*=", {50, true , tok_augassign, BinaryOperator::Mult}}, | ||
25 | {"/=", {50, true , tok_augassign, BinaryOperator::Div}}, | ||
26 | {"%=", {50, true , tok_augassign, BinaryOperator::Mod}}, | ||
27 | {"**=", {50, true , tok_augassign, BinaryOperator::Pow}}, | ||
28 | {"//=", {50, true , tok_augassign, BinaryOperator::FloorDiv}}, | ||
29 | //*/ | ||
30 | // Assignment | ||
31 | {"=", {50, true , tok_assign}}, | ||
32 | // Logic | ||
33 | {"~", {40, false, tok_operator, BinaryOperator::None, UnaryOperator::Invert}}, | ||
34 | {"<<", {40, false, tok_operator, BinaryOperator::LShift}}, | ||
35 | {">>", {40, false, tok_operator, BinaryOperator::RShift}}, | ||
36 | {"^", {40, false, tok_operator, BinaryOperator::BitXor}}, | ||
37 | {"&", {40, true , tok_operator, BinaryOperator::BitAnd}}, | ||
38 | {"and", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::And}}, | ||
39 | {"|", {40, true , tok_operator, BinaryOperator::BitOr}}, | ||
40 | {"or", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::Or}}, | ||
41 | {"!", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::Not}}, | ||
42 | {"not", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::Not}}, | ||
43 | // Comparison | ||
44 | {"==", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::Eq}}, | ||
45 | {"!=", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::NotEq}}, | ||
46 | {">=", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::GtE}}, | ||
47 | {"<=", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::LtE}}, | ||
48 | {">", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::Gt}}, | ||
49 | {"<", {40, true , tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::Lt}}, | ||
50 | // membership | ||
51 | {"in", {40, false, tok_in , BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::In}}, | ||
52 | {"not in", {40, false, tok_in , BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::NotIn}}, | ||
53 | // identity | ||
54 | {"is", {40, false, tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::Is}}, | ||
55 | {"is not", {40, false, tok_operator, BinaryOperator::None, UnaryOperator::None, BoolOperator::None, CmpOperator::IsNot}}, | ||
56 | // Not an operator but we use same data structure for parsing | ||
57 | {"->", {10, false, tok_arrow}}, | ||
58 | {":=", {10, false, tok_walrus}}, | ||
59 | {":", {10, false, (TokenType)':'}}, | ||
60 | {".", {60, true , tok_dot}}, | ||
61 |
6/11✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12872 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 12 times.
✓ Branch 10 taken 492 times.
✓ Branch 11 taken 12 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
13388 | }; |
62 | // clang-format on | ||
63 | 12884 | return val; | |
64 | 24 | } | |
65 | |||
66 | std::ostream& AbstractLexer::debug_print(std::ostream& out) { | ||
67 | |||
68 | ✗ | Token t = next_token(); | |
69 | ✗ | int k = 1; | |
70 | do { | ||
71 | ✗ | out << fmt::format("{:4}", k) << " "; | |
72 | ✗ | t.debug_print(out) << std::endl; | |
73 | ✗ | k += 1; | |
74 | ✗ | } while ((t = next_token())); | |
75 | |||
76 | ✗ | out << fmt::format("{:4}", k) << " "; | |
77 | ✗ | t.debug_print(out) << std::endl; // eof | |
78 | |||
79 | ✗ | return out; | |
80 | ✗ | } | |
81 | |||
82 | // print out tokens as they were inputed | ||
83 | std::ostream& AbstractLexer::print(std::ostream& out) { | ||
84 | |||
85 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 4 taken 16 times.
|
16 | Token t = next_token(); |
86 | 16 | Unlex unlex; | |
87 | |||
88 | do { | ||
89 |
1/1✓ Branch 1 taken 339 times.
|
339 | unlex.format(out, t); |
90 |
4/4✓ Branch 1 taken 339 times.
✓ Branch 4 taken 339 times.
✓ Branch 7 taken 323 times.
✓ Branch 8 taken 16 times.
|
339 | } while ((t = next_token())); |
91 | |||
92 | // send eof for reset | ||
93 |
1/1✓ Branch 1 taken 16 times.
|
16 | unlex.format(out, t); |
94 | |||
95 | 16 | return out; | |
96 | 16 | } | |
97 | |||
98 | int Lexer::get_mode() const { | ||
99 | 55 | return int(_fmtstr); | |
100 | } | ||
101 | |||
102 | void Lexer::set_mode(int mode) { | ||
103 | 110 | _fmtstr = mode > 0; | |
104 | 110 | } | |
105 | |||
106 | Token const& Lexer::format_tokenizer() { | ||
107 | 195 | char c = peek(); | |
108 | 195 | nextc(); | |
109 | 195 | return make_token(c); | |
110 | } | ||
111 | |||
112 | |||
113 | Token const& Lexer::next_token() { | ||
114 | 12838 | _count += 1; | |
115 | |||
116 | // if we peeked ahead return that one | ||
117 |
2/2✓ Branch 1 taken 168 times.
✓ Branch 2 taken 12670 times.
|
12838 | if (_buffer.size() > 0) { |
118 | 168 | _token = _buffer[_buffer.size() - 1]; | |
119 | 168 | _buffer.pop_back(); | |
120 | 168 | return _token; | |
121 | } | ||
122 | |||
123 |
2/2✓ Branch 0 taken 195 times.
✓ Branch 1 taken 12475 times.
|
12670 | if (_fmtstr) { |
124 | 195 | return format_tokenizer(); | |
125 | } | ||
126 | |||
127 | 12475 | char c = peek(); | |
128 | |||
129 | // newline | ||
130 |
2/2✓ Branch 0 taken 1216 times.
✓ Branch 1 taken 11259 times.
|
12475 | if (c == '\n') { |
131 | // Only reset current indentation once in case of double new_lines | ||
132 |
2/2✓ Branch 0 taken 578 times.
✓ Branch 1 taken 638 times.
|
1216 | if (_cindent != 0) { |
133 | 578 | _oindent = _cindent; | |
134 | 578 | _cindent = 0; | |
135 | } | ||
136 | 1216 | consume(); | |
137 | 1216 | return make_token(tok_newline); | |
138 | } | ||
139 | |||
140 |
2/2✓ Branch 0 taken 2528 times.
✓ Branch 1 taken 8731 times.
|
11259 | if (c == EOF) |
141 | 2528 | return make_token(tok_eof); | |
142 | |||
143 | // Indentation | ||
144 | // -------------------------------- | ||
145 |
6/6✓ Branch 0 taken 4206 times.
✓ Branch 1 taken 4525 times.
✓ Branch 3 taken 742 times.
✓ Branch 4 taken 3464 times.
✓ Branch 5 taken 742 times.
✓ Branch 6 taken 7989 times.
|
8731 | if (c == ' ' && empty_line()) { |
146 | 742 | int k = 1; | |
147 | do { | ||
148 | 2226 | c = nextc(); | |
149 | 2226 | k++; | |
150 | |||
151 |
4/4✓ Branch 0 taken 742 times.
✓ Branch 1 taken 1484 times.
✓ Branch 2 taken 740 times.
✓ Branch 3 taken 2 times.
|
2226 | if (k == LYTHON_INDENT && c == ' ') { |
152 | 740 | consume(); | |
153 | 740 | break; | |
154 | } | ||
155 |
2/2✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 2 times.
|
1486 | } while (c == ' '); |
156 | |||
157 | 742 | _cindent += LYTHON_INDENT; | |
158 | |||
159 | // if current indent is the same do nothing | ||
160 |
2/2✓ Branch 0 taken 330 times.
✓ Branch 1 taken 412 times.
|
742 | if (_cindent <= _oindent) |
161 | 330 | return next_token(); | |
162 | |||
163 | // else increase indent | ||
164 | 412 | return make_token(tok_indent); | |
165 | } | ||
166 | |||
167 | // only broadcast desindent on actual code | ||
168 | // comments have no impacts on our indentation level | ||
169 | // | ||
170 | // Doing it here brings another problem: | ||
171 | // - now comment indentation is going to change | ||
172 | // this could be a good thing as it forces comment | ||
173 | // to be at the "right" indentation | ||
174 | // | ||
175 | // but if you write a comment after a class its indentation is going to be wrong | ||
176 | // | ||
177 | // class X: | ||
178 | // # comment | ||
179 | // def __init__(self): | ||
180 | // ... | ||
181 | // | ||
182 | // becomes | ||
183 | // | ||
184 | // class X: | ||
185 | // # comment | ||
186 | // def __init__(self): | ||
187 | // ... | ||
188 | // | ||
189 | // and | ||
190 | // | ||
191 | // for i in range(10): | ||
192 | // ... | ||
193 | // # comment | ||
194 | // | ||
195 | // becomes | ||
196 | // | ||
197 | // for i in range(10): | ||
198 | // ... | ||
199 | // # comment | ||
200 | // | ||
201 | // 1) is ok, the comment was written inside a statement block | ||
202 | // 2) is problematic, the comment was written outside the block | ||
203 | // but we cannot tell until we reached a desindent block | ||
204 | // which happens AFTER the comment | ||
205 | // | ||
206 | // SOLUTION: make the parser associate comment with the comming statement | ||
207 | #define FORCE_COMMENT_INDENT(X) X | ||
208 | |||
209 |
4/4✓ Branch 0 taken 163 times.
✓ Branch 1 taken 7826 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 151 times.
|
7989 | bool desindent_comment = _cindent < _oindent && c == tok_comment; |
210 | |||
211 |
2/2✓ Branch 0 taken 163 times.
✓ Branch 1 taken 7826 times.
|
7989 | if (_cindent < _oindent) { |
212 | // TODO: this behaviour is not good for the Unlexer | ||
213 | // but it is fine for the parser | ||
214 |
2/2✓ Branch 0 taken 151 times.
✓ Branch 1 taken 12 times.
|
163 | if (FORCE_COMMENT_INDENT(c != tok_comment)) { |
215 | 151 | _oindent -= LYTHON_INDENT; | |
216 | 151 | return make_token(tok_desindent); | |
217 | } else { | ||
218 | // reset current indent to match previous indentation level | ||
219 | // because comment indentation do not matter | ||
220 | 12 | _cindent = _oindent; | |
221 | } | ||
222 | } | ||
223 | |||
224 | // remove white space | ||
225 |
2/2✓ Branch 0 taken 3794 times.
✓ Branch 1 taken 7838 times.
|
11632 | while (c == ' ') { |
226 | 3794 | c = nextc(); | |
227 | } | ||
228 | |||
229 | // Identifiers | ||
230 | // ----------- | ||
231 |
4/4✓ Branch 0 taken 3777 times.
✓ Branch 1 taken 4061 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 3762 times.
|
7838 | if ((isalpha(c) || c == '_')) { |
232 | 4076 | String identifier; | |
233 | |||
234 | // FIXME: check that ident can be an identifier | ||
235 |
1/1✓ Branch 1 taken 4076 times.
|
4076 | identifier.push_back(c); |
236 | |||
237 |
3/3✓ Branch 1 taken 10425 times.
✓ Branch 4 taken 6349 times.
✓ Branch 5 taken 4076 times.
|
10425 | while (is_identifier(c = nextc())) { |
238 |
1/1✓ Branch 1 taken 6349 times.
|
6349 | identifier.push_back(c); |
239 | } | ||
240 | |||
241 | // is it a string operator (is, not, in, and, or) ? | ||
242 | { | ||
243 |
2/2✓ Branch 1 taken 4076 times.
✓ Branch 4 taken 4076 times.
|
4076 | auto result = default_precedence().find(identifier); |
244 |
3/3✓ Branch 1 taken 4076 times.
✓ Branch 5 taken 119 times.
✓ Branch 6 taken 3957 times.
|
4076 | if (result != default_precedence().end()) { |
245 | 119 | OpConfig const& conf = result->second; | |
246 |
1/1✓ Branch 2 taken 119 times.
|
119 | Token tok = dummy(); |
247 | |||
248 | // combine is not & not in right now | ||
249 |
6/6✓ Branch 1 taken 105 times.
✓ Branch 2 taken 14 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 91 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 91 times.
|
119 | if (identifier == "is" || identifier == "not") { |
250 |
2/2✓ Branch 1 taken 28 times.
✓ Branch 4 taken 28 times.
|
28 | tok = next_token(); |
251 | } else { | ||
252 |
1/1✓ Branch 1 taken 91 times.
|
91 | return make_token(conf.type, identifier); |
253 | } | ||
254 | |||
255 |
6/6✓ Branch 1 taken 14 times.
✓ Branch 2 taken 14 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 7 times.
✓ Branch 8 taken 21 times.
|
28 | if (identifier == "is" && tok.operator_name() == "not") { |
256 |
2/2✓ Branch 2 taken 7 times.
✓ Branch 5 taken 7 times.
|
7 | return make_token(conf.type, "is not"); |
257 | } | ||
258 | |||
259 |
6/6✓ Branch 1 taken 14 times.
✓ Branch 2 taken 7 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 7 times.
✓ Branch 8 taken 14 times.
|
21 | if (identifier == "not" && tok.operator_name() == "in") { |
260 |
2/2✓ Branch 2 taken 7 times.
✓ Branch 5 taken 7 times.
|
7 | return make_token(conf.type, "not in"); |
261 | } | ||
262 | |||
263 |
1/1✓ Branch 1 taken 14 times.
|
14 | _buffer.push_back(tok); |
264 |
1/1✓ Branch 1 taken 14 times.
|
14 | return make_token(conf.type, identifier); |
265 | 119 | } | |
266 | } | ||
267 | |||
268 | // is it a keyword ? | ||
269 | { | ||
270 |
2/2✓ Branch 1 taken 3957 times.
✓ Branch 4 taken 3957 times.
|
3957 | auto result = keywords().find(identifier); |
271 |
3/3✓ Branch 1 taken 3957 times.
✓ Branch 5 taken 1189 times.
✓ Branch 6 taken 2768 times.
|
3957 | if (result != keywords().end()) { |
272 |
1/1✓ Branch 2 taken 1189 times.
|
1189 | return make_token(result->second); |
273 | } | ||
274 | } | ||
275 | |||
276 | // is it followed by a quote | ||
277 |
5/6✓ Branch 1 taken 2750 times.
✓ Branch 2 taken 18 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2750 times.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 2750 times.
|
2768 | if (peek() == '"' || peek() == '\'') { |
278 |
1/1✓ Branch 1 taken 18 times.
|
18 | return make_token(tok_formatstr, identifier); |
279 | } | ||
280 | |||
281 | // then it must be an identifier | ||
282 |
1/1✓ Branch 1 taken 2750 times.
|
2750 | return make_token(tok_identifier, identifier); |
283 | 4076 | } | |
284 | |||
285 | // Operators | ||
286 | // ----------------------------------------------- | ||
287 | // c is not alpha num | ||
288 | { | ||
289 | 3762 | auto next = _operators.match(c); | |
290 |
2/2✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 2282 times.
|
3762 | if (next != nullptr) { |
291 | 1480 | String op; | |
292 |
1/1✓ Branch 1 taken 1480 times.
|
1480 | op.reserve(6); |
293 | 1480 | auto prev = next; | |
294 | |||
295 |
2/2✓ Branch 0 taken 1628 times.
✓ Branch 1 taken 1480 times.
|
3108 | while (next != nullptr) { |
296 |
1/1✓ Branch 1 taken 1628 times.
|
1628 | op.push_back(c); |
297 |
1/1✓ Branch 1 taken 1628 times.
|
1628 | c = nextc(); |
298 | 1628 | prev = next; | |
299 |
1/1✓ Branch 1 taken 1628 times.
|
1628 | next = prev->matching(c); |
300 | } | ||
301 | |||
302 |
1/2✓ Branch 1 taken 1480 times.
✗ Branch 2 not taken.
|
1480 | if (prev->leaf()) { |
303 |
1/1✓ Branch 1 taken 1480 times.
|
1480 | op = strip(op); |
304 |
2/2✓ Branch 1 taken 1480 times.
✓ Branch 4 taken 1480 times.
|
1480 | auto result = default_precedence().find(op); |
305 |
2/3✓ Branch 1 taken 1480 times.
✓ Branch 5 taken 1480 times.
✗ Branch 6 not taken.
|
1480 | if (result != default_precedence().end()) { |
306 | 1480 | OpConfig const& conf = result->second; | |
307 |
1/1✓ Branch 1 taken 1480 times.
|
1480 | return make_token(conf.type, op); |
308 | } | ||
309 | } | ||
310 | 1480 | } | |
311 | } | ||
312 | |||
313 | // Numbers | ||
314 | // ----------------------------------------------- | ||
315 |
2/2✓ Branch 0 taken 436 times.
✓ Branch 1 taken 1846 times.
|
2282 | if (std::isdigit(c)) { |
316 | 436 | String num; | |
317 | 436 | TokenType ntype = tok_int; | |
318 | |||
319 |
2/2✓ Branch 0 taken 445 times.
✓ Branch 1 taken 436 times.
|
881 | while (std::isdigit(c)) { |
320 |
1/1✓ Branch 1 taken 445 times.
|
445 | num.push_back(c); |
321 |
1/1✓ Branch 1 taken 445 times.
|
445 | c = nextc(); |
322 | } | ||
323 | |||
324 |
2/2✓ Branch 0 taken 88 times.
✓ Branch 1 taken 348 times.
|
436 | if (c == '.') { |
325 | 88 | ntype = tok_float; | |
326 |
1/1✓ Branch 1 taken 88 times.
|
88 | num.push_back(c); |
327 |
1/1✓ Branch 1 taken 88 times.
|
88 | c = nextc(); |
328 |
2/2✓ Branch 0 taken 88 times.
✓ Branch 1 taken 88 times.
|
176 | while (std::isdigit(c)) { |
329 |
1/1✓ Branch 1 taken 88 times.
|
88 | num.push_back(c); |
330 |
1/1✓ Branch 1 taken 88 times.
|
88 | c = nextc(); |
331 | } | ||
332 | } | ||
333 | |||
334 | /*/ Incorrect Numbers | ||
335 | while (c != ' ' && c != '\n' && c != EOF){ | ||
336 | num.push_back(c); | ||
337 | c = nextc(); | ||
338 | ntype = tok_incorrect; | ||
339 | }*/ | ||
340 | |||
341 | // std::cout << '"' << num << '"' << ntype << ',' << tok_incorrect << std::endl; | ||
342 | // throw 0; | ||
343 |
1/1✓ Branch 1 taken 436 times.
|
436 | return make_token(ntype, num); |
344 | 436 | } | |
345 | |||
346 | // Strings | ||
347 | // -------------------------------------------------- | ||
348 | |||
349 | // Regular string | ||
350 | // -------------- | ||
351 |
3/4✓ Branch 0 taken 1761 times.
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1761 times.
|
1846 | if (c == '"' || c == '\'') { |
352 | 85 | char end = c; | |
353 | 85 | String str; | |
354 | 85 | TokenType tok = tok_string; | |
355 |
1/1✓ Branch 1 taken 85 times.
|
85 | char c2 = nextc(); |
356 | 85 | char c3 = '\0'; | |
357 | |||
358 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 69 times.
|
85 | if (c2 == end) { |
359 |
1/1✓ Branch 1 taken 16 times.
|
16 | char c3 = nextc(); |
360 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | if (c3 == end) { |
361 | 16 | tok = tok_docstring; | |
362 | } else { | ||
363 | ✗ | str.push_back(c2); | |
364 | ✗ | str.push_back(c3); | |
365 | } | ||
366 | } else { | ||
367 |
1/1✓ Branch 1 taken 69 times.
|
69 | str.push_back(c2); |
368 | } | ||
369 | |||
370 |
2/2✓ Branch 0 taken 69 times.
✓ Branch 1 taken 16 times.
|
85 | if (tok == tok_string) |
371 |
6/7✓ Branch 1 taken 175 times.
✓ Branch 3 taken 106 times.
✓ Branch 4 taken 69 times.
✓ Branch 5 taken 106 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 106 times.
✓ Branch 8 taken 69 times.
|
175 | while ((c = nextc()) != end && c != EOF) { |
372 |
1/1✓ Branch 1 taken 106 times.
|
106 | str.push_back(c); |
373 | } | ||
374 | else { | ||
375 |
1/2✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
|
180 | while (c != EOF) { |
376 |
1/1✓ Branch 1 taken 180 times.
|
180 | c = nextc(); |
377 | |||
378 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 164 times.
|
180 | if (c == end) { |
379 |
1/1✓ Branch 1 taken 16 times.
|
16 | c2 = nextc(); |
380 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | if (c2 == end) { |
381 |
1/1✓ Branch 1 taken 16 times.
|
16 | c3 = nextc(); |
382 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | if (c3 == end) { |
383 | 16 | break; | |
384 | } else { | ||
385 | ✗ | str.push_back(c); | |
386 | ✗ | str.push_back(c2); | |
387 | ✗ | str.push_back(c3); | |
388 | } | ||
389 | } else { | ||
390 | ✗ | str.push_back(c); | |
391 | ✗ | str.push_back(c2); | |
392 | } | ||
393 | } else { | ||
394 |
1/1✓ Branch 1 taken 164 times.
|
164 | str.push_back(c); |
395 | } | ||
396 | } | ||
397 | } | ||
398 |
1/1✓ Branch 1 taken 85 times.
|
85 | consume(); |
399 |
1/1✓ Branch 1 taken 85 times.
|
85 | return make_token(tok, str); |
400 | 85 | } | |
401 | |||
402 | 1761 | c = peek(); | |
403 |
2/2✓ Branch 0 taken 278 times.
✓ Branch 1 taken 1483 times.
|
1761 | if (c == tok_comment) { |
404 | 278 | String comment; | |
405 |
1/1✓ Branch 1 taken 278 times.
|
278 | comment.reserve(128); |
406 | |||
407 | // eat the comment token | ||
408 |
1/1✓ Branch 1 taken 278 times.
|
278 | c = nextc(); |
409 | |||
410 | // eat all characters until the newline | ||
411 |
3/4✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 278 times.
✓ Branch 2 taken 4173 times.
✗ Branch 3 not taken.
|
4451 | while (c != '\n' && c != EOF) { |
412 |
1/1✓ Branch 1 taken 4173 times.
|
4173 | comment.push_back(c); |
413 |
1/1✓ Branch 1 taken 4173 times.
|
4173 | c = nextc(); |
414 | }; | ||
415 | |||
416 |
1/1✓ Branch 1 taken 278 times.
|
278 | return make_token(tok_comment, comment); |
417 | 278 | } | |
418 | |||
419 | // get next char | ||
420 | 1483 | c = peek(); | |
421 | 1483 | consume(); | |
422 | |||
423 |
1/2✓ Branch 0 taken 1483 times.
✗ Branch 1 not taken.
|
1483 | if (c > 0) { |
424 | 1483 | return make_token(c); | |
425 | } | ||
426 | ✗ | return make_token(tok_incorrect); | |
427 | } | ||
428 | |||
429 | } // namespace lython | ||
430 |