From cde848ce1eb995170723f6f070b9fcba0dfdb880 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Sat, 5 Jan 2013 22:30:35 +0100 Subject: Moved node classes into separate compilation unit; File extension change --- Makefile | 12 ++-- main.cc | 27 ++++++++ main.cpp | 27 -------- src/nodes.cc | 77 +++++++++++++++++++++++ src/nodes.h | 53 ++++++++++++++++ src/parser.cc | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/parser.cpp | 190 -------------------------------------------------------- src/parser.h | 19 +----- src/tree.cc | 69 +++++++++++++++++++++ src/tree.cpp | 127 -------------------------------------- src/tree.h | 61 ++---------------- test.cc | 44 +++++++++++++ test.cpp | 44 ------------- 13 files changed, 476 insertions(+), 465 deletions(-) create mode 100644 main.cc delete mode 100644 main.cpp create mode 100644 src/nodes.cc create mode 100644 src/nodes.h create mode 100644 src/parser.cc delete mode 100644 src/parser.cpp create mode 100644 src/tree.cc delete mode 100644 src/tree.cpp create mode 100644 test.cc delete mode 100644 test.cpp diff --git a/Makefile b/Makefile index dcfeee7..6db0c9b 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,15 @@ -LIB_FILES = src/tree.cpp src/parser.cpp -PROG_FILES = main.cpp -TEST_FILES = test.cpp +LIB_FILES = src/nodes.cc src/tree.cc src/parser.cc +PROG_FILES = main.cc +TEST_FILES = test.cc + +FLAGS = -std=c++11 -W -Wall -Wextra -pedantic all: parser test parser: $(PROG_FILES) $(LIB_FILES) - g++ -std=c++11 -g -o bin/parser $(PROG_FILES) $(LIB_FILES) + g++ -g -o bin/parser $(FLAGS) $(PROG_FILES) $(LIB_FILES) test: $(LIB_FILES) $(TEST_FILES) - g++ -std=c++11 -O3 -o bin/test -lgtest $(LIB_FILES) $(TEST_FILES) + g++ -O3 -o bin/test -lgtest $(FLAGS) $(LIB_FILES) $(TEST_FILES) ./bin/test diff --git a/main.cc b/main.cc new file mode 100644 index 0000000..c03cce2 --- /dev/null +++ b/main.cc @@ -0,0 +1,27 @@ +#include +#include + +#include "src/parser.h" + +int main() +{ + std::string inputTerm; + + std::cin >> inputTerm; // Example: 2.5*(2+3-(3/2+1)) + + SimpleParser::Parser parser; + + try { + typedef std::numeric_limits dbl; + std::cout.precision(dbl::digits10); + + std::cout << parser.calculate(inputTerm) << std::endl; + } + catch ( std::exception &e ) + { + std::cerr << e.what() << std::endl; + return 1; + } + + return 0; +} diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 0342e28..0000000 --- a/main.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include - -#include "src/parser.h" - -int main(int argc, char *argv[]) -{ - std::string inputTerm; - - std::cin >> inputTerm; // Example: 2.5*(2+3-(3/2+1)) - - SimpleParser::Parser parser; - - try { - typedef std::numeric_limits dbl; - std::cout.precision(dbl::digits10); - - std::cout << parser.calculate(inputTerm) << std::endl; - } - catch ( std::exception &e ) - { - std::cerr << e.what() << std::endl; - return 1; - } - - return 0; -} diff --git a/src/nodes.cc b/src/nodes.cc new file mode 100644 index 0000000..70b9e50 --- /dev/null +++ b/src/nodes.cc @@ -0,0 +1,77 @@ +#include "nodes.h" +#include "exceptions.h" + +#include +#include +#include + +namespace SimpleParser { + +OperandNode::OperandNode(double val) { + this->value_ = val; +} + +double OperandNode::solve() { + return this->value_; +} + +NodeType OperandNode::getType() { + return OPERAND_NODE; +} + +std::string OperandNode::print() { + std::stringstream convertStream; + convertStream.precision(std::numeric_limits::digits10); + + convertStream << this->value_; + + return convertStream.str(); +} + +OperatorNode::OperatorNode(char op) { + this->function_ = op; +} + +double OperatorNode::solve() { + switch ( this->function_ ) { + case '*': { + return this->leftChild->solve() * this->rightChild->solve(); + } + case '/': { + double rightChild = this->rightChild->solve(); + + if ( rightChild != 0 ) { + return this->leftChild->solve() / rightChild; + } + else { + throw divide_exception(); + } + } + case '+': { + return this->leftChild->solve() + this->rightChild->solve(); + } + case '-': { + return this->leftChild->solve() - this->rightChild->solve(); + } + case '^': { + return std::pow( this->leftChild->solve(), this->rightChild->solve() ); + } + default: { + throw operator_exception(); + } + } +} + +NodeType OperatorNode::getType() { + return OPERATOR_NODE; +} + +std::string OperatorNode::print() { + return std::string(1, this->function_); +} + +char OperatorNode::getFunction() { + return this->function_; +} + +} diff --git a/src/nodes.h b/src/nodes.h new file mode 100644 index 0000000..3a99474 --- /dev/null +++ b/src/nodes.h @@ -0,0 +1,53 @@ +#ifndef PARSER_SRC_NODES_H_ +#define PARSER_SRC_NODES_H_ + +#include + +namespace SimpleParser { + +enum NodeType { + OPERAND_NODE, + OPERATOR_NODE, +}; + +class Node { + public: + virtual ~Node() {}; + + virtual double solve() = 0; + virtual NodeType getType() = 0; + virtual std::string print() = 0; + + Node* leftChild; + Node* rightChild; +}; + +class OperatorNode: public Node { + public: + explicit OperatorNode(char); + + virtual double solve(); + virtual NodeType getType(); + virtual std::string print(); + + char getFunction(); + + private: + char function_; +}; + +class OperandNode: public Node { + public: + explicit OperandNode(double); + + virtual double solve(); + virtual NodeType getType(); + virtual std::string print(); + + private: + double value_; +}; + +} + +#endif // PARSER_SRC_NODES_H_ diff --git a/src/parser.cc b/src/parser.cc new file mode 100644 index 0000000..0f05790 --- /dev/null +++ b/src/parser.cc @@ -0,0 +1,191 @@ +#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(); +} + +} diff --git a/src/parser.cpp b/src/parser.cpp deleted file mode 100644 index 3aaf7e2..0000000 --- a/src/parser.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "parser.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(); -} - -} diff --git a/src/parser.h b/src/parser.h index 12d745a..b943ebe 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,9 +1,8 @@ -#ifndef PARSER_PARSER_H_ -#define PARSER_PARSER_H_ +#ifndef PARSER_SRC_PARSER_H_ +#define PARSER_SRC_PARSER_H_ #include #include -#include #include "tree.h" @@ -19,18 +18,6 @@ class Parser { Node* buildTree(Tree*, std::string); }; -class parenthese_exception: public std::exception { - virtual const char* what() const throw() { - return "Invalid parenthesized expression - check your input term."; - } -}; - -class operator_exception: public std::exception { - virtual const char* what() const throw() { - return "Unexpected operator placement - check your input term."; - } -}; - } -#endif // PARSER_PARSER_H_ +#endif // PARSER_SRC_PARSER_H_ diff --git a/src/tree.cc b/src/tree.cc new file mode 100644 index 0000000..675009e --- /dev/null +++ b/src/tree.cc @@ -0,0 +1,69 @@ +#include "tree.h" +#include "exceptions.h" + +#include +#include + +namespace SimpleParser { + +void Tree::setRoot(Node* root) { + this->root_node_ = root; +} + +double Tree::solve() { + return this->root_node_->solve(); +} + +Node* Tree::addOperand(Node** place, double value) { + this->node_collection_.emplace_back(new OperandNode(value)); + + if ( place != nullptr ) { + *place = this->node_collection_.back().get(); + } + + return this->node_collection_.back().get(); +} + +Node* Tree::addOperator(Node** place, char oper) { + this->node_collection_.emplace_back(new OperatorNode(oper)); + + if ( place != nullptr ) { + *place = this->node_collection_.back().get(); + } + + return this->node_collection_.back().get(); +} + +std::string Tree::print(std::string term) { + std::stringstream out; + out.precision(std::numeric_limits::digits10); + + out << "digraph \"" << term << "\"" << std::endl + << "{" << std::endl + << "node [shape = box];" << std::endl; + + int i = 0; + + for ( auto it = this->node_collection_.begin(); it != this->node_collection_.end(); ++it ) { + out << "node" << i << " [ label = \"" << (*it)->print() << "\"];" << std::endl; + + if ( (*it)->getType() == OPERATOR_NODE ) { + for ( auto iter = this->node_collection_.begin(); iter != this->node_collection_.end(); ++iter ) { + if ( (*iter).get() == (*it)->leftChild ) { + out << "\"node" << i << "\" -> \"node" << (iter - this->node_collection_.begin()) << "\";" << std::endl; + } + if ( (*iter).get() == (*it)->rightChild ) { + out << "\"node" << i << "\" -> \"node" << (iter - this->node_collection_.begin()) << "\";" << std::endl; + } + } + } + + i++; + } + + out << "}" << std::endl; + + return out.str(); +} + +} diff --git a/src/tree.cpp b/src/tree.cpp deleted file mode 100644 index c8f0aac..0000000 --- a/src/tree.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "tree.h" - -#include - -namespace SimpleParser { - -OperandNode::OperandNode(double val) { - this->value_ = val; -} - -double OperandNode::solve() { - return this->value_; -} - -NodeType OperandNode::getType() { - return OPERAND_NODE; -} - -std::string OperandNode::print() { - std::stringstream convertStream; - convertStream.precision(std::numeric_limits::digits10); - - convertStream << this->value_; - - return convertStream.str(); -} - -OperatorNode::OperatorNode(char op) { - this->function_ = op; -} - -double OperatorNode::solve() { - switch ( this->function_ ) { - case '*': - return this->leftChild->solve() * this->rightChild->solve(); - case '/': { - double rightChild = this->rightChild->solve(); - - if ( rightChild != 0 ) { - return this->leftChild->solve() / rightChild; - } - else { - throw divide_exception(); - } - } - case '+': - return this->leftChild->solve() + this->rightChild->solve(); - case '-': - return this->leftChild->solve() - this->rightChild->solve(); - case '^': - return std::pow( this->leftChild->solve(), this->rightChild->solve() ); - } -} - -NodeType OperatorNode::getType() { - return OPERATOR_NODE; -} - -std::string OperatorNode::print() { - return std::string(1, this->function_); -} - -char OperatorNode::getFunction() { - return this->function_; -} - -void Tree::setRoot(Node* root) { - this->root_node_ = root; -} - -double Tree::solve() { - return this->root_node_->solve(); -} - -Node* Tree::addOperand(Node** place, double value) { - this->node_collection_.emplace_back(new OperandNode(value)); - - if ( place != nullptr ) { - *place = this->node_collection_.back().get(); - } - - return this->node_collection_.back().get(); -} - -Node* Tree::addOperator(Node** place, char oper) { - this->node_collection_.emplace_back(new OperatorNode(oper)); - - if ( place != nullptr ) { - *place = this->node_collection_.back().get(); - } - - return this->node_collection_.back().get(); -} - -std::string Tree::print(std::string term) { - std::stringstream out; - out.precision(std::numeric_limits::digits10); - - out << "digraph \"" << term << "\"" << std::endl - << "{" << std::endl - << "node [shape = box];" << std::endl; - - int i = 0; - - for ( auto it = this->node_collection_.begin(); it != this->node_collection_.end(); ++it ) { - out << "node" << i << " [ label = \"" << (*it)->print() << "\"];" << std::endl; - - if ( (*it)->getType() == OPERATOR_NODE ) { - for ( auto iter = this->node_collection_.begin(); iter != this->node_collection_.end(); ++iter ) { - if ( (*iter).get() == (*it)->leftChild ) { - out << "\"node" << i << "\" -> \"node" << (iter - this->node_collection_.begin()) << "\";" << std::endl; - } - if ( (*iter).get() == (*it)->rightChild ) { - out << "\"node" << i << "\" -> \"node" << (iter - this->node_collection_.begin()) << "\";" << std::endl; - } - } - } - - i++; - } - - out << "}" << std::endl; - - return out.str(); -} - -} diff --git a/src/tree.h b/src/tree.h index 4177098..da611c7 100644 --- a/src/tree.h +++ b/src/tree.h @@ -1,57 +1,13 @@ -#ifndef PARSER_NODE_H_ -#define PARSER_NODE_H_ +#ifndef PARSER_SRC_NODE_H_ +#define PARSER_SRC_NODE_H_ #include #include -#include #include -#include -namespace SimpleParser { - -enum NodeType { - OPERAND_NODE, - OPERATOR_NODE, -}; - -class Node { - public: - virtual ~Node() {}; - - virtual double solve() = 0; - virtual NodeType getType() = 0; - virtual std::string print() = 0; - - Node* leftChild; - Node* rightChild; -}; - -class OperatorNode: public Node { - public: - explicit OperatorNode(char); +#include "nodes.h" - virtual double solve(); - virtual NodeType getType(); - virtual std::string print(); - - char getFunction(); - - private: - char function_; -}; - - -class OperandNode: public Node { - public: - explicit OperandNode(double); - - virtual double solve(); - virtual NodeType getType(); - virtual std::string print(); - - private: - double value_; -}; +namespace SimpleParser { class Tree { public: @@ -68,13 +24,6 @@ class Tree { std::vector> node_collection_; }; -class divide_exception: public std::exception { - virtual const char* what() const throw() - { - return "A divison through zero had to be prevented by the parser - check your input term."; - } -}; - } -#endif // PARSER_NODE_H_ +#endif // PARSER_SRC_NODE_H_ diff --git a/test.cc b/test.cc new file mode 100644 index 0000000..a752ad3 --- /dev/null +++ b/test.cc @@ -0,0 +1,44 @@ +#include "src/parser.h" +#include "gtest/gtest.h" + +class ParserTest : public ::testing::Test { + +}; + +TEST_F(ParserTest, BasicCalc) { + SimpleParser::Parser p; + + EXPECT_EQ(4, p.calculate("2+2")); + EXPECT_EQ(0, p.calculate("2-2")); + EXPECT_EQ(42, p.calculate("21*2")); + EXPECT_EQ(21, p.calculate("42/2")); +} + +TEST_F(ParserTest, OperatorPriority) { + SimpleParser::Parser p; + + EXPECT_EQ(10, p.calculate("2+2*4")); + EXPECT_EQ(4, p.calculate("2+4/2")); + EXPECT_EQ(42, p.calculate("5+10*4-3")); + EXPECT_EQ(17, p.calculate("10+20/2-3")); + EXPECT_EQ(261, p.calculate("5+2^8")); + EXPECT_EQ(32768, p.calculate("2*2^16/4")); + EXPECT_EQ(32772, p.calculate("2*2^16/4+4")); +} + +TEST_F(ParserTest, BracketCalc) { + SimpleParser::Parser p; + + EXPECT_EQ(16, p.calculate("(2+2)*4")); + EXPECT_EQ(10, p.calculate("2+(2*4)")); + EXPECT_EQ(10, p.calculate("(10-5)*(5-3)")); + EXPECT_EQ(4, p.calculate("((((2))*((2))))")); + EXPECT_EQ(37, p.calculate("(((5))*(((((3+2*2)))))+2)")); + EXPECT_EQ(6.25, p.calculate("2.5*(2+3-(3/2+1))")); +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test.cpp b/test.cpp deleted file mode 100644 index a752ad3..0000000 --- a/test.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "src/parser.h" -#include "gtest/gtest.h" - -class ParserTest : public ::testing::Test { - -}; - -TEST_F(ParserTest, BasicCalc) { - SimpleParser::Parser p; - - EXPECT_EQ(4, p.calculate("2+2")); - EXPECT_EQ(0, p.calculate("2-2")); - EXPECT_EQ(42, p.calculate("21*2")); - EXPECT_EQ(21, p.calculate("42/2")); -} - -TEST_F(ParserTest, OperatorPriority) { - SimpleParser::Parser p; - - EXPECT_EQ(10, p.calculate("2+2*4")); - EXPECT_EQ(4, p.calculate("2+4/2")); - EXPECT_EQ(42, p.calculate("5+10*4-3")); - EXPECT_EQ(17, p.calculate("10+20/2-3")); - EXPECT_EQ(261, p.calculate("5+2^8")); - EXPECT_EQ(32768, p.calculate("2*2^16/4")); - EXPECT_EQ(32772, p.calculate("2*2^16/4+4")); -} - -TEST_F(ParserTest, BracketCalc) { - SimpleParser::Parser p; - - EXPECT_EQ(16, p.calculate("(2+2)*4")); - EXPECT_EQ(10, p.calculate("2+(2*4)")); - EXPECT_EQ(10, p.calculate("(10-5)*(5-3)")); - EXPECT_EQ(4, p.calculate("((((2))*((2))))")); - EXPECT_EQ(37, p.calculate("(((5))*(((((3+2*2)))))+2)")); - EXPECT_EQ(6.25, p.calculate("2.5*(2+3-(3/2+1))")); -} - -int main(int argc, char **argv) { - testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} -- cgit v1.2.3