Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ////////////////////////////////////////////////////////////////////////////////
- // Module Name: stack_machine.h/cpp
- // Authors: Sergey Shershakov
- // Version: 0.2.0
- // Date: 23.01.2017
- //
- // This is a part of the course "Algorithms and Data Structures"
- // provided by the School of Software Engineering of the Faculty
- // of Computer Science at the Higher School of Economics.
- ////////////////////////////////////////////////////////////////////////////////
- #include "stack_machine.h"
- #include <vector>
- #include <sstream>
- #include <vector>
- #include <string>
- #include <iostream>
- #include <stdlib.h>
- namespace xi {
- //==============================================================================
- // Free functions -- helpers
- //==============================================================================
- bool isNumb(const std::string& s)
- {
- size_t offset = 0;
- if (s[offset] == '-' || (s[offset] == '+' && s.length() != 1))
- ++offset;
- return s.find_first_not_of("0123456789", offset) == std::string::npos;
- }
- //==============================================================================
- // class PlusOp
- //==============================================================================
- int PlusOp::operation(char op, int a, int b, int /*c*/) // < just commented unused argument. This does not affect the code anyhow.
- {
- if (op != '+')
- throw std::logic_error("Operation other than Plus (+) are not supported");
- // here we just ignore unused operands
- return a + b;
- }
- IOperation::Arity PlusOp::getArity() const
- {
- return arDue;
- }
- int ChoiceOp::operation(char op, int a, int b, int c)
- {
- if (op != '?')
- throw std::logic_error("Operation other than Choise (?) are not supported");
- if (a != 0)
- return b;
- return c;
- }
- IOperation::Arity ChoiceOp::getArity() const
- {
- return arTre;
- }
- int SigChangeOp::operation(char op, int a, int /*b*/, int /*c*/)
- {
- if (op != '!')
- throw std::logic_error("Operation other than SigChange (!) are not supported");
- return -a;
- }
- IOperation::Arity SigChangeOp::getArity() const
- {
- return arUno;
- }
- int AndOp::operation(char op, int a, int b, int /*c*/)
- {
- if (op != '&')
- throw std::logic_error("Operation other than And (&) are not supported");
- return a & b;
- }
- IOperation::Arity AndOp::getArity() const
- {
- return arDue;
- }
- //==============================================================================
- // class StackMachine
- //==============================================================================
- // types
- typedef std::map<char, IOperation*> SymbolToOperMap;
- typedef SymbolToOperMap::const_iterator SymbolToOperMapConstIter;
- // TODO: put StackMachine methods implementation here
- /** Register an operation object for a given symbol.
- *
- * If the symbol is already registered, throws an exception.
- *
- * !The method implementation should be shred with students!
- */
- void StackMachine::registerOperation(char symb, IOperation* oper)
- {
- SymbolToOperMapConstIter it = _opers.find(symb);
- if (it != _opers.end())
- throw std::logic_error("An operation already registered.");
- _opers[symb] = oper;
- }
- /** For a given symb returns an operation object.
- *
- * If the given symbol is not mapped to any operation, a nullptr is returned.
- */
- IOperation* StackMachine::getOperation(char symb) {
- SymbolToOperMapConstIter it = _opers.find(symb);
- if (it != _opers.end())
- return it->second;
- else
- return nullptr;
- }
- /** Calculates given expression using the shared stack and returns the value on its top.
- *
- * \param clearStack determines if a stack should be clear before parsing the expression.
- * If one prefer not to clear stack before parsing, the results of previous calculations
- * can be used further.
- *
- * \param expr contains a string-based expression contains interger operands and one-symbol operators
- * If an unrecognized symbol (or substring) is found, throws an exception.
- * If given expression is not valid (e.g., in the case of lack of operands or similar),
- * an exception is thrown.
- */
- int StackMachine::calculate(const std::string& expr, bool clearStack)
- {
- if (clearStack)
- _s.clear();
- std::string word = "";
- IOperation* operation;
- int a, b, c;
- IOperation::Arity arity;
- for (int i = 0; i < expr.length(); i++)
- {
- if (expr[i] != ' ')
- word += expr[i];
- if ((expr[i] == ' ' || expr[i + 1] == '\0') && word.length() != 0)
- {
- if (isNumb(word))
- {
- _s.push(stoi(word));
- word = "";
- }
- else if (word.length() == 1)
- {
- char symb = word[0];
- operation = getOperation(symb);
- if (operation == nullptr)
- throw std::logic_error("nullptr");
- arity = operation->getArity();
- switch (arity)
- {
- case 0:
- a = _s.pop();
- _s.push(operation->operation(symb, a));
- break;
- case 1:
- b = _s.pop();
- a = _s.pop();
- _s.push(operation->operation(symb, a, b));
- break;
- case 2:
- c = _s.pop();
- b = _s.pop();
- a = _s.pop();
- _s.push(operation->operation(symb, a, b, c));
- break;
- }
- word = "";
- }
- else if ((expr[i] == ' ' || expr[i + 1] == '\0') && word.length() == 0)
- continue;
- else
- throw std::logic_error("It is not number or operation.");
- }
- }
- return _s.top();
- }
- } // namespace xi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement