From 39038fddb2032c9944e549be8f1665e028cb68b8 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Sat, 5 Jan 2013 23:06:51 +0100 Subject: Deprecated parser class in favour of plain functions; Internal lexer, priority determination and tree building functions were hidden in unnamed namespace --- Makefile | 14 +++++++++----- main.cc | 6 ++---- src/nodes.cc | 2 +- src/parser.cc | 34 ++++++++++++++++++---------------- src/parser.h | 16 +++++++--------- src/tree.cc | 2 +- test.cc | 40 +++++++++++++++++----------------------- 7 files changed, 55 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index 6db0c9b..4fd4faf 100644 --- a/Makefile +++ b/Makefile @@ -2,14 +2,18 @@ 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 +FLAGS = -std=c++11 -W -Wall -Wextra -pedantic +PARSER = -o bin/parser $(FLAGS) $(PROG_FILES) $(LIB_FILES) -all: parser test +all: dev test -parser: $(PROG_FILES) $(LIB_FILES) - g++ -g -o bin/parser $(FLAGS) $(PROG_FILES) $(LIB_FILES) +dev: $(PROG_FILES) $(LIB_FILES) + g++ -g $(PARSER) + +release: $(PROG_FILES) $(LIB_FILES) + g++ -O3 $(PARSER) test: $(LIB_FILES) $(TEST_FILES) - g++ -O3 -o bin/test -lgtest $(FLAGS) $(LIB_FILES) $(TEST_FILES) + g++ -O3 -o bin/test -lgtest $(TEST_FILES) $(FLAGS) $(LIB_FILES) ./bin/test diff --git a/main.cc b/main.cc index c03cce2..3378e14 100644 --- a/main.cc +++ b/main.cc @@ -7,15 +7,13 @@ int main() { std::string inputTerm; - std::cin >> inputTerm; // Example: 2.5*(2+3-(3/2+1)) - - SimpleParser::Parser parser; + std::cin >> inputTerm; try { typedef std::numeric_limits dbl; std::cout.precision(dbl::digits10); - std::cout << parser.calculate(inputTerm) << std::endl; + std::cout << SimpleParser::calculate(inputTerm) << std::endl; } catch ( std::exception &e ) { diff --git a/src/nodes.cc b/src/nodes.cc index 70b9e50..2ec3167 100644 --- a/src/nodes.cc +++ b/src/nodes.cc @@ -74,4 +74,4 @@ char OperatorNode::getFunction() { return this->function_; } -} +} // SimpleParser diff --git a/src/parser.cc b/src/parser.cc index 0f05790..5989027 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -5,8 +5,16 @@ namespace SimpleParser { -int8_t Parser::getPriority(char tmp) -{ +double calculate(std::string term) { + Tree termTree; + termTree.setRoot(buildTree(&termTree, term)); + + return termTree.solve(); +} + +namespace { + +int8_t getPriority(char tmp) { switch ( tmp ) { case '-': return 10; @@ -29,8 +37,7 @@ int8_t Parser::getPriority(char tmp) } } -std::vector Parser::lexer(std::string term) -{ +std::vector lexer(std::string term) { std::string tmp; std::string tmpNum; std::string::iterator termIter; @@ -41,7 +48,7 @@ std::vector Parser::lexer(std::string term) uint32_t level = 0; for ( termIter = term.begin(); termIter != term.end(); termIter++ ) { - priority = this->getPriority(*termIter); + priority = getPriority(*termIter); if ( priority == -1 || ( termIter == term.begin() && priority == 10 ) ) { if ( level > 0 ) { @@ -111,24 +118,24 @@ std::vector Parser::lexer(std::string term) return output; } -Node* Parser::buildTree(Tree *tree, std::string term) { +Node* buildTree(Tree *tree, std::string term) { std::stack operandStack; std::stack operatorStack; std::vector tmpLexer; - std::vector lexerOutput = this->lexer(term); + std::vector lexerOutput = lexer(term); int8_t priority; for ( auto termIter = lexerOutput.begin(); termIter != lexerOutput.end(); termIter++ ) { std::string& currTerm = (*termIter); - priority = this->getPriority(currTerm[0]); + priority = getPriority(currTerm[0]); if ( priority != -1 && (*termIter).size() == 1 ) { if ( !operatorStack.empty() ) { OperatorNode *lastNode = static_cast(operatorStack.top()); - if ( this->getPriority(lastNode->getFunction()) < priority ) { + if ( getPriority(lastNode->getFunction()) < priority ) { operatorStack.push( tree->addOperator(nullptr, currTerm[0]) ); @@ -150,7 +157,7 @@ Node* Parser::buildTree(Tree *tree, std::string term) { operatorStack.push(tree->addOperator(nullptr, currTerm[0])); } } else { - tmpLexer = this->lexer(*termIter); + tmpLexer = lexer(*termIter); if ( tmpLexer.size() == 1 ) { double value; @@ -181,11 +188,6 @@ Node* Parser::buildTree(Tree *tree, std::string term) { return operandStack.top(); } -double Parser::calculate(std::string term) { - Tree termTree; - termTree.setRoot(this->buildTree(&termTree, term)); - - return termTree.solve(); } -} +} // SimpleParser diff --git a/src/parser.h b/src/parser.h index b943ebe..7e594ca 100644 --- a/src/parser.h +++ b/src/parser.h @@ -8,15 +8,13 @@ namespace SimpleParser { -class Parser { - public: - double calculate(std::string); - - private: - int8_t getPriority(char); - std::vector lexer(std::string); - Node* buildTree(Tree*, std::string); -}; +double calculate(std::string); + +namespace { + int8_t getPriority(char); + std::vector lexer(std::string); + Node* buildTree(Tree*, std::string); +} } diff --git a/src/tree.cc b/src/tree.cc index 675009e..3755423 100644 --- a/src/tree.cc +++ b/src/tree.cc @@ -66,4 +66,4 @@ std::string Tree::print(std::string term) { return out.str(); } -} +} // SimpleParser diff --git a/test.cc b/test.cc index a752ad3..0b6f36b 100644 --- a/test.cc +++ b/test.cc @@ -6,35 +6,29 @@ 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")); + EXPECT_EQ(4, SimpleParser::calculate("2+2")); + EXPECT_EQ(0, SimpleParser::calculate("2-2")); + EXPECT_EQ(42, SimpleParser::calculate("21*2")); + EXPECT_EQ(21, SimpleParser::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")); + EXPECT_EQ(10, SimpleParser::calculate("2+2*4")); + EXPECT_EQ(4, SimpleParser::calculate("2+4/2")); + EXPECT_EQ(42, SimpleParser::calculate("5+10*4-3")); + EXPECT_EQ(17, SimpleParser::calculate("10+20/2-3")); + EXPECT_EQ(261, SimpleParser::calculate("5+2^8")); + EXPECT_EQ(32768, SimpleParser::calculate("2*2^16/4")); + EXPECT_EQ(32772, SimpleParser::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))")); + EXPECT_EQ(16, SimpleParser::calculate("(2+2)*4")); + EXPECT_EQ(10, SimpleParser::calculate("2+(2*4)")); + EXPECT_EQ(10, SimpleParser::calculate("(10-5)*(5-3)")); + EXPECT_EQ(4, SimpleParser::calculate("((((2))*((2))))")); + EXPECT_EQ(37, SimpleParser::calculate("(((5))*(((((3+2*2)))))+2)")); + EXPECT_EQ(6.25, SimpleParser::calculate("2.5*(2+3-(3/2+1))")); } int main(int argc, char **argv) { -- cgit v1.2.3