#include "parser.h" int 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; } } vector Parser::lexer(string term) { int priority = 0; int last_priority = 0; int level = 0; string tmp, tmp_num; vector output; string::iterator termIter; 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 { tmp_num += *termIter; } } else { if ( last_priority == -1 && level == 0 ) { output.push_back( tmp_num ); tmp_num = ""; } switch ( *termIter ) { case '(': { if ( level > 0 ) { tmp += *termIter; } level++; break; } case ')': { level--; if ( level == 0 ) { output.push_back( tmp ); tmp = ""; } else { tmp += *termIter; } break; } default: { if ( level == 0 ) { string helper; helper = *termIter; output.push_back( helper ); } else { tmp += *termIter; } break; } } } last_priority = priority; } if ( last_priority == -1 ) { output.push_back( tmp_num ); } else if ( last_priority != 90 ) { throw operator_exception(); } if (level != 0) { throw parenthese_exception(); } return output; } Node* Parser::buildTree(Tree *tree, string term) { stack operandStack; stack operatorStack; int priority; vector tmpLexer; vector lexerOutput = this->lexer(term); for ( vector::iterator termIter = lexerOutput.begin(); termIter != lexerOutput.end(); termIter++ ) { priority = this->getPriority( (*termIter)[0] ); if ( priority != -1 && (*termIter).size() == 1 ) { if ( !operatorStack.empty() ) { OperatorNode *lastNode = static_cast( operatorStack.top() ); if ( this->getPriority( lastNode->function ) < priority ) { operatorStack.push( tree->addOperator( NULL, (*termIter)[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( NULL, (*termIter)[0] ) ); } } else { tmpLexer = this->lexer( *termIter ); if ( tmpLexer.size() == 1 ) { operandStack.push( tree->addOperand( NULL, strtod( termIter->c_str(), NULL ) ) ); } 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(); } ParserResult Parser::calculate(string term, bool getTreeAsDot) { Tree termTree; termTree.root = this->buildTree(&termTree, term); ParserResult returnVal; returnVal.result = termTree.root->solve(); if ( getTreeAsDot ) { returnVal.tree = termTree.print(term); } return returnVal; }