| 617 | } |
| 618 | |
| 619 | char ExpressionParser::LexInfo::nextToken() { |
| 620 | while (isspace(static_cast<unsigned char>(LastChar))) { |
| 621 | LastChar = static_cast<signed char>(ss.get()); |
| 622 | } |
| 623 | |
| 624 | if (!ss.good()) { |
| 625 | curtok = 0; |
| 626 | return 0; |
| 627 | } |
| 628 | |
| 629 | // Handle numbers |
| 630 | if (isdigit(static_cast<unsigned char>(LastChar)) |
| 631 | || (LastChar == '.')) { // Number: [0-9.]+ |
| 632 | bool gotdecimal = false, gotexponent = false; |
| 633 | std::string NumStr; |
| 634 | |
| 635 | while (true) { |
| 636 | if (LastChar == '.') { |
| 637 | if (gotdecimal || gotexponent) { |
| 638 | throw ParseException("Unexpected '.' in number expression"); |
| 639 | } |
| 640 | gotdecimal = true; |
| 641 | } else if ((LastChar == 'E') || (LastChar == 'e')) { |
| 642 | if (gotexponent) { |
| 643 | throw ParseException( |
| 644 | "ExpressionParser error: Unexpected extra 'e' in number expression"); |
| 645 | } |
| 646 | gotexponent = true; |
| 647 | // Next character should be a '+' or '-' or digit |
| 648 | NumStr += 'e'; |
| 649 | LastChar = static_cast<signed char>(ss.get()); |
| 650 | if ((LastChar != '+') && (LastChar != '-') |
| 651 | && !isdigit(static_cast<unsigned char>(LastChar))) { |
| 652 | throw ParseException( |
| 653 | "ExpressionParser error: Expecting '+', '-' or number after 'e'"); |
| 654 | } |
| 655 | } else if (!isdigit(static_cast<unsigned char>(LastChar))) { |
| 656 | break; |
| 657 | } |
| 658 | |
| 659 | NumStr += LastChar; |
| 660 | LastChar = static_cast<signed char>(ss.get()); |
| 661 | } |
| 662 | |
| 663 | curval = std::stod(NumStr); |
| 664 | curtok = -1; |
| 665 | return curtok; |
| 666 | } |
| 667 | |
| 668 | // Symbols can contain anything else which is not reserved |
| 669 | if ((LastChar == '`') || (reserved_chars.find(LastChar) == std::string::npos)) { |
| 670 | |
| 671 | // Special case: If the last token returned was a number |
| 672 | // then insert a multiplication ("*") |
| 673 | if (curtok == -1) { |
| 674 | curtok = '*'; |
| 675 | return curtok; |
| 676 | } |
no test coverage detected