From 0b29d1a9b4629570ed54f0f64247b771e1414bbe Mon Sep 17 00:00:00 2001 From: NilsForssen Date: Mon, 9 Oct 2023 11:33:46 +0200 Subject: [PATCH] Implemented expression tree --- src/expression.cc | 99 +++++++++++++++++++++++++++++++++++++++++++++++ src/expression.h | 57 +++++++++++++++++++-------- src/node.h | 20 ++++++++++ src/operands.h | 2 +- src/operators.h | 4 +- 5 files changed, 163 insertions(+), 19 deletions(-) create mode 100644 src/node.h diff --git a/src/expression.cc b/src/expression.cc index e69de29..36e3a25 100644 --- a/src/expression.cc +++ b/src/expression.cc @@ -0,0 +1,99 @@ +#include "expression.h" + +Expression::Expression(const std::string & expression) +: expression_root{nullptr} +{ + std::string post_string{Postfix{expression}.to_string()}; + + std::stringstream iss{post_string}; + + Token token{}; + std::stack stack{}; + Node * new_node{nullptr}; + + while (iss >> token) + { + std::cout << token << std::endl; + + if (token.is_integer()) + { + new_node = new Const_int{std::stoi(token)}; + } + else if (token.is_decimal()) + { + new_node = new Const_double{std::stod(token)}; + } + else if ( isalpha(token.at(0))) + { + throw std::logic_error("Variables are not implemented"); + } + else if (token.is_operator()) + { + Node * lhs{stack.top()}; + stack.pop(); + Node * rhs{stack.top()}; + stack.pop(); + + if (lhs == nullptr || rhs == nullptr) + { + throw std::logic_error("Missing operands"); + } + + switch (operator_string_map[token]) + { + case ADDITION: + new_node = new Addition{*lhs, *rhs}; + break; + case SUBTRACTION: + new_node = new Subtraction{*lhs, *rhs}; + break; + case DIVISION: + new_node = new Division{*lhs, *rhs}; + break; + case MULTIPLICATION: + new_node = new Multiplication{*lhs, *rhs}; + break; + case EXPONENT: + new_node = new Exponent{*lhs, *rhs}; + break; + default: + throw std::logic_error("Operator not implemented"); + break; + } + } + else + { + throw std::logic_error("Undefined characters in expression"); + } + stack.push(new_node); + } + if (stack.size() == 0) + { + throw std::logic_error("Empty expression"); + } + if (stack.size() > 1) + { + throw std::logic_error("Missing operators"); + } + + expression_root = stack.top(); +} + +std::string Expression::to_string(StringFormat s_format) const +{ + switch(s_format) + { + case PREFIX: + return expression_root->get_prefix(); + case POSTFIX: + return expression_root->get_postfix(); + case INFIX: + default: + return expression_root->get_infix(); + } +} + +double Expression::evaluate() const +{ + return expression_root->get_value(); +} \ No newline at end of file diff --git a/src/expression.h b/src/expression.h index d1d1a99..0ddab71 100644 --- a/src/expression.h +++ b/src/expression.h @@ -2,29 +2,54 @@ #define EXPRESSION_H #include - -class Equation { +#include + +#include "postfix.h" +#include "token.h" +#include "operators.h" +#include "operands.h" + +#include // TA bort +#include +#include +#include + +typedef enum +{ + PREFIX, + POSTFIX, + INFIX +} StringFormat; + +typedef enum +{ + ADDITION, + SUBTRACTION, + MULTIPLICATION, + DIVISION, + EXPONENT +} Operator_types; + +std::map operator_string_map; + +class Expression +{ public: -protected: -private: -}; + Expression(const std::string & expression); -class Node { -public: - virtual ~Node() = default; + Expression(Expression const&) = delete; + Expression& operator=(Expression const&) = delete; - virtual double get_value() const = 0; - virtual std::string get_postfix() const = 0; - virtual std::string get_infix() const = 0; - virtual std::string get_prefix() const = 0; + std::string to_string(StringFormat s_format=INFIX) const; + double evaluate() const; -private: protected: +private: + Node *expression_root; }; -class Result { +class Result +{ }; - - #endif \ No newline at end of file diff --git a/src/node.h b/src/node.h new file mode 100644 index 0000000..d94663a --- /dev/null +++ b/src/node.h @@ -0,0 +1,20 @@ +#ifndef NODE_H +#define NODE_H + +#include + +class Node +{ +public: + virtual ~Node() = default; + + virtual double get_value() const = 0; + virtual std::string get_postfix() const = 0; + virtual std::string get_infix() const = 0; + virtual std::string get_prefix() const = 0; + +private: +protected: +}; + +#endif \ No newline at end of file diff --git a/src/operands.h b/src/operands.h index fd43bd0..04769fe 100644 --- a/src/operands.h +++ b/src/operands.h @@ -5,7 +5,7 @@ #include #include -#include "expression.h" +#include "node.h" class Operand : public Node { diff --git a/src/operators.h b/src/operators.h index 2730c3f..5023a39 100644 --- a/src/operators.h +++ b/src/operators.h @@ -6,7 +6,7 @@ #include #include -#include "expression.h" +#include "node.h" class Operator : public Node { @@ -17,7 +17,7 @@ public: Operator & operator=(Operator const &) = delete; virtual ~Operator() = default; - + std::string get_symbol() const; std::string get_postfix() const override; std::string get_infix() const override; -- 2.30.2