初学c++时写的,还很不完善,没有用到很多c++的许多独有的特性,仅供参考一下,有括号sqrt()表示开根号
#include <iostream>
#include <string>
#include <map>
#include <math.h>
using namespace std;
map<string,double>table;
double expr(bool);
double term(bool);
double prim(bool);
double error(const string&);
enum Token_value{NAME,
NUMBER,
END,
SQR,
EXIT,
PLUS='+',
MINUS='-', MUL='*', DIV='/',
ASSIGN='=', PRINT=';', LP='(',
RP=')'};
Token_value curr_tok=PRINT;
//定义一个全局变量;
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 b=prim(true))
{
left/=b;
break;
}
return error("divide by 0!");
default:
return left;
}
}
}
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 SQR:
{double v=sqrt(prim(true));
return v;
}
case MINUS:
{
return -prim(true);
}
case LP:
{double e=expr(true);
if(curr_tok!=RP) return error(") is expected!");
get_token();
return e;
}
default:
return error("primary expected!");
}
}
Token_value get_token()
{
char ch;
do
{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 '(':
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))
{
string_value=ch;
while (cin.get(ch)&&isalnum(ch))
string_value.push_back(ch);
cin.putback(ch);
if (string_value=="sqrt")
{return curr_tok=SQR; }
else if(string_value=="exit")
{return curr_tok=EXIT;
}
//添加
return curr_tok=NAME;
}
error ("bad token!");
return curr_tok=PRINT;
}
}
int no_error;
double error(const string& s)
{
no_error++;
cerr<<"error:"<<s<<endl;
return no_error;
}
int main()
{
table["pi"]=3.14159;
table["eq"]=2.718281;
while (cin)
{get_token();
if(curr_tok==END) break;
if(curr_tok==PRINT) continue;
if(curr_tok==EXIT) break;
cout<<expr(false)<<"\n";
}
system("pause");
return no_error;
}
dev-c++下编译通过