MCPcopy Create free account
hub / github.com/GothenburgBitFactory/taskwarrior / infixToPostfix

Method infixToPostfix

src/Eval.cpp:631–687  ·  view source on GitHub ↗

/////////////////////////////////////////////////////////////////////////// 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,

Source from the content-addressed store, hash-verified

629// Exit.
630//
631void 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

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected