#include "parser.h" #include "exceptions.h" #include namespace SimpleParser { int8_t Parser::getPriority(char tmp) { switch ( tmp ) { case '-': return 10; case '+': return 10; case '/': return 20; case '*': return 20; case '^': return 30; case '(': return 90; case ')': return 90; case ',': return -1; default: return -1; } } std::vector Parser::lexer(std::string term) { std::string tmp; std::string tmpNum; std::string::iterator termIter; std::vector output; int8_t priority = 0; int8_t lastPriority = 0; uint32_t level = 0; for ( termIter = term.begin(); termIter != term.end(); termIter++ ) { priority = this->getPriority(*termIter); if ( priority == -1 || ( termIter == term.begin() && priority == 10 ) ) { if ( level > 0 ) { tmp += *termIter; } else { tmpNum += *termIter; } } else { if ( lastPriority == -1 && level == 0 ) { output.push_back(tmpNum); tmpNum.clear(); } switch ( *termIter ) { case '(': { if ( level > 0 ) { tmp += *termIter; } level++; break; } case ')': { level--; if ( level == 0 ) { output.push_back(tmp); tmp.clear(); } else { tmp += *termIter; } break; } default: { if ( level == 0 ) { std::string helper; helper = *termIter; output.push_back(helper); } else { tmp += *termIter; } break; } } } lastPriority = priority; } if ( lastPriority == -1 ) { output.push_back(tmpNum); } else if ( lastPriority != 90 ) { throw operator_exception(); } if (level != 0) { throw parenthese_exception(); } if ( lastPriority == 90 && output.size() == 1 ) { output = lexer(output[0]); } return output; } Node* Parser::buildTree(Tree *tree, std::string term) { std::stack operandStack; std::stack operatorStack; std::vector tmpLexer; std::vector lexerOutput = this->lexer(term); int8_t priority; for ( auto termIter = lexerOutput.begin(); termIter != lexerOutput.end(); termIter++ ) { std::string& currTerm = (*termIter); priority = this->getPriority(currTerm[0]); if ( priority != -1 && (*termIter).size() == 1 ) { if ( !operatorStack.empty() ) { OperatorNode *lastNode = static_cast(operatorStack.top()); if ( this->getPriority(lastNode->getFunction()) < priority ) { operatorStack.push( tree->addOperator(nullptr, currTerm[0]) ); } else { Node *currOperator = operatorStack.top(); operatorStack.pop(); currOperator->rightChild = operandStack.top(); operandStack.pop(); currOperator->leftChild = operandStack.top(); operandStack.pop(); operandStack.push( currOperator ); termIter--; } } else { operatorStack.push(tree->addOperator(nullptr, currTerm[0])); } } else { tmpLexer = this->lexer(*termIter); if ( tmpLexer.size() == 1 ) { double value; std::istringstream convertStream(tmpLexer[0]); convertStream >> value; operandStack.push(tree->addOperand(nullptr,value)); } else if ( tmpLexer.size() > 1 ) { operandStack.push(buildTree(tree, *termIter)); } } } while ( !operatorStack.empty() ) { OperatorNode *currOperator = static_cast(operatorStack.top()); operatorStack.pop(); currOperator->rightChild = operandStack.top(); operandStack.pop(); currOperator->leftChild = operandStack.top(); operandStack.pop(); operandStack.push(currOperator); } return operandStack.top(); } double Parser::calculate(std::string term) { Tree termTree; termTree.setRoot(this->buildTree(&termTree, term)); return termTree.solve(); } }