()
| 2523 | // the end of the source string. A token may be a string, number, `null` |
| 2524 | // literal, or Boolean literal. |
| 2525 | var lex = function () { |
| 2526 | var source = Source, length = source.length, value, begin, position, isSigned, charCode; |
| 2527 | while (Index < length) { |
| 2528 | charCode = source.charCodeAt(Index); |
| 2529 | switch (charCode) { |
| 2530 | case 9: case 10: case 13: case 32: |
| 2531 | // Skip whitespace tokens, including tabs, carriage returns, line |
| 2532 | // feeds, and space characters. |
| 2533 | Index++; |
| 2534 | break; |
| 2535 | case 123: case 125: case 91: case 93: case 58: case 44: |
| 2536 | // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at |
| 2537 | // the current position. |
| 2538 | value = charIndexBuggy ? source.charAt(Index) : source[Index]; |
| 2539 | Index++; |
| 2540 | return value; |
| 2541 | case 34: |
| 2542 | // `"` delimits a JSON string; advance to the next character and |
| 2543 | // begin parsing the string. String tokens are prefixed with the |
| 2544 | // sentinel `@` character to distinguish them from punctuators and |
| 2545 | // end-of-string tokens. |
| 2546 | for (value = "@", Index++; Index < length;) { |
| 2547 | charCode = source.charCodeAt(Index); |
| 2548 | if (charCode < 32) { |
| 2549 | // Unescaped ASCII control characters (those with a code unit |
| 2550 | // less than the space character) are not permitted. |
| 2551 | abort(); |
| 2552 | } else if (charCode == 92) { |
| 2553 | // A reverse solidus (`\`) marks the beginning of an escaped |
| 2554 | // control character (including `"`, `\`, and `/`) or Unicode |
| 2555 | // escape sequence. |
| 2556 | charCode = source.charCodeAt(++Index); |
| 2557 | switch (charCode) { |
| 2558 | case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114: |
| 2559 | // Revive escaped control characters. |
| 2560 | value += Unescapes[charCode]; |
| 2561 | Index++; |
| 2562 | break; |
| 2563 | case 117: |
| 2564 | // `\u` marks the beginning of a Unicode escape sequence. |
| 2565 | // Advance to the first character and validate the |
| 2566 | // four-digit code point. |
| 2567 | begin = ++Index; |
| 2568 | for (position = Index + 4; Index < position; Index++) { |
| 2569 | charCode = source.charCodeAt(Index); |
| 2570 | // A valid sequence comprises four hexdigits (case- |
| 2571 | // insensitive) that form a single hexadecimal value. |
| 2572 | if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { |
| 2573 | // Invalid Unicode escape sequence. |
| 2574 | abort(); |
| 2575 | } |
| 2576 | } |
| 2577 | // Revive the escaped character. |
| 2578 | value += fromCharCode("0x" + source.slice(begin, Index)); |
| 2579 | break; |
| 2580 | default: |
| 2581 | // Invalid escape sequence. |
| 2582 | abort(); |
no test coverage detected