()
| 593 | // the end of the source string. A token may be a string, number, `null` |
| 594 | // literal, or Boolean literal. |
| 595 | var lex = function () { |
| 596 | var source = Source, length = source.length, value, begin, position, isSigned, charCode; |
| 597 | while (Index < length) { |
| 598 | charCode = source.charCodeAt(Index); |
| 599 | switch (charCode) { |
| 600 | case 9: case 10: case 13: case 32: |
| 601 | // Skip whitespace tokens, including tabs, carriage returns, line |
| 602 | // feeds, and space characters. |
| 603 | Index++; |
| 604 | break; |
| 605 | case 123: case 125: case 91: case 93: case 58: case 44: |
| 606 | // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at |
| 607 | // the current position. |
| 608 | value = charIndexBuggy ? source.charAt(Index) : source[Index]; |
| 609 | Index++; |
| 610 | return value; |
| 611 | case 34: |
| 612 | // `"` delimits a JSON string; advance to the next character and |
| 613 | // begin parsing the string. String tokens are prefixed with the |
| 614 | // sentinel `@` character to distinguish them from punctuators and |
| 615 | // end-of-string tokens. |
| 616 | for (value = "@", Index++; Index < length;) { |
| 617 | charCode = source.charCodeAt(Index); |
| 618 | if (charCode < 32) { |
| 619 | // Unescaped ASCII control characters (those with a code unit |
| 620 | // less than the space character) are not permitted. |
| 621 | abort(); |
| 622 | } else if (charCode == 92) { |
| 623 | // A reverse solidus (`\`) marks the beginning of an escaped |
| 624 | // control character (including `"`, `\`, and `/`) or Unicode |
| 625 | // escape sequence. |
| 626 | charCode = source.charCodeAt(++Index); |
| 627 | switch (charCode) { |
| 628 | case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114: |
| 629 | // Revive escaped control characters. |
| 630 | value += Unescapes[charCode]; |
| 631 | Index++; |
| 632 | break; |
| 633 | case 117: |
| 634 | // `\u` marks the beginning of a Unicode escape sequence. |
| 635 | // Advance to the first character and validate the |
| 636 | // four-digit code point. |
| 637 | begin = ++Index; |
| 638 | for (position = Index + 4; Index < position; Index++) { |
| 639 | charCode = source.charCodeAt(Index); |
| 640 | // A valid sequence comprises four hexdigits (case- |
| 641 | // insensitive) that form a single hexadecimal value. |
| 642 | if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { |
| 643 | // Invalid Unicode escape sequence. |
| 644 | abort(); |
| 645 | } |
| 646 | } |
| 647 | // Revive the escaped character. |
| 648 | value += fromCharCode("0x" + source.slice(begin, Index)); |
| 649 | break; |
| 650 | default: |
| 651 | // Invalid escape sequence. |
| 652 | abort(); |
no test coverage detected