diff options
-rw-r--r-- | src/tree.cc | 48 | ||||
-rw-r--r-- | src/utils.cc | 61 | ||||
-rw-r--r-- | src/utils.h | 13 |
3 files changed, 73 insertions, 49 deletions
diff --git a/src/tree.cc b/src/tree.cc index 81de460..2dfb786 100644 --- a/src/tree.cc +++ b/src/tree.cc @@ -123,21 +123,21 @@ Node* Tree::buildTree(std::string term) { std::vector<std::string> tmpLexer; std::vector<std::string> lexerOutput = lexer(term); - int8_t priority; - for ( auto termIter = lexerOutput.begin(); termIter != lexerOutput.end(); termIter++ ) { - std::string& currTerm = (*termIter); - priority = getPriority(currTerm[0]); + const std::string& currTerm = (*termIter); + const TokenType token = getTokenType(currTerm[0]); - if ( priority != -1 && priority != 100 && (*termIter).size() == 1 ) { + if ( token != TokenType::VALUE_NUMBER && + token != TokenType::VALUE_IDENTIFIER && + (*termIter).size() == 1 ) { if ( !operatorStack.empty() ) { OperatorNode* lastNode( static_cast<OperatorNode*>(topNodeFrom(operatorStack)) ); - if ( getPriority(lastNode->getFunction()) < priority ) { + if ( token > getTokenType(lastNode->getFunction()) ) { operatorStack.push( this->addOperator(nullptr, currTerm[0]) ); @@ -164,20 +164,30 @@ Node* Tree::buildTree(std::string term) { tmpLexer = lexer(*termIter); if ( tmpLexer.size() == 1 ) { - if ( getPriority(tmpLexer[0][0]) == -1 ) { - double value; - std::istringstream convertStream(tmpLexer[0]); - convertStream >> value; - - operandStack.push( - this->addOperand(nullptr,value) - ); - } else if ( getPriority(tmpLexer[0][0]) == 100 ) { - operandStack.push( - this->addOperand(nullptr,tmpLexer[0]) - ); + switch ( getTokenType(tmpLexer[0][0]) ) { + case TokenType::VALUE_NUMBER: { + double value; + std::istringstream convertStream(tmpLexer[0]); + convertStream >> value; + + operandStack.push( + this->addOperand(nullptr,value) + ); + + break; + } + case TokenType::VALUE_IDENTIFIER: { + operandStack.push( + this->addOperand(nullptr,tmpLexer[0]) + ); + + break; + } + default: { + throw operator_exception(); + } } - } else if ( tmpLexer.size() > 1 ) { + } else { operandStack.push( buildTree(*termIter) ); diff --git a/src/utils.cc b/src/utils.cc index 8914166..4e2ed91 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -6,29 +6,29 @@ namespace SimpleParser { -int8_t getPriority(char tmp) { +TokenType getTokenType(char tmp) { if ( std::isalpha(tmp) ) { - return 100; + return TokenType::VALUE_IDENTIFIER; } else { switch ( tmp ) { case '-': - return 10; + return TokenType::OPERATOR_PLUS; case '+': - return 10; + return TokenType::OPERATOR_MINUS; case '/': - return 20; + return TokenType::OPERATOR_DIVIDE; case '*': - return 20; + return TokenType::OPERATOR_MULTIPLY; case '^': - return 30; + return TokenType::OPERATOR_POWER; case '(': - return 90; + return TokenType::PARENTHESES_OPEN; case ')': - return 90; + return TokenType::PARENTHESES_CLOSE; case ',': - return -1; + return TokenType::VALUE_NUMBER; default: - return -1; + return TokenType::VALUE_NUMBER; } } } @@ -38,40 +38,42 @@ std::vector<std::string> lexer(std::string term) { std::string tmpNumber; std::string tmpIdentifier; std::vector<std::string> output; + TokenType token; + TokenType lastToken; - int8_t priority = 0; - int8_t lastPriority = 0; - uint32_t level = 0; + uint32_t level = 0; for ( auto termIter = term.begin(); termIter != term.end(); termIter++ ) { - priority = getPriority(*termIter); + token = getTokenType(*termIter); - if ( priority == -1 || priority == 100 || ( termIter == term.begin() && - priority == 10 ) ) { + if ( token == TokenType::VALUE_NUMBER || + token == TokenType::VALUE_IDENTIFIER || + ( token == TokenType::OPERATOR_MINUS && + termIter == term.begin() ) ) { if ( level > 0 ) { tmp += *termIter; } else { - if ( priority == -1 ) { + if ( token == TokenType::VALUE_NUMBER ) { tmpNumber += *termIter; - } else if ( priority == 100 ) { + } else if ( token == TokenType::VALUE_IDENTIFIER ) { tmpIdentifier += *termIter; } } } else { if ( level == 0 ) { - if ( lastPriority == -1 ) { + if ( lastToken == TokenType::VALUE_NUMBER ) { output.push_back(tmpNumber); tmpNumber.clear(); - } else if ( lastPriority == 100 ) { + } else if ( lastToken == TokenType::VALUE_IDENTIFIER ) { output.push_back(tmpIdentifier); tmpIdentifier.clear(); } } - switch ( *termIter ) { - case '(': { + switch ( token ) { + case TokenType::PARENTHESES_OPEN: { if ( level > 0 ) { tmp += *termIter; } @@ -80,7 +82,7 @@ std::vector<std::string> lexer(std::string term) { break; } - case ')': { + case TokenType::PARENTHESES_CLOSE: { level--; if ( level == 0 ) { @@ -107,14 +109,14 @@ std::vector<std::string> lexer(std::string term) { } } - lastPriority = priority; + lastToken = token; } - if ( lastPriority == -1 ) { + if ( lastToken == TokenType::VALUE_NUMBER ) { output.push_back(tmpNumber); - } else if ( lastPriority == 100 ) { + } else if ( lastToken == TokenType::VALUE_IDENTIFIER ) { output.push_back(tmpIdentifier); - } else if ( lastPriority != 90 ) { + } else if ( lastToken != TokenType::PARENTHESES_CLOSE ) { throw operator_exception(); } @@ -122,7 +124,8 @@ std::vector<std::string> lexer(std::string term) { throw parenthese_exception(); } - if ( lastPriority == 90 && output.size() == 1 ) { + if ( lastToken == TokenType::PARENTHESES_CLOSE && + output.size() == 1 ) { output = lexer(output[0]); } diff --git a/src/utils.h b/src/utils.h index f71c835..6e43605 100644 --- a/src/utils.h +++ b/src/utils.h @@ -8,7 +8,18 @@ namespace SimpleParser { -int8_t getPriority(char); +enum class TokenType : int8_t { + OPERATOR_PLUS = 10, + OPERATOR_MINUS = 11, + OPERATOR_DIVIDE = 20, + OPERATOR_MULTIPLY = 21, + OPERATOR_POWER = 30, + PARENTHESES_OPEN = 90, + PARENTHESES_CLOSE = 91, + VALUE_NUMBER = -1, +}; + +TokenType getTokenType(char); std::vector<std::string> lexer(std::string); } |