Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 6 Try This Page 204
Using std_lib_facilities.h by Bjarne Stroustrup.
// Philipp Siedler // Bjarne Stroustrup's PP // Chapter 6 Try This Page 204 #include "std_lib_facilities.h" class Token { public: char kind; // what kind of token double value; // for numbers: a value Token(char ch) // make a Token from a char :kind(ch), value(0) { } Token(char ch, double val) // make a Token from a char and a double :kind(ch), value(val) { } }; Token get_token() // read a token from cin { char ch; cin >> ch; // note that >> skips whitespace (space, newline, tab, etc.) switch (ch) { //not yet case ';': // for "print" //not yet case 'q': // for "quit" case '(': case ')': case '+': case '-': case '*': case '/': return Token(ch); // let each character represent itself case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { cin.putback(ch); // put digit back into the input stream double val; cin >> val; // read a floating-point number return Token('8', val); // let '8' represent "a number" } default: error("Bad token"); } } double expression(); // read and evaluate a Expression double term(); // read and evaluate a Term double primary() // read and evaluate a Primary { Token t = get_token(); switch (t.kind) { case '(': // handle '(' expression ')' { double d = expression(); t = get_token(); if (t.kind != ')') error("')' expected"); return d; } case '8': // we use '8' to represent a number return t.value; // return the number's value default: error("primary expected"); } } int main() try { while (cin) cout << "=" << expression() << '\n'; keep_window_open("~0"); } catch (exception& e) { cerr << e.what() << endl; keep_window_open("~1"); return 1; } catch (...) { cerr << "exception \n"; keep_window_open("~2"); return 2; } double expression() { double left = term(); // read and evaluate a Term Token t = get_token(); // get the next token while (true) { switch (t.kind) { case '+': left += term(); // evaluate Term and add t = get_token(); break; case '-': left -= term(); // evaluate Term and subtract t = get_token(); break; default: return left; // finally: no more + or -: return the answer } } } double term() { double left = primary(); Token t = get_token(); // get the next token while (true) { switch (t.kind) { case '*': left *= primary(); t = get_token(); break; case '/': { double d = primary(); if (d == 0) error("divide by zero"); left /= d; t = get_token(); break; } default: return left; } } }
Output: 4+8 =4