All pastes #418758 Raw Edit

Miscellany

public cpp v1 · immutable
#418758 ·published 2007-03-31 20:29 UTC
rendered paste body
#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;}