/* Simple calculator This program implements a basic expression calculator. input from cin; output to cout. The grammer for input is: Statement: Expression Print Quit Print: ';' Quit: 'q' Expression: Term Expression "+" Term Expression "-" Term Term: Primary Term "*" Primary Term "/" Primary Term "%" Primary Primary: Number "(" Expression ")" "-" Primary "+" Primary Number: floating-point-literal */ #include #include //Define the symbolic names: const char number='8'; const char quit='q'; const char print=';'; const std::string prompt="> "; const std::string result="= "; //--------------------------------------------------------- class Token { public: char kind; double value; Token(char ch) :kind(ch), value(0){} Token(char ch, double val) :kind(ch), value(val){} }; class Token_stream { public: Token_stream(); Token get(); void putback(Token t); void ignore(char c); private: bool full; Token buffer; }; Token_stream::Token_stream() :full(false), buffer(0){} void Token_stream::putback(Token t) { if(full) throw std::runtime_error("putback() into a full buffer"); buffer=t; full=true; } Token Token_stream::get() { if (full) { full=false; return buffer; } char ch; std::cin>>ch; switch(ch) { case quit: case print: case '(': case ')': case '+': case '-': case '*': case '/': case '%': return Token(ch); case'.': case'0': case'1': case'2': case'3': case'4': case'5': case'6': case'7': case'8': case'9': { std::cin.putback(ch); double val; std::cin>>val; return Token(number, val); } default: throw std::runtime_error("Bad Token"); } } void Token_stream::ignore(char c) { if(full && c==buffer.kind) { full=false; return; } full=false; //now search input: char ch=0; while(std::cin>>ch) if(ch==c) return; } //--------------------------------------------------------- Token_stream ts; double primary(); double term(); double expression(); void calculate(); void clean_up_mess(); int main() try { calculate(); return 0; } catch (std::exception& e) { std::cerr<