https://rentry.org/PPP2_p212

// Code derived from Stroustrup's PPP2 book
// § 6.8.2 Reading tokens
//  -and beginning on p 212

#include <iostream>
#include <stdexcept>
#include <string>

using namespace std;

void error(const char* s) { throw runtime_error(s); }

//------------------------------------------------------------------------------
class Token {
 public:
  Token(char ch) : kind{ch} {}

  Token(char ch, double val) : kind{ch}, value{val} {}

  char   kind  = '0';
  double value = 0.0;
};

//------------------------------------------------------------------------------
class Token_stream {
 public:
  Token_stream();  // make a Token_stream that reads from cin

  Token get();             // get a Token
  void  putback(Token t);  // put a Token back

 private:
  bool  full;    // is there a Token in the buffer?
  Token buffer;  // here is where we keep a Token put back using putback()
};

//------------------------------------------------------------------------------
Token_stream::Token_stream() : full{false}, buffer{0}  // no Token in buffer
{
}

//------------------------------------------------------------------------------
// read a token from cin
Token Token_stream::get()
{
  if (full) {  // check if we already have a Token ready
    full = false;
    return buffer;
  }

  char ch;
  cin >> ch;  // note that >> skips whitespace (space, newline, tab, etc.)

  // clang-format off
  switch (ch) {
    case ';':  // for "print"
    case 'q':  // for "quit"
    case '(': case ')': case '+': case '-': case '*': case '/':
      return Token{ch};  // let each character represent itself
      break;
    default:
      error("Bad token");
      return Token{'K'};  // invalid, shouldn't reach here
  }
  // clang-format on
}

//------------------------------------------------------------------------------
void Token_stream::putback(Token t)
{
  if (full)
    error("putback() into a full buffer");

  buffer = t;     // copy t to buffer
  full   = true;  // buffer is now full
}

//------------------------------------------------------------------------------
int main()
try {
  Token_stream ts;

  Token t{')'};
  ts.putback(t);

  Token u = ts.get();
  if (u.kind != t.kind || u.value != t.value)
    error("Error in token stream logic");

} catch (exception& e) {
  cerr << e.what() << '\n';
  return 1;

} catch (...) {
  cerr << "exception \n";
  return 2;
}

build & run:

g++ -std=c++20 -O2 -Wall -pedantic ./ch_06/main_p212.cpp && ./a.out

PrevUpNext

Edit
Pub: 01 Apr 2023 13:29 UTC
Edit: 02 May 2023 21:26 UTC
Views: 621