#include // for access to logic_error #include #include using namespace std; class Expr { public: Expr() = default; virtual ~Expr() = default; virtual double evaluate() const = 0; virtual void print(ostream& os) const = 0; }; class Operand : public Expr { public: Operand(double d) : value{d} {} double evaluate() const { return value; } void print(ostream& os) const { os << value; } private: double value; }; class Operator : public Expr { public: Operator(Expr* l, Expr* r) : Expr(), left{l}, right{r} {} Operator() = default; ~Operator() { delete right; delete left; } virtual double evaluate() const = 0; virtual void print(ostream& os) const { os << '('; left->print(os); os << symbol(); right->print(os); os << ')'; } protected: virtual char symbol() const = 0; Expr* left; Expr* right; }; class Plus : public Operator { public: Plus(Expr* l, Expr* r) : Operator(l, r) {} ~Plus() = default; double evaluate() const { return left->evaluate() + right->evaluate(); } protected: virtual char symbol() const { return '+'; }; }; class Mult : public Operator { public: Mult(Expr* l, Expr* r) : Operator(l, r) {} ~Mult() = default; double evaluate() const { return left->evaluate() * right->evaluate(); } protected: virtual char symbol() const { return '*'; }; }; Expr* top_and_pop(stack& s) { if ( s.empty() ) throw logic_error{"Too few operands"}; Expr* e{ s.top() }; s.pop(); return e; } int main() { stack exprs; string input; while ( cin >> input ) { switch( input.at(0) ) { case '+': { Expr* right{ top_and_pop( exprs ) }; Expr* left{ top_and_pop( exprs ) }; exprs.push( new Plus{left, right} ); } break; case '*': { Expr* right{ top_and_pop( exprs ) }; Expr* left{ top_and_pop( exprs ) }; exprs.push( new Mult{left, right} ); } break; default: { exprs.push( new Operand{ stod(input) } ); } break; } } Expr* e{ exprs.top() }; e->print( cout ); cout << endl << "Answer: " << e->evaluate() << endl; while ( ! exprs.empty() ) { delete top_and_pop( exprs ); } return 0; }