Restructuring
authorNilsForssen <forssennils@gmail.com>
Mon, 9 Oct 2023 09:34:42 +0000 (11:34 +0200)
committerNilsForssen <forssennils@gmail.com>
Mon, 9 Oct 2023 09:34:42 +0000 (11:34 +0200)
.gitignore
postfix.cc [deleted file]
postfix.h [deleted file]
token.cc [deleted file]
token.h [deleted file]
token_test.cc [deleted file]
uppgift13.cc [deleted file]

index 7db1089fdadc9dc9d897f97dcb6280c1b9bc1442..64025642b5ad13612340291d314726c7874c11b0 100644 (file)
@@ -1,2 +1,3 @@
 *.txt
-a.out
\ No newline at end of file
+a.out
+*.o
\ No newline at end of file
diff --git a/postfix.cc b/postfix.cc
deleted file mode 100644 (file)
index a51f184..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-#include "postfix.h"
-#include "token.h"
-
-#include <string>
-#include <vector>
-#include <stack>
-#include <map>
-#include <istream>
-
-#include <sstream>
-#include <algorithm>
-#include <iterator>
-
-// PUBLIC
-
-Postfix::Postfix(std::string const& infix_string) : expr{}
-{
-  std::istringstream is{infix_string};
-  expr = make_postfix(is);
-}
-    
-std::string Postfix::to_string() const
-{
-  std::ostringstream os;
-  std::copy( std::begin(expr), std::end(expr),
-             std::ostream_iterator<std::string>{os, " "});
-  return os.str();
-}
-
-Postfix::operator std::string() const
-{
-  return to_string();
-}
-
-bool Postfix::operator==(std::string const& rhs) const
-{
-  return to_string() == rhs;
-}
-
-
-// PRIVATE
-
-// right associative operators have input priority > stack priority  
-// left associative operators have input priority < stack priority
-const Postfix::priority_table Postfix::operator_table {
-  // {symbol, input prio, stack prio}
-  {"^", {8, 7}},
-  {"*", {5, 6}},
-  {"/", {5, 6}},
-  {"%", {5, 6}},
-  {"+", {3, 4}},
-  {"-", {3, 4}},
-  {"=", {2, 1}}
-};
-
-bool Postfix::is_operator(const std::string& token)
-{
-  // C++20: return operator_table.contains( token );
-  return ( operator_table.count( token ) > 0 );
-}
-
-Postfix::expression Postfix::make_postfix(std::istream& is, bool match_parenthesis) const
-{
-  using namespace std::literals; // for string literals ""s
-  
-  op_stack operator_stack;
-  expression postfix;
-  Token token;
-  int unused_operands{0};
-
-  while (is >> token && token != ")"s )
-  {
-    if ( is_operator(token) )
-    {
-      while ( ! operator_stack.empty() && 
-              operator_table.at(token).input <=
-              operator_table.at(operator_stack.top()).stack )
-      {
-        postfix.push_back( operator_stack.top() );
-        unused_operands -= 1; // uses 2 but creates 1
-        operator_stack.pop();
-      }
-      operator_stack.push(token);
-    }
-    else if (token == "("s)
-    {
-      expression parentesis{ make_postfix(is, true) };
-      std::copy( std::begin(parentesis), std::end(parentesis), std::back_inserter(postfix) );
-      unused_operands += 1; // entire postix is 1 operand
-    }
-    else
-    {
-      postfix.push_back( token );
-      unused_operands += 1;
-    }
-  }
-
-  if ( postfix.empty() && match_parenthesis && token == ")"s )
-  {
-    throw Infix_Error{"Empty parenthesis"};
-  }
-
-  if ( match_parenthesis && token != ")"s )
-  {
-    throw Infix_Error{"Missing ending parenthesis"};
-  }
-    
-  if ( ! match_parenthesis && token == ")"s )
-  {
-    throw Infix_Error{"Missing starting parenthesis"};
-  }
-    
-  while ( ! operator_stack.empty() )
-  {
-    postfix.push_back( operator_stack.top() );
-    unused_operands -= 1; // uses 2 but creates 1
-    operator_stack.pop();
-  }
-
-  if ( unused_operands != 1 ) // the last one is the answer
-  {
-    if ( unused_operands > 1 )
-      throw Infix_Error{"Missing operator"};
-    else
-      throw Infix_Error{"Missing operand"};
-  }
-    
-  return postfix;
-}
diff --git a/postfix.h b/postfix.h
deleted file mode 100644 (file)
index 3d3a69c..0000000
--- a/postfix.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef POSTFIX_H
-#define POSTFIX_H
-
-#include <string>
-#include <vector>
-#include <stack>
-#include <map>
-#include <istream>
-#include <stdexcept>
-
-class Infix_Error : public std::logic_error
-{
-    using std::logic_error::logic_error;
-};
-
-// Creates a Postfix from a given infix string. All operands and
-// operators are required to be separated by at least one space.
-class Postfix
-{
-public:
-  Postfix(std::string const& infix_string);
-    
-  std::string to_string() const;
-  operator std::string() const;
-  bool operator==(std::string const& rhs) const;
-  
-private:
-  using op_stack = std::stack<std::string>;
-  using expression = std::vector<std::string>;
-  
-  expression expr;
-  
-  struct priority
-  {
-    int input;
-    int stack;
-  };
-  
-  using priority_table = std::map<std::string, Postfix::priority>;
-  static const priority_table operator_table;
-
-  static bool is_operator(const std::string& token);
-  
-  expression make_postfix(std::istream& is, bool match_parenthesis = false) const;
-};
-
-#endif
diff --git a/token.cc b/token.cc
deleted file mode 100644 (file)
index 65db2cd..0000000
--- a/token.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-#include <iostream>
-#include <iomanip>
-#include <string>
-#include <set>
-#include <algorithm>
-#include <cctype>
-
-#include "token.h"
-
-using namespace std;
-
-// Public
-
-set<string> const Token::default_operators{
-  "+", "-", "*", "/", "%", "^", "=", "(", ")", "?", "£", "$"
-    };
-
-string const Token::default_separators{" \t\n\r"};
-
-Token::Token(set<string> const& ops, string const& sep)
-  : operators{ops}, separators{sep}, token{}
-{
-}
-
-istream& operator>>(istream& iss, Token& t)
-{
-  return t.next(iss);
-}
-
-ostream& operator<<(ostream& oss, Token const& t)
-{
-  return oss << t.token;
-}
-
-bool Token::is_operator() const
-{
-  return operators.count( token ) == 1;
-}
-
-bool Token::is_integer() const
-{
-  return all_of(token.begin(), token.end(), ::isdigit);
-}
-
-bool Token::is_decimal() const
-{
-  bool valid_chars = all_of(token.begin(), token.end(), [](char c)->bool
-                            {
-                              return c == '.' || isdigit(c);
-                            });
-  bool one_dot = count(token.begin(), token.end(), '.') == 1;
-  return valid_chars && one_dot;
-}
-
-bool Token::is_identifier() const
-{
-  return all_of(token.begin(), token.end(), [](char c)->bool
-                {
-                  return c == '_' || isalnum(c);
-                });
-}
-
-// Private
-
-bool Token::is_separator(int c) const
-{
-  return ( separators.find(c) != string::npos );
-}
-
-bool Token::is_delimeter(int c) const
-{
-  if ( c == -1 ) // Traits::eof()
-    return true;
-  
-  if ( is_separator( c ) )
-    return true;
-  
-  auto b{ operators.begin() };
-  auto e{ operators.end() };
-  
-  for ( ; b != e; ++b )
-  {
-    if ( b->at(0) == c )
-      return true;
-  }
-  return false;
-}
-
-bool Token::is_candidate() const
-{
-  auto b{ operators.begin() };
-  auto e{ operators.end() };
-
-  for ( ; b != e; ++b )
-  {
-    if ( b->find( token ) == 0 && *b != token )
-      return true;
-  }
-  return false;
-}
-
-void Token::append(int c)
-{
-  token.push_back( static_cast<char>(c) );
-}
-
-void Token::ignore_separators(istream& iss)
-{
-  auto c{ iss.peek() };
-
-  while ( c != -1 ) // Traits::eof()
-  {
-    if ( ! is_separator( c ) )
-      return;
-    
-    iss.get();
-    c = iss.peek();
-  }
-}
-
-istream& Token::next(istream& iss)
-{
-  token.clear();
-
-  ignore_separators( iss );
-  
-  auto c{ iss.peek() };
-
-  bool prev_is_op{false};
-  
-  while ( c != -1 ) // Traits::eof()
-  {
-    append( c );
-
-    bool is_op{ is_operator() };
-    bool is_can{ is_candidate() };
-    bool is_del{ is_delimeter(c) };
-    
-    if ( is_op && ! is_can )
-    {
-      iss.get();
-      return iss;
-    }
-
-    if ( prev_is_op && ! is_op && ! is_can )
-    {
-      token.pop_back();
-      return iss;
-    }
-    
-    if ( is_del && ! is_can )
-    {
-      token.pop_back();
-      return iss;
-    }
-
-    prev_is_op = is_op;
-    iss.get();
-    c = iss.peek();
-  }
-  
-  return iss;
-}
diff --git a/token.h b/token.h
deleted file mode 100644 (file)
index 35bfd0e..0000000
--- a/token.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef TOKEN_H
-#define TOKEN_H
-
-#include <iostream>
-#include <string>
-#include <set>
-
-// A class to read strings from an istream just like std::string,
-// but tokens are separated not only by space, but also by operators.
-//
-// You should be able to just change from "std::string" to "Token" in
-// your program unless you do something special with your strings.
-//
-// Tokens can be classified as integers, deciamls, identifiers or operators.
-//
-class Token
-{
-public:
-
-  // interoperability with standard library (STL)
-  using token_t = std::string;
-  
-  using value_type = token_t::value_type;
-  using size_type = token_t::size_type;
-  using pointer = token_t::pointer;
-  using reference = token_t::reference;
-  using iterator = token_t::const_iterator;
-
-  iterator begin() const { return token.begin(); }
-  iterator end() const { return token.end(); }
-  size_type size() const { return token.size(); }
-  size_type length() const { return token.length(); }
-  value_type at(int i) const { return token.at(i); }
-
-  // static constants for default values
-  static std::set<std::string> const default_operators;
-  static std::string const default_separators;
-
-  // public members
-  Token(std::set<std::string> const& operators = default_operators,
-        std::string const& separators = default_separators);
-
-  friend std::istream& operator>>(std::istream& iss, Token& t);
-  
-  friend std::ostream& operator<<(std::ostream& oss, Token const& t);
-
-  operator std::string() const { return token; }
-
-  bool operator==(std::string const& rhs) { return token == rhs; }
-  bool operator!=(std::string const& rhs) { return token != rhs; }
-  
-  bool is_operator() const;
-  bool is_integer() const;
-  bool is_decimal() const;
-  bool is_identifier() const;
-  
-private:
-
-  // help functions
-  bool is_delimeter(int c) const;
-  bool is_separator(int c) const;
-
-  bool is_candidate() const;
-
-  void append(int c);
-  void ignore_separators(std::istream& iss);
-  
-  std::istream& next(std::istream& iss);
-
-  // data members
-  std::set<std::string> const& operators;
-  std::string const& separators;
-  std::string token;
-
-  friend class Token_Private_Tester;
-};
-
-#endif
diff --git a/token_test.cc b/token_test.cc
deleted file mode 100644 (file)
index 39cc98e..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-#define CATCH_CONFIG_RUNNER
-#include "catch.hpp"
-
-#include <iostream>
-#include <sstream>
-
-#include "token.h"
-
-using namespace std;
-
-const std::set<std::string> my_operators{
-  "+", "+-+", "-", "*", "/", "%", "^", "=", "==", "(", ")", "?", "£", "$", "####"
-    };
-
-class Token_Private_Tester
-{
-public:
-  Token_Private_Tester(Token& t) : t{t} {}
-  
-  bool is_delimeter(int c) const { return t.is_delimeter(c); }
-  bool is_separator(int c) const { return t.is_separator(c); }
-
-  bool is_candidate() const { return t.is_candidate(); }
-
-  bool check_candidate(string const& s) { t.token = s; return t.is_candidate(); }
-
-  Token& set(string const& s) { t.token = s; return t; }
-  
-private:
-  Token& t;
-};
-
-TEST_CASE("help functions")
-{
-  Token tok{my_operators};
-  Token_Private_Tester t{tok};
-
-  CHECK( t.is_delimeter('+') );
-  CHECK( t.is_delimeter('#') );
-  CHECK( t.is_delimeter(' ') );
-  CHECK_FALSE( t.is_delimeter('.') );
-  
-  CHECK( t.is_separator(' ') );
-  CHECK_FALSE( t.is_separator('0') );
-  
-  CHECK(       t.check_candidate("+") );
-  CHECK(       t.check_candidate("+-") );
-  CHECK_FALSE( t.check_candidate("+-+") );
-  CHECK_FALSE( t.check_candidate("+-++") );
-
-}
-
-TEST_CASE("classifier functions")
-{
-  Token tok{my_operators};
-  Token_Private_Tester t{tok};
-  
-  CHECK( t.set("+").is_operator() );
-  CHECK_FALSE( t.set("+-").is_operator() );
-  CHECK( t.set("+-+").is_operator() );
-  CHECK_FALSE( t.set("+-++").is_operator() );
-  
-  CHECK( t.set("123").is_integer() );
-  CHECK( t.set("3.14").is_decimal() );
-  CHECK( t.set("x_34").is_identifier() );
-
-  CHECK_FALSE( t.set("123a").is_integer() );
-  CHECK_FALSE( t.set("3.14.").is_decimal() );
-  CHECK_FALSE( t.set("=x_34").is_identifier() );
-}
-
-TEST_CASE("normal input output")
-{
-  Token t{my_operators};
-  istringstream iss{"1+2*34-sfd"};
-  ostringstream oss{};
-  
-  while ( iss >> t )
-  {
-    oss << t << " ";
-  }
-  CHECK( oss.str() == "1 + 2 * 34 - sfd ");
-}
-
-TEST_CASE("normal input output, default operators")
-{
-  Token t;
-  istringstream iss{"1+2*34-sfd"};
-  ostringstream oss{};
-  
-  while ( iss >> t )
-  {
-    oss << t << " ";
-  }
-  CHECK( oss.str() == "1 + 2 * 34 - sfd ");
-}
-
-TEST_CASE("multichar operator input output")
-{
-  Token t{my_operators};
-  istringstream iss{"1+-++2===as#####fgh"};
-  ostringstream oss{};
-  
-  while ( iss >> t )
-  {
-    oss << t << " ";
-  }
-  CHECK( oss.str() == "1 +-+ + 2 == = as #### #fgh ");
-}
-
-int main(int argc, char* argv[] __attribute__((unused)))
-{
-  Catch::Session session;
-
-  session.run();
-
-   
-  Token t{my_operators};
-  string s;
-
-  if ( argc <= 1 )
-    return 0;
-  
-  cout << "Manual test mode, press Ctrl-D to exit. "
-       << "Please enter lines to split: " << endl;
-  while ( getline(cin, s) )
-  {
-    istringstream iss{s};
-    
-    while ( iss >> t )
-    {
-      if ( t.is_operator() )
-        cout << "op: '" << t << "', ";
-      else if ( t.is_integer() )
-        cout << "int: '" << t << "', ";
-      else if ( t.is_decimal() )
-        cout << "double: '" << t << "', ";
-      else if ( t.is_identifier() )
-        cout << "var: '" << t << "', ";
-      else
-        cout << "token: '" << t << "', ";
-    }
-    cout << endl;
-  }
-  return 0;
-}
diff --git a/uppgift13.cc b/uppgift13.cc
deleted file mode 100644 (file)
index fb82a08..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <iostream>
-
-using namespace std;
-
-int main()
-{
-  string line;
-  while ( getline(cin, line) )
-  {
-    Expression e{line};
-    cout << e.to_string() << endl
-         << e.evaluate() << endl;
-  }
-  return 0;
-}