/////////////////////////////////////////////////////////////////////////// Dijkstra Shunting Algorithm. https://en.wikipedia.org/wiki/Shunting-yard_algorithm While there are tokens to be read: Read a token. If the token is an operator, o1, then: while there is an operator token, o2, at the top of the stack, and either o1 is left-associative and its precedence is less than or equal to that of o2,
| 629 | // Exit. |
| 630 | // |
| 631 | void Eval::infixToPostfix(std::vector<std::pair<std::string, Lexer::Type>>& infix) const { |
| 632 | // Short circuit. |
| 633 | if (infix.size() == 1) return; |
| 634 | |
| 635 | // Result. |
| 636 | std::vector<std::pair<std::string, Lexer::Type>> postfix; |
| 637 | |
| 638 | // Shunting yard. |
| 639 | std::vector<std::pair<std::string, Lexer::Type>> op_stack; |
| 640 | |
| 641 | // Operator characteristics. |
| 642 | char type; |
| 643 | unsigned int precedence; |
| 644 | char associativity; |
| 645 | |
| 646 | for (auto& token : infix) { |
| 647 | if (token.second == Lexer::Type::op && token.first == "(") { |
| 648 | op_stack.push_back(token); |
| 649 | } else if (token.second == Lexer::Type::op && token.first == ")") { |
| 650 | while (op_stack.size() && op_stack.back().first != "(") { |
| 651 | postfix.push_back(op_stack.back()); |
| 652 | op_stack.pop_back(); |
| 653 | } |
| 654 | |
| 655 | if (op_stack.size()) |
| 656 | op_stack.pop_back(); |
| 657 | else |
| 658 | throw std::string("Mismatched parentheses in expression"); |
| 659 | } else if (token.second == Lexer::Type::op && |
| 660 | identifyOperator(token.first, type, precedence, associativity)) { |
| 661 | char type2; |
| 662 | unsigned int precedence2; |
| 663 | char associativity2; |
| 664 | while (op_stack.size() > 0 && |
| 665 | identifyOperator(op_stack.back().first, type2, precedence2, associativity2) && |
| 666 | ((associativity == 'l' && precedence <= precedence2) || |
| 667 | (associativity == 'r' && precedence < precedence2))) { |
| 668 | postfix.push_back(op_stack.back()); |
| 669 | op_stack.pop_back(); |
| 670 | } |
| 671 | |
| 672 | op_stack.push_back(token); |
| 673 | } else { |
| 674 | postfix.push_back(token); |
| 675 | } |
| 676 | } |
| 677 | |
| 678 | while (op_stack.size()) { |
| 679 | if (op_stack.back().first == "(" || op_stack.back().first == ")") |
| 680 | throw std::string("Mismatched parentheses in expression"); |
| 681 | |
| 682 | postfix.push_back(op_stack.back()); |
| 683 | op_stack.pop_back(); |
| 684 | } |
| 685 | |
| 686 | infix = postfix; |
| 687 | } |
| 688 |
nothing calls this directly
no outgoing calls
no test coverage detected