| 477 | } |
| 478 | |
| 479 | CheckedError Parser::Next() { |
| 480 | doc_comment_.clear(); |
| 481 | prev_cursor_ = cursor_; |
| 482 | bool seen_newline = cursor_ == source_; |
| 483 | attribute_.clear(); |
| 484 | attr_is_trivial_ascii_string_ = true; |
| 485 | for (;;) { |
| 486 | char c = *cursor_++; |
| 487 | token_ = c; |
| 488 | switch (c) { |
| 489 | case '\0': |
| 490 | cursor_--; |
| 491 | token_ = kTokenEof; |
| 492 | return NoError(); |
| 493 | case ' ': |
| 494 | case '\r': |
| 495 | case '\t': break; |
| 496 | case '\n': |
| 497 | MarkNewLine(); |
| 498 | seen_newline = true; |
| 499 | break; |
| 500 | case '{': |
| 501 | case '}': |
| 502 | case '(': |
| 503 | case ')': |
| 504 | case '[': |
| 505 | case ']': |
| 506 | case '<': |
| 507 | case '>': |
| 508 | case ',': |
| 509 | case ':': |
| 510 | case ';': |
| 511 | case '=': return NoError(); |
| 512 | case '\"': |
| 513 | case '\'': { |
| 514 | int unicode_high_surrogate = -1; |
| 515 | |
| 516 | while (*cursor_ != c) { |
| 517 | if (*cursor_ < ' ' && static_cast<signed char>(*cursor_) >= 0) |
| 518 | return Error("illegal character in string constant"); |
| 519 | if (*cursor_ == '\\') { |
| 520 | attr_is_trivial_ascii_string_ = false; // has escape sequence |
| 521 | cursor_++; |
| 522 | if (unicode_high_surrogate != -1 && *cursor_ != 'u') { |
| 523 | return Error( |
| 524 | "illegal Unicode sequence (unpaired high surrogate)"); |
| 525 | } |
| 526 | switch (*cursor_) { |
| 527 | case 'n': |
| 528 | attribute_ += '\n'; |
| 529 | cursor_++; |
| 530 | break; |
| 531 | case 't': |
| 532 | attribute_ += '\t'; |
| 533 | cursor_++; |
| 534 | break; |
| 535 | case 'r': |
| 536 | attribute_ += '\r'; |
nothing calls this directly
no test coverage detected