// Code derived from Stroustrup's PPP2 book// § 6.8.2 Reading tokens// -and beginning on p 212#include<iostream>#include<stdexcept>#include<string>usingnamespacestd;voiderror(constchar*s){throwruntime_error(s);}//------------------------------------------------------------------------------classToken{public:Token(charch):kind{ch}{}Token(charch,doubleval):kind{ch},value{val}{}charkind='0';doublevalue=0.0;};//------------------------------------------------------------------------------classToken_stream{public:Token_stream();// make a Token_stream that reads from cinTokenget();// get a Tokenvoidputback(Tokent);// put a Token backprivate:boolfull;// is there a Token in the buffer?Tokenbuffer;// 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 cinTokenToken_stream::get(){if(full){// check if we already have a Token readyfull=false;returnbuffer;}charch;cin>>ch;// note that >> skips whitespace (space, newline, tab, etc.)// clang-format offswitch(ch){case';':// for "print"case'q':// for "quit"case'(':case')':case'+':case'-':case'*':case'/':returnToken{ch};// let each character represent itselfbreak;default:error("Bad token");returnToken{'K'};// invalid, shouldn't reach here}// clang-format on}//------------------------------------------------------------------------------voidToken_stream::putback(Tokent){if(full)error("putback() into a full buffer");buffer=t;// copy t to bufferfull=true;// buffer is now full}//------------------------------------------------------------------------------intmain()try{Token_streamts;Tokent{')'};ts.putback(t);Tokenu=ts.get();if(u.kind!=t.kind||u.value!=t.value)error("Error in token stream logic");}catch(exception&e){cerr<<e.what()<<'\n';return1;}catch(...){cerr<<"exception \n";return2;}