parse_number() * * Parse a double. */
| 568 | * Parse a double. |
| 569 | */ |
| 570 | Json parse_number() { |
| 571 | size_t start_pos = i; |
| 572 | |
| 573 | if (str[i] == '-') |
| 574 | i++; |
| 575 | |
| 576 | // Integer part |
| 577 | if (str[i] == '0') { |
| 578 | i++; |
| 579 | if (in_range(str[i], '0', '9')) |
| 580 | return fail("Leading 0s not permitted in numbers"); |
| 581 | } else if (in_range(str[i], '1', '9')) { |
| 582 | i++; |
| 583 | while (in_range(str[i], '0', '9')) |
| 584 | i++; |
| 585 | } else { |
| 586 | return fail("Invalid " + esc(str[i]) + " in number"); |
| 587 | } |
| 588 | |
| 589 | if (str[i] != '.' && str[i] != 'e' && str[i] != 'E' |
| 590 | && (i - start_pos) <= static_cast<size_t>(std::numeric_limits<int>::digits10)) { |
| 591 | return std::atoi(str.c_str() + start_pos); |
| 592 | } |
| 593 | |
| 594 | // Decimal part |
| 595 | if (str[i] == '.') { |
| 596 | i++; |
| 597 | if (!in_range(str[i], '0', '9')) |
| 598 | return fail("At least one digit required in fractional part"); |
| 599 | |
| 600 | while (in_range(str[i], '0', '9')) |
| 601 | i++; |
| 602 | } |
| 603 | |
| 604 | // Exponent part |
| 605 | if (str[i] == 'e' || str[i] == 'E') { |
| 606 | i++; |
| 607 | |
| 608 | if (str[i] == '+' || str[i] == '-') |
| 609 | i++; |
| 610 | |
| 611 | if (!in_range(str[i], '0', '9')) |
| 612 | return fail("At least one digit required in exponent"); |
| 613 | |
| 614 | while (in_range(str[i], '0', '9')) |
| 615 | i++; |
| 616 | } |
| 617 | |
| 618 | return std::strtod(str.c_str() + start_pos, nullptr); |
| 619 | } |
| 620 | |
| 621 | /* expect(str, res) |
| 622 | * |