《小型桌面计算器源程序》由会员分享,可在线阅读,更多相关《小型桌面计算器源程序(5页珍藏版)》请在金锄头文库上搜索。
1、小型桌面计算器源程序#include#include#include#includeusing namespace std;maptable;namespace Lexerenum Token_valueNAME,NUMBER,END,PLUS=+,MINUS=-,MUL=*,DIV=/,PRINT=;,ASSIGN=,LP=(,RP=);Token_value curr_tok=PRINT;double number_value;string string_value;Token_value get_token();namespace Errorstruct Zero_divide;stru
2、ct Syntax_errorconst char* p;Syntax_error(const char* q)p=q;namespace Parserdouble expr(bool get);double term(bool get);double prim(bool get);using namespace Lexer;using namespace Error;namespace Driverint no_of_errors;std:istream*input; void skip();Lexer:Token_value Lexer:get_token() char ch;cinch;
3、switch(ch)case#:return curr_tok=END;case;:case*:case/:case+:case-:case(:case):case=:return curr_tok=Token_value(ch);case0:case1:case2:case3:case4:case5:case6:case7:case8:case9:case.:cin.putback(ch);cinnumber_value;return curr_tok=NUMBER;default:if(isalpha(ch)cin.putback(ch);cinstring_value;return cu
4、rr_tok=NAME;throw Error:Syntax_error(bad token);return curr_tok=PRINT;double Parser:expr(bool get) using namespace Lexer; double left=term(get); for(;) switch(curr_tok) case PLUS: left+=term(true); break; case MINUS: left-=term(true); break; default: return left; double Parser:term(bool get)using na
5、mespace Lexer; double left=prim(get); for(;) switch(curr_tok) case MUL: left*=prim(true); break; case DIV: if(double d=prim(true) left/=d; break; throw Error:Zero_divide(); default: return left; double Parser:prim(bool get) using namespace Lexer;if(get)get_token();switch(curr_tok)case NUMBER:double
6、v=number_value;get_token();return v;case NAME:double& v=tablestring_value;if(get_token()=ASSIGN)v=expr(true);return v;case MINUS:return-prim(true);case LP:double e=expr(true);if(curr_tok!=RP) throw Error:Syntax_error()expected);get_token();return e;case END:return 1;default:throw Error:Syntax_error(
7、primary expected);void Driver:skip()no_of_errors+;while(*input) char ch;input-get(ch);switch(ch)casen:case;:return ;int main(int argc,char*argv)cout.欢迎使用桌面计算器.endl;cout注意:1.如果输入了一个以字母开头的标识符;cout请在标识符的后面加上一个空格,否则程序将会出错endl;cout2.若输入了一个表达式,切记在后面加上;号endl;cout3.若想退出程序,请输出#endl;Driver:input=&cin; tablepi
8、=3.; tablee=2.; while(*Driver:input) try Lexer:get_token(); if(Lexer:curr_tok=Lexer:END)break; if(Lexer:curr_tok=Lexer:PRINT) continue; coutParser:expr(false)endl; catch(Error:Zero_divide) cerrattempt to divide by zeroendl; if(Lexer:curr_tok!=Lexer:PRINT) Driver:skip(); catch(Error:Syntax_error e) cerrsyntax error:e.pendl; if(Lexer:curr_tok!=Lexer:PRINT) Driver:skip(); if(Driver:input!=&std:cin) delete Driver:input; cout.谢谢使用.endl; return Driver:no_of_errors;