《C++程序设计语言》6.6_18 计算机的例子

来源:互联网 发布:免费外汇行情软件 编辑:程序博客网 时间:2024/05/19 22:57
/*------------------------------------------------键入计算机的例子并使之能够工作. 不要"浪费时间"去使用已有的正文文件. 你将会从发现并改正各种 "小而蠢的错误" 中学到许多东西.------------------------------------------------*/#include <iostream>#include <sstream>// include istringstream#include <string>#include <map>#include <cctype>using std::cout;using std::cin;using std::endl;using std::cerr;using std::string;using std::map;using std::istream;using std::istringstream;double expr(bool get);double term(bool get);double prim(bool get);double error(const string& s);enum Token_value get_token();map<string, double> table;enum Token_value{NAME,NUMBER,END,PLUS = '+',MINUS = '-',MUL = '*',DIV = '/',PRINT = ';',ASSIGN = '=',LP = '(',RP = ')'};Token_value curr_tok = PRINT;// 函数expr()处理加和减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;}}// 函数term()处理乘和除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)){left /= d;break;}return error("divide by 0");default:return left;}}// 函数prim()处理初等式double number_value;string string_value;double prim(bool get){if (get)get_token();switch(curr_tok){case NUMBER:{double v = number_value;get_token();return v;}case NAME:{double &v = table[string_value];if (get_token() == ASSIGN)v = expr(true);return v;}case MINUS:return -prim(true);case LP:{double e = expr(true);if (curr_tok != RP)return error(") expected");get_token();return e;}default:return error("primary expected");}}// 函数get_token()为输入函数Token_value get_token(){char ch = 0;cin >> ch;switch (ch){case 0:return curr_tok = END;case ';':case '*':case '/':case '+':case '-':case '(':case ')':case '=':return curr_tok = Token_value(ch);case '0': case '1': case '2': case '3':case '4': case '5': case '6': case '7':case '8': case '9': case '.':cin.putback(ch);cin >> number_value;return curr_tok = NUMBER;default:if (isalpha(ch)){cin.putback(ch);cin >> string_value;return curr_tok = NAME;}error("bad token");return curr_tok = PRINT;}}// 错误处理int no_of_errors;double error(const string& s){no_of_errors++;cerr << "error: " << s << '\n';return 1;}// 驱动程序istream *input;int main(int argc, char* argv[]){switch (argc){case 1:input = &cin;break;case 2:input = new istringstream(argv[1]);break;default:error ("too many arguments");return 1;}table["pi"] = 3.1415926535897932385;// 插入预定义的名字table["e"] = 2.7182818284590452354;while (*input){get_token();if (curr_tok == END) break;if (curr_tok == PRINT) continue;cout << expr(false) << '\n';}if (input != &cin)delete input;return no_of_errors;}



原创粉丝点击