一个简单的计算器程序


const char number = '8';
const char quit = 'q';
const char print = ';';

const string prompt = ">";
const string result = "=";

const char name = 'a';
const char let = 'L';
const string declkey = "let";


//定义单词
class Token{
public:
char kind;
double value;
string name;

Token(char ch)
:kind(ch),value(0){}
Token(char ch, double val)
:kind(ch), value(val){}
Token(char ch, string n): kind(ch),name(n){}
};

//单词流
class Token_stream{
public:
Token_stream();
Token get();
void putback(Token t);
void ignore(char c);

private:
bool full;
Token buffer;
};

//定义单词流的构造函数
Token_stream::Token_stream()
:full(false),buffer(0){}

//
void Token_stream::putback(Token t)
{
if(full) error("putback() into a full buffer()");
full = true;
buffer = t;
}

//得到一个单词
Token Token_stream::get()
{
if(full){ //如果单词流中已经有一个单词
full = false;
return buffer;
}

char ch;
cin>>ch;

switch(ch) {
case print:
case quit:
//处理云算法,数字分组符号
case '(': case ')': case '{': case '}': case '+':
case '-': case '*': case '/': case '!': case '%':
//处理 let ×× = 的情况
case '=':
return Token(ch);
//处理数字
case '.':
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(number,val);

}
default:
//处理变量
if(isalpha(ch)) {
string s;
s += ch;
while( cin.get(ch) && (isalpha(ch) || (isdigit(ch) ))) s+=ch;
cin.putback(ch);
if(s == declkey)
return Token(let); //返回表示let的单词
return Token(name, s); //返回表示变量的单词
}
error("Bad token");
}
}

void Token_stream::ignore(char c)
{
if(full && buffer.kind == c)
{
full = false;
return ;
}
full = false;

char ch = 0;
while(cin>>ch)
{
if(ch == c) return;
}
}

//定义variable类
class Variable
{
public:
string name;
double value;
Variable(string n, double v):name(n),value(v){}
};

//定义variable向量
vector<Variable> var_table;

//return the value of the Variable named s
double get_value(string s)
{
for(int i=0; i<var_table.size(); i++)
if(var_table[i].name == s) return var_table[i].value;
error("get: undefined variable ",s);
}

//set the Variable named s to d
void set_value(string s, double d)
{
for(int i=0; i<var_table.size(); i++)
if(var_table[i].name == s)
{
var_table[i].value = d;
return ;
}
error("get: undefined variable ",s);
}

//判断变量var是否已经存在
bool is_declared(string var)
{
for(int i=0; i<var_table.size(); i++)
if(var_table[i].name == var) return true;
return false;
}

//新加入一个初始化的变量
double define_name(string var, double val)
{
if(is_declared(var) ) error(var,"declared twice");
var_table.push_back(Variable(var, val));
return val;
}


Token_stream ts;

double expression();

//定义primary规则
double primary()
{
Token t = ts.get();
switch(t.kind) {
case '(':
{
double d = expression();
t = ts.get();
if(t.kind !=')') error("')' expected");
return d;
}
case '{':
{
double d = expression();
t = ts.get();
if(t.kind !='}') error("'}' expected");
return d;
}
case number:
return t.value;
case '+':
return primary();
case '-':
return -primary();
case name:
return get_value(t.name);
default:
error("primary expected");
}
}

//处理阶乘
double factorial()
{
double left = primary();

double ff = left;
Token t = ts.get();
//处理阶乘
if(t.kind =='!')
{
if(left == 0) left = 1;

if(left > 0)
{
for(int i=1; i<left; ++i)
ff*=(left-i);
}
}else{
ts.putback(t);
}
return ff;
}


double term()
{
double left = factorial();
Token t = ts.get();

while(true) {
switch (t.kind){
case '*' :
left *= factorial();
t = ts.get();
break;
case '/':
{
double d = factorial();
if(d==0) error("divide by zero");
left/=d;
t = ts.get();
break;
}
case '%':
{
int i1 = narrow_cast<int>(left);
int i2 = narrow_cast<int>(factorial() );
if(i2 == 0) error("%: divide by zero");
left = i1%i2;
t = ts.get();
break;
}
default:
ts.putback(t);
return left;
}
}
}

double expression()
{
double left = term();
Token t = ts.get();

while(true)
{
switch(t.kind)
{
case '+':
left += term();
t = ts.get();
break;
case '-':
left -= term();
t = ts.get();
break;
default:
ts.putback(t);
return left;
}
}
}

double declaration()
{
Token t = ts.get();
if(t.kind != name) error("name expected in declaration");
string var_name = t.name;

Token t2 = ts.get();
if(t2.kind != '=') error("= missing in declaration of ", var_name);

double d = expression();

define_name(var_name, d );
return d;
}

double statement()
{
Token t = ts.get();
switch (t.kind) {
case let:
return declaration();
default :
ts.putback(t);
return expression();
}
}


void clean_up_mess();

void calculate()
{
while(cin)
{
try{
cout<<prompt;
Token t = ts.get();
while(t.kind == print) t = ts.get();

if(t.kind == quit)
{
return;
}
ts.putback(t);
cout<< result <<statement()<<endl;
}catch(exception&e)
{
cerr<<e.what()<<endl;
clean_up_mess();
}
}
}

void clean_up_mess()
{
ts.ignore(print);
}


int main()
{
try{
define_name("pi", 3.1415926535);
define_name("e", 2.7182818284);
calculate();
keep_window_open();
return 0;

}catch(runtime_error& e )
{
cerr<<e.what()<<endl;
keep_window_open("~~");
return 1;
}catch(...)
{
cerr<<"exception\n";
keep_window_open("~~");
return 2;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值