//6.1 #include<iostream>//I/O #include<string> //字符串 #include<map> //映射 #include<cctype>//isatpha()
using namespace std; int no_of_errors; double error(const string& s) { no_of_errors++; cerr<<"error:"; cerr<<s; cerr<<"/n"; return 1; }
enum Token_value { NAME,NUMBER,END,PLUS='+',MINUS='-',MUL='*', DIV='/',PRINT=';',ASSING='=',LP='(',RP=')' }; Token_value curr_tok=PRINT; double number_value; string string_value; Token_value get_token() { char ch; do{//跳过空白,除了'\n' if(!cin.get(ch))return curr_tok=END; }while(ch!='\n'&&isspace(ch)); switch(ch){ case ';': case '\n': return curr_tok=PRINT; 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: //NAME,NAME=,或者错误 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("bad token"); return curr_tok=PRINT; } } map<string,double> table; double expr(bool); 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()==ASSING)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"); } } 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; } } 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; } } int main() { table["pi"]=3.1415926535897932385; table["e"]=2.7182818284590452354; while(cin){ get_token(); if(curr_tok==END)break; if(curr_tok==PRINT)continue; cout<<expr(false)<<"\n"; } return no_of_errors; } 
|