#include <iostream>
#include <assert.h>
using namespace std;
/**
* calculator parser
* express -> express+term | express-term | term
* term -> term*primary | term/primary | primary
* primary -> (express) | num
*/
class Token{
public:
Token(char ch):kind(ch), value(0){}
Token(char ch, double value): kind(ch), value(value){}
char kind;
double value;
};
class Token_stream{
private:
Token buffer;
bool full;
public:
Token_stream():buffer(0), full(false){}
void putback(Token token);
Token get();
};
void Token_stream::putback(Token token) {
buffer = token;
full = true;
}
Token Token_stream::get() {
if (full){
full = false;
return buffer;
}
char ch;
cin>>ch;
switch(ch){
case '(':
case ')':
case '+':
case '-':
case '*':
case '/':
case ';':
case 'q':
return Token(ch);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
cin.putback(ch);
double val;
cin>>val;
return Token('8', val);
}
}
Token_stream ts;
double express();
double primary();
double term();
double express(){
double left = term();
Token t = ts.get();
char ch = t.kind;
while (true){
switch (ch){
case '+':
left += term();
t = ts.get();
ch = t.kind;
break;
case '-':
left -= term();
t = ts.get();
ch = t.kind;
break;
default:
ts.putback(t);
return left;
}
}
}
double term(){
double left = primary();
Token t = ts.get();
char ch = t.kind;
while (true){
switch (ch){
case '*':
left *= primary();
t = ts.get();
ch = t.kind;
break;
case '/':
left /= primary();
t = ts.get();
ch = t.kind;
break;
default:
ts.putback(t);
return left;
}
}
}
double primary(){
Token t = ts.get();
if (t.kind == '('){
double val = express();
assert(ts.get().kind == ')');
return val;
} else{
return t.value;
}
}
int main(){
cout<<"input the express"<<endl;
double val;
while (cin){
Token t = ts.get();
if (t.kind == ';')
cout<<"="<<val<<endl;
if (t.kind == 'q')
break;
else
ts.putback(t);
val = express();
}
}
recursive decent calculator parser
最新推荐文章于 2024-08-03 09:13:50 发布