// based on http://www.stroustrup.com/dc.c // by Bjarne Stroustrup // The desk calculator // pp 107-117, sec 6.1, A Desk calculator // No guarantees offered. Constructive comments to bs@research.att.com /* expr_list: expression PRINT // PRINT is \n expression PRINT expr_list expression: expression + term expression - term term term: term / power term * power power power: power # primary // char '^' produces problems with terminal input primary primary: NUMBER ( expression ) while statt for erweitern um o,i oder HexaDezimal mit &, |, x, */ #include #include #include using namespace std; int no_of_errors; // note: default initialized to 0 bool doPrintCalculations = true; unsigned int error(const char* s) { no_of_errors++; cerr << "error: " << s << '\n'; return 1; } enum Token_value { NUMBER, // '0' ... '9' PLUS='+', MINUS='-', MUL='*', DIV='/', PRINT='\n', POWER='#', LP='(', RP=')' }; Token_value global_token = PRINT; unsigned int number_value; unsigned int asciToInt(string string_value){ unsigned int result = 0; for(size_t i=0; i> number_value; string string_value; string_value = ch; while (cin.get(ch) && isdigit(ch)) string_value += ch; // string_value.push_back(ch); // to work around library bug cin.putback(ch); number_value = asciToInt(string_value); return global_token=NUMBER; } default: error("bad token"); return global_token=PRINT; } } unsigned int expression(); // cannot do without (indirect recursion) unsigned int primary() // handle primaries { Token_value current_token = get_token(); switch (current_token) { case NUMBER:{ unsigned int v = number_value; get_token(); // proceed global_token to next token (i.e. operator or '\n') return v; } case LP:{ unsigned int e = expression(); if (global_token != RP) return error(") expected"); get_token(); // eat ')' in order to proceed global_token to next token return e; } default: return error("primary expected"); } } unsigned int power() // 2 ^ 3 { unsigned int left = primary(); unsigned int right = 0; for (;;) switch (global_token) { case POWER:{ right = primary(); if (doPrintCalculations) printf("%u # %u\n", left, right); unsigned int base = left; left = 1; for (int i=0; i "; cout << expression() << '\n'; } return no_of_errors; }