本计算器采用LR分析,可支持CMATH.H库里的大部分运算,并且支持导数运算 #include <iostream> #include <vector> #include <string> #include <sstream> #include <stack> #include <queue> #include <cmath> #include <fstream> #define END "$" #define COL 11 #define ROW 20 #define ACCEPT "ac" #define PI 3.1415926 #define CHANGSHU_a "a" #define CHANGSHU_n "n" #define CHANGSHU_e "e" using namespace std; class Token { public: typedef double Value; typedef string Property; string name; Value sync; Property property; Token():sync(0.0){} Token(const string &s):name(s),property(s),sync(0.0) {} Token(const char* s):name(s),property(s),sync(0.0) {} friend bool operator ==(const Token& t1,const Token& t2); }; bool operator ==(const Token& t1,const Token& t2) { return t1.name==t2.name; } class LRpda//定义LL语法分析下推自动机 { typedef vector<Token> Engender;//定义产生式 typedef int State; typedef string Action; typedef struct eexpr//定义表达式 { Token uToken; Engender engender; }eExpr; public: LRpda(); bool Caculate(const string& exprtmp);//执行PDA bool Derivative(const string& exprtmp); private: bool in_propertys(Token::Property pro,vector<Token::Property> &pVec); bool is_unTerminateToken(const Token& token);//判断是否为非终结符 bool is_TerminateToken(const Token& token);//判断是否为终结符 bool is_delim(char ch); bool is_operator(char ch); bool is_letter(char ch); bool is_num(const string& str); bool is_num(const Token& token) {} bool is_id(const string& str); bool is_changshu(const string &str); double get_digit(char *&exprtmp); string get_operator(char *&exprtmp); void MatrixToFile(const char* filename); void get_propertys(const char* str,vector<Token::Property> &pVec); Token::Property get_property(const string& str); void addExpr(const Token& token,const Engender& engender);//添加产生式 void addExpr(const Token& token,const string& engender); void showMatrix();//打印LL语法分析表 void printExpr(const eExpr& expr); Token operate(const Token& t1,const Token& op,const Token& t2); Token operate(const Token& op,const Token& t1); string der_operate(const string& op,const string& t1); string LRpda::der_operate(const Token& t1,const string& d1,const string& op,const Token& t2,const string& d2); Action ACTION(const State state,const Token& ttoken);//返回 LL语法分析表中行为uToken,列为tToken中的元素 Action GOTO(const State state,const Token& utoken); private: State start; //开始符号 Token end; //结束符号 vector<Token::Property> uTokens;//非终结符号集 vector<Token::Property> tTokens;//终结符号集 vector<Token::Property> operator_1; vector<Token::Property> operator_2; vector<Token::Property> operator_3; vector<Token::Property> operator_4; vector<Token::Property> operator_5; vector<string> Error; vector<eExpr> eExprs;//表达式集合 stack<Token> tStack; stack<State> sStack; stack<Token::Value> vStack; stack<string> dStack; unsigned int uTokenCount;//非终结符号数量 unsigned int tTokenCount;//终结符号数量 string matrix[ROW][COL];//LL语法分析表 }; LRpda::LRpda() { //num id op1 op2 op3 op4 op5 ( ) $ E string copymatrix[ROW][COL]={ {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","1" }, //0 {"s5","s6","s7","s8","s9","s2","s3","s4","e2","ac","10"}, //1 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","11"}, //2 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","12"}, //3 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","13"}, //4 {"r8","r8","r8","r8","r8","r8","r8","r8","r8","r8",""}, //5 {"r9","r9","r9","r9","r9","r9","r9","r9","r9","r9",""}, //6 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","14"}, //7 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","15"}, //8 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","16"}, //9 {"r6","r6","r6","r6","s9","r6","r6","r6","r6","r6","10"}, //10 {"s5","s6","s7","s8","s9","s2","s3","s4","e2","e1","17"}, //11 {"r5","r5","r5","r5","r5","r5","r5","r5","r5","r5",""}, //12 {"s5","s6","s7","s8","s9","s2","s3","s4","s18","e4","10"}, //13 {"s5","s6","r1","s8","s9","s2","s3","s4","r1","r1","10"}, //14 {"r2","r2","r2","r2","s9","r2","r2","r2","r2","r2","10"}, //15 {"r3","r3","r3","r3","s9","r3","r3","r3","r3","r3","10"}, //16 {"r4","r4","r4","r4","r4","r4","r4","r4","r4","r4","10"}, //17 {"r7","r7","r7","r7","r7","r7","r7","r7","r7","r7",""}}; //18 Token tTmp; string sTmp; int i,j; for(i=0;i<ROW;++i) for(j=0;j<COL;++j) matrix[i][j]=copymatrix[i][j]; get_propertys("num id op1 op2 op3 op4 op5 ( ) $ ",tTokens); get_propertys("E ",uTokens); get_propertys("+ -",operator_1); get_propertys("* /",operator_2); get_propertys("^",operator_3); get_propertys("log",operator_4); get_propertys("ln sin cos tan cot sec csc arcsin arccos arctan arccot sh ch th arsh arch arth ",operator_5); uTokenCount=uTokens.size(); tTokenCount=tTokens.size(); start=0; end=END; addExpr("E'","E"); //0 addExpr("E","E op1 E"); //1 addExpr("E","E op2 E"); //2 addExpr("E","E op3 E"); //3 addExpr("E","op4 E E"); //4 addExpr("E","op5 E"); //5 addExpr("E","E E"); //6 addExpr("E","( E )"); //7 addExpr("E","num"); //8 addExpr("E","id"); //9 Error.push_back("语法错误!"); Error.push_back("缺少运算分量!"); Error.push_back("不匹配的右括号!"); Error.push_back("缺少运算符!"); Error.push_back("缺少右括号!"); } void LRpda::MatrixToFile(const char* filename) { ofstream fout(filename),fout_t("martrix_tmp.txt"); int i,j; if(fout.good()) { fout<<"/t"; for(i=0;i<tTokenCount;++i) fout<<tTokens[i]<<"/t"; for(i=0;i<uTokenCount;++i) fout<<uTokens[i]<<"/t"; fout<<endl; for(i=0;i<ROW;++i) { fout<<i<<"/t"; for(j=0;j<COL;++j) fout<<matrix[i][j]<<"/t"; fout<<endl; } } for(i=0;i<ROW;++i) { fout_t<<"{"; for(j=0;j<COL-1;++j) fout_t<<"/""<<matrix[i][j]<<"/","; fout_t<<"/""<<matrix[i][j]<<"/""<<"},"<<endl; } fout_t.close(); fout.close(); } void LRpda::get_propertys(const char* str,vector<Token::Property> &pVec) { stringstream ss(str); string sTmp; while( ss>>sTmp) pVec.push_back(sTmp); } bool LRpda::in_propertys(Token::Property pro,vector<Token::Property> &pVec)