#include<iostream>#include<map>#include<string>#include<cctype>using namespace std;double number_value;string string_value;map<string,double> table;int num_errors;enum Token_value { NAME, NUMBER, END, PLUS='+', MINUS='-', MUL='*', DIV='/', PRINT=';', ASSIGN='=', LP='(', RP=')'};Token_value curr_tok = PRINT;double expr(bool);double term(bool);double prim(bool);double error(const string);Token_value get_token();double expr(bool get) { double left term(get); for(;;) { switch(curr_tok) { case PLUS: left += term(true); break; case MINUS: left -= term(true); break; default: return left; } }}double term(bool get) { double left = prim(get); for(;;) { switch(curr_tok) { case MUL: left *= prim(true); break; case DIV: if (double d = prim(true)) { // Returns value of d, so false if divisor = 0 left /= d; break; } return error("divide by zero... OH SHI--"); default: return left; } }}double prim(bool get) { if (get) get_token(); switch(curr_tok) { case NUMBER: double v = number_value; // Save in case of errors get_token(); return v; case NAME: double& v = table[string_value]; if (get_token() == ASSIGN) v = expr(true); return v; case MINUS: // unary minus, there! return -prim(true); case LP: double e = expr(true); if (curr_tok != RP) return error("')' expected"); get_token(); // be a good girl and swallow ) return e; default: return error("wtf..."); }}Token_value get_token() { char ch = 0; do { //Skip whitespace except \n if (!cin.get(ch)) return curr_tok = END; } while (ch != '\n' && isspace(ch)); switch(ch) { case 0: //EOF return curr_tok = END; case ';': case '\n': return curr_tok = PRINT; case '*': case '/': case '+': case '-': case '(': case ')': case '=': return curr_tok = Token_value(ch); // From the enumeration/symbol table case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0': case '.': cin.putback(ch); //Put it back so we can take it out again.... cin >> number_value; return curr_tok = NUMBER; default: // Assingment, variable or screwup if (isalpha(ch)) { string_value = ch; while (cin.get(ch) && isalnum(ch)) string_value.push_back(ch); cin.putback(ch); return curr_tok = NAME; } error("baaaaad token... spank it!"); return curr_tok = PRINT; }}double error(const string& s) { num_errors++; cerr << "error: " << s << endl; return 1;}int main () { table["pi"] = 3.1415926535897932385; table["e"] = 2.7182818284590452354; while (cin) { get_token(); if (curr_tok == END) break; if (curr_tok == PRINT) continue; // Handle empty statements (when users fail yet again) cout << expr(false) << endl; } return num_errors;}