| 331 | } |
| 332 | |
| 333 | CheckedError Parser::Next() { |
| 334 | doc_comment_.clear(); |
| 335 | bool seen_newline = cursor_ == source_; |
| 336 | attribute_.clear(); |
| 337 | attr_is_trivial_ascii_string_ = true; |
| 338 | for (;;) { |
| 339 | char c = *cursor_++; |
| 340 | token_ = c; |
| 341 | switch (c) { |
| 342 | case '\0': |
| 343 | cursor_--; |
| 344 | token_ = kTokenEof; |
| 345 | return NoError(); |
| 346 | case ' ': |
| 347 | case '\r': |
| 348 | case '\t': break; |
| 349 | case '\n': |
| 350 | MarkNewLine(); |
| 351 | seen_newline = true; |
| 352 | break; |
| 353 | case '{': |
| 354 | case '}': |
| 355 | case '(': |
| 356 | case ')': |
| 357 | case '[': |
| 358 | case ']': |
| 359 | case ',': |
| 360 | case ':': |
| 361 | case ';': |
| 362 | case '=': return NoError(); |
| 363 | case '\"': |
| 364 | case '\'': { |
| 365 | int unicode_high_surrogate = -1; |
| 366 | |
| 367 | while (*cursor_ != c) { |
| 368 | if (*cursor_ < ' ' && static_cast<signed char>(*cursor_) >= 0) |
| 369 | return Error("illegal character in string constant"); |
| 370 | if (*cursor_ == '\\') { |
| 371 | attr_is_trivial_ascii_string_ = false; // has escape sequence |
| 372 | cursor_++; |
| 373 | if (unicode_high_surrogate != -1 && *cursor_ != 'u') { |
| 374 | return Error( |
| 375 | "illegal Unicode sequence (unpaired high surrogate)"); |
| 376 | } |
| 377 | switch (*cursor_) { |
| 378 | case 'n': |
| 379 | attribute_ += '\n'; |
| 380 | cursor_++; |
| 381 | break; |
| 382 | case 't': |
| 383 | attribute_ += '\t'; |
| 384 | cursor_++; |
| 385 | break; |
| 386 | case 'r': |
| 387 | attribute_ += '\r'; |
| 388 | cursor_++; |
| 389 | break; |
| 390 | case 'b': |
no test coverage detected