#include<iostream>
#include<map>
#include<string>
#include<cctype>
#include<math.h>
using namespace std;
class expr;
enum Token_value{
SQRT,SIN,COS,
NAME,NUMBER,END,
PLUS='+',MINUS='-',MUL='*',DIV='/',
PRINT=';',ASSIGN='=',LP='(',RP=')',MIN='^'
};
typedef double (*dfdp)(double);
dfdp math[]={sqrt,sin,cos};
int i;
typedef Token_value (expr::*get_token_p_p)();
get_token_p_p get_token_p;
class expr{
public:
expr(const char* str);
expr(void);
void jisuan(void);
double eval();
void print(){}
private:
int line_no;
string string_expr;
double (*dfddp)(double,double);
double number_value;
string string_value;
map<string,double> table;
Token_value curr_tok;
double my_expr(bool get);
double term(bool get);
double prim(bool get);
double min(bool get);
Token_value get_token(void);
Token_value get_token_ios(void);
double error(char *str);
};
expr::expr(void)
{
line_no=0;
i=-1;
number_value=0;
table["pi"]=3.1415;
table["e"]=2.718281;
}
expr::expr(const char* str)
{
string_expr=str;
expr();
}
double expr::error(char *str)
{
cerr<<"line:"<<line_no<<" "<<str<<endl;
return 1;
}
double expr::my_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 expr::term(bool get)
{
double left=min(get);
for(;;)
switch(curr_tok){
case MUL:
left*=min(true);
break;
case DIV:
if(double d=min(true)){
left/=d;
break;
}
return error("divide by 0");
default:
return left;
}
}
double expr::min(bool get)
{
double left=prim(get);
dfddp=pow;
for(;;)
{
switch(curr_tok){
case MIN:
left=dfddp(left,prim(true));
break;
case SQRT:
left=math[SQRT](left);
(this->*get_token_p)();
return left;
case SIN:
left=math[SIN](left);
(this->*get_token_p)();
return left;
case COS:
left=math[COS](left);
(this->*get_token_p)();
return left;
default:
return left;
}
}
}
double expr::prim(bool get)
{
if(get) (this->*get_token_p)();
switch(curr_tok){
case NUMBER:
{
double v=number_value;
(this->*get_token_p)();
return v;
}
case NAME:
{
if(strcmp(string_value.c_str(),"sqrt")==0)
{
(this->*get_token_p)();
if(curr_tok!=LP) return error("(expected");
double e=my_expr(true);
if(curr_tok!=RP) return error(")expected");
//get_token(); // delete RP;
curr_tok=SQRT;
return e;
}
else if(strcmp(string_value.c_str(),"sin")==0)
{
(this->*get_token_p)();
if(curr_tok!=LP) return error("( expected");
double e=my_expr(true);
if(curr_tok!=RP) return error(")expected");
curr_tok=SIN;
return e;
}
else if(strcmp(string_value.c_str(),"cos")==0)
{
(this->*get_token_p)();
if(curr_tok!=LP) return error("( expected");
double e=my_expr(true);
if(curr_tok!=RP) return error(")expected");
curr_tok=COS;
return e;
}
else {
double& v=table[string_value];
if((this->*get_token_p)()==ASSIGN)
{ line_no++; v=my_expr(true);}
return v;
}
}
case MINUS:
return -prim(true);
case LP:
{
double e=my_expr(true);
if(curr_tok!=RP) return error(")expected");
(this->*get_token_p)(); // delete RP;
return e;
}
return error("primay expected");
}
}
Token_value expr::get_token(void)
{
char ch=0;
double power=1;
number_value=0.0;
do{
if(!(ch=string_expr[++i])) return curr_tok=END;
}while(ch!='/n' && isspace(ch));
switch(ch){
case 0:
return curr_tok=END;
case ';':
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 '.':
//string_expr.putback(ch);
while((isdigit((int)ch)))
{
number_value=number_value*10+(ch-'0');
ch=string_expr[++i];
}
if(ch=='.')
ch=string_expr[++i];
while((isdigit((int)ch)))
{
number_value=number_value*10+(ch-'0');
ch=string_expr[++i];
power*=10;
}
i--;
number_value=number_value/power;
// cout<<number_value<<endl;
return curr_tok=NUMBER;
default:
if(isalpha(ch)){
string_value=ch;
while((ch=string_expr[++i]) && isalnum(ch)) string_value.push_back(ch);
i--;
return curr_tok=NAME;
}
//error("bad token");
return curr_tok=PRINT;
}
}
Token_value expr::get_token_ios(void)
{
char ch=0;
do{
if(!cin.get(ch)) return curr_tok=END;
}while(ch!='/n' && isspace(ch));
switch(ch){
case 0:
return curr_tok=END;
case ';':
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)){
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;
}
}
void expr::jisuan(void)
{
get_token_p=&expr::get_token_ios;
while(cin){
(this->*get_token_p)();
if(curr_tok==END)break;
if(curr_tok==PRINT)continue;
cout<<my_expr(false)<<'/n';
// cout<<number_value<<endl;
}
//return 0;
}
double expr::eval(void)
{
get_token_p=&expr::get_token;
//while(string_expr){
(this->*get_token_p)();
//if(curr_tok==END)break;
//if(curr_tok==PRINT)continue;
return my_expr(false);
// cout<<number_value<<endl;
// }
//return 0;
}
int main(void)
{ /*
expr x("123/3+123*4-3");
cout<<"x="<<x.eval()<<"/n";
x.print();
*/
expr a("1+3+9/3");
cout<<a.eval()<<endl;
a.jisuan();
}
#include<map>
#include<string>
#include<cctype>
#include<math.h>
using namespace std;
class expr;
enum Token_value{
SQRT,SIN,COS,
NAME,NUMBER,END,
PLUS='+',MINUS='-',MUL='*',DIV='/',
PRINT=';',ASSIGN='=',LP='(',RP=')',MIN='^'
};
typedef double (*dfdp)(double);
dfdp math[]={sqrt,sin,cos};
int i;
typedef Token_value (expr::*get_token_p_p)();
get_token_p_p get_token_p;
class expr{
public:
expr(const char* str);
expr(void);
void jisuan(void);
double eval();
void print(){}
private:
int line_no;
string string_expr;
double (*dfddp)(double,double);
double number_value;
string string_value;
map<string,double> table;
Token_value curr_tok;
double my_expr(bool get);
double term(bool get);
double prim(bool get);
double min(bool get);
Token_value get_token(void);
Token_value get_token_ios(void);
double error(char *str);
};
expr::expr(void)
{
line_no=0;
i=-1;
number_value=0;
table["pi"]=3.1415;
table["e"]=2.718281;
}
expr::expr(const char* str)
{
string_expr=str;
expr();
}
double expr::error(char *str)
{
cerr<<"line:"<<line_no<<" "<<str<<endl;
return 1;
}
double expr::my_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 expr::term(bool get)
{
double left=min(get);
for(;;)
switch(curr_tok){
case MUL:
left*=min(true);
break;
case DIV:
if(double d=min(true)){
left/=d;
break;
}
return error("divide by 0");
default:
return left;
}
}
double expr::min(bool get)
{
double left=prim(get);
dfddp=pow;
for(;;)
{
switch(curr_tok){
case MIN:
left=dfddp(left,prim(true));
break;
case SQRT:
left=math[SQRT](left);
(this->*get_token_p)();
return left;
case SIN:
left=math[SIN](left);
(this->*get_token_p)();
return left;
case COS:
left=math[COS](left);
(this->*get_token_p)();
return left;
default:
return left;
}
}
}
double expr::prim(bool get)
{
if(get) (this->*get_token_p)();
switch(curr_tok){
case NUMBER:
{
double v=number_value;
(this->*get_token_p)();
return v;
}
case NAME:
{
if(strcmp(string_value.c_str(),"sqrt")==0)
{
(this->*get_token_p)();
if(curr_tok!=LP) return error("(expected");
double e=my_expr(true);
if(curr_tok!=RP) return error(")expected");
//get_token(); // delete RP;
curr_tok=SQRT;
return e;
}
else if(strcmp(string_value.c_str(),"sin")==0)
{
(this->*get_token_p)();
if(curr_tok!=LP) return error("( expected");
double e=my_expr(true);
if(curr_tok!=RP) return error(")expected");
curr_tok=SIN;
return e;
}
else if(strcmp(string_value.c_str(),"cos")==0)
{
(this->*get_token_p)();
if(curr_tok!=LP) return error("( expected");
double e=my_expr(true);
if(curr_tok!=RP) return error(")expected");
curr_tok=COS;
return e;
}
else {
double& v=table[string_value];
if((this->*get_token_p)()==ASSIGN)
{ line_no++; v=my_expr(true);}
return v;
}
}
case MINUS:
return -prim(true);
case LP:
{
double e=my_expr(true);
if(curr_tok!=RP) return error(")expected");
(this->*get_token_p)(); // delete RP;
return e;
}
return error("primay expected");
}
}
Token_value expr::get_token(void)
{
char ch=0;
double power=1;
number_value=0.0;
do{
if(!(ch=string_expr[++i])) return curr_tok=END;
}while(ch!='/n' && isspace(ch));
switch(ch){
case 0:
return curr_tok=END;
case ';':
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 '.':
//string_expr.putback(ch);
while((isdigit((int)ch)))
{
number_value=number_value*10+(ch-'0');
ch=string_expr[++i];
}
if(ch=='.')
ch=string_expr[++i];
while((isdigit((int)ch)))
{
number_value=number_value*10+(ch-'0');
ch=string_expr[++i];
power*=10;
}
i--;
number_value=number_value/power;
// cout<<number_value<<endl;
return curr_tok=NUMBER;
default:
if(isalpha(ch)){
string_value=ch;
while((ch=string_expr[++i]) && isalnum(ch)) string_value.push_back(ch);
i--;
return curr_tok=NAME;
}
//error("bad token");
return curr_tok=PRINT;
}
}
Token_value expr::get_token_ios(void)
{
char ch=0;
do{
if(!cin.get(ch)) return curr_tok=END;
}while(ch!='/n' && isspace(ch));
switch(ch){
case 0:
return curr_tok=END;
case ';':
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)){
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;
}
}
void expr::jisuan(void)
{
get_token_p=&expr::get_token_ios;
while(cin){
(this->*get_token_p)();
if(curr_tok==END)break;
if(curr_tok==PRINT)continue;
cout<<my_expr(false)<<'/n';
// cout<<number_value<<endl;
}
//return 0;
}
double expr::eval(void)
{
get_token_p=&expr::get_token;
//while(string_expr){
(this->*get_token_p)();
//if(curr_tok==END)break;
//if(curr_tok==PRINT)continue;
return my_expr(false);
// cout<<number_value<<endl;
// }
//return 0;
}
int main(void)
{ /*
expr x("123/3+123*4-3");
cout<<"x="<<x.eval()<<"/n";
x.print();
*/
expr a("1+3+9/3");
cout<<a.eval()<<endl;
a.jisuan();
}