标题: 计算器(计算字符串表达式)(修改自lemon例子) [打印本页] 作者: wumao2 时间: 2009-12-21 21:32 标题: 计算器(计算字符串表达式)(修改自lemon例子) #include
#include
#include
#include
#include
using namespace std;
//== 字符串表达式======
string strExp="3*(x-5) +7";
enum Token_value {
NAME, NUMBER, END, INC, DEC,
PLUS='+', MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')'
};
Token_value curr_tok = PRINT;
double number_value;
string string_value;
double expr(bool );
double term(bool );
double error(const string&);
double prim(bool );
Token_value get_token();
map table;
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)) {
left /=d;
break;
}
return error("divide by 0");
default:
return left;
}
}
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];
get_token();
if (curr_tok == ASSIGN)
v = expr(true);
if (curr_tok == INC) //r++;
v = v+1;
if (curr_tok == DEC) //r++;
v = v-1;
return v;
}
case INC:
return prim(true)+1;
case DEC:
return prim(true)-1;
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");
}
}
Token_value get_token()
{
char ch;
string strTemp;
do {
//============changed=========================
//if(!cin.get(ch)) return curr_tok = END;
//========= to ==============================
if (strExp.empty()) {
return curr_tok = END;
}
ch = strExp.at(0);
strExp.erase(0,1);
if(!ch) {
return curr_tok = END;
}
//===========================================
} while(ch!='\n' && isspace(ch));
switch(ch) {
case ';':
case '\n':
return curr_tok=PRINT;
case 0:
return curr_tok=END;
case '+': // added for ++name and name++
{
char c;
//================ changed =========================
//if ( cin.get(c) && c == '+' )
//return curr_tok=INC;
//========= to ==============================
c = strExp.at(0);
if (c == '+') {
strExp.erase(0,1);
return curr_tok=INC;
}
//================================================
return curr_tok=Token_value(ch);
}
case '-':
{
char c;
//===============changed============================
//if ( cin.get(c) && c == '-' ) {
//return curr_tok=DEC;
//}
//cin.putback(c);
//============= to ==================================
c = strExp.at(0);
if (c == '-') {
strExp.erase(0,1);
return curr_tok=DEC;
}
//======================================
return curr_tok=Token_value(ch);
}
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 '.':
//================= changed =================================
//cin.putback(ch);
//cin >> number_value;
//================ to =====================================
strTemp.clear();
strTemp.assign(1,ch);
number_value = atof(strTemp.c_str());
//=======================================================
return curr_tok=NUMBER;
default:
if (isalpha(ch)){
string_value=ch;
//========================changed=========================
//while(cin.get(ch) && isalnum(ch)) string_value.push_back(ch);
//cin.putback(ch);
//==========================to ===========================
ch = strExp.at(0);
if (isalnum(ch)) {
strExp.erase(0,1);
string_value.push_back(ch);
}
//================================================================