Analyse.h
  1 #include<iostream>
  2 #include<map>
  3 #include<string>
  4 using namespace std;
  5 
  6 enum Token_value
  7 {
  8     NAME,       NUMBER,      END,
  9     PLUS='+',   MINUS='-',   MUL='*', DIV='/',
 10     PRINT=';',  ASSIGN='=',  LP='(',RP=')'
 11 };
 12 
 13 Token_value curr_tok = PRINT;
 14 
 15 double number_value;
 16 string string_value;
 17 
 18 map<string,double>table;
 19 
 20 //------------error_status-----------
 21 int no_of_errors;
 22 
 23 double error(const string& s)
 24 {
 25     no_of_errors++;
 26     cerr<<"错误:"<<s<<'\n';
 27     return 1;
 28 }
 29 
 30 
 31 //------------get_token--------------
 32 Token_value get_token()
 33 {
 34     char ch;
 35     do{
 36         if(!cin.get(ch))return curr_tok = END;
 37     }while(ch!='\n' && isspace(ch));
 38 
 39     switch(ch)
 40     {
 41     case ';':
 42     case '\n':
 43         return curr_tok = PRINT;
 44 
 45     case '+':
 46     case '-':
 47     case '*':
 48     case '/':
 49     case '(':
 50     case ')':
 51     case '=':
 52         return  curr_tok = Token_value(ch);
 53 
 54     case '0':case '1':case '2':case '3':case '4':
 55     case '5':case '6':case '7':case '8':case '9':
 56     case '.':
 57         cin.putback(ch);
 58         cin>>number_value;
 59         return curr_tok = NUMBER;
 60 
 61     default:
 62         if(isalpha(ch))
 63         {
 64             string_value = ch;
 65             while(cin.get(ch) && isalnum(ch))string_value.push_back(ch);
 66             cin.putback(ch);
 67             return curr_tok = NAME;
 68         }
 69         error("非法变量名");
 70         return curr_tok = PRINT;
 71     }
 72 }
 73 
 74 
 75 //------------analyse----------------
 76 double prim(bool get);
 77 
 78 double term(bool get)
 79 {
 80     double left = prim(get);
 81     for(;;)
 82     {
 83         switch(curr_tok)
 84         {
 85         case MUL:
 86             left *= prim(true);
 87             break;
 88         case DIV:
 89             if(double d = prim(true))
 90             {
 91                 left /= d;
 92                 break;
 93             }
 94             return error("除以0溢出");
 95 
 96         default:
 97             return left;
 98         }
 99     }
100 }
101 
102 double expr(bool get)
103 {
104     double left = term(get);
105 
106     for(;;)
107     {
108         switch(curr_tok)
109         {
110         case PLUS:
111             left += term(true);
112             break;
113         case MINUS:
114             left -= term(true);
115             break;
116         default:
117             return left;
118         }
119     }
120 }
121 
122 double prim(bool get)
123 {
124     if(get)get_token();
125 
126     switch(curr_tok)
127     {
128     case NUMBER:{double v = number_value;
129                  get_token();
130                  return v;
131                 }
132 
133     case NAME:  {double& v = table[string_value];
134                  if(get_token() == ASSIGN){v = expr(true);}
135                  return v;
136                 }
137 
138     case MINUS: {return -prim(true);}
139 
140     case LP:    {double e = expr(true);
141                  if(curr_tok != RP){return error("没有匹配右括号");}
142                  get_token();
143                  return e;
144                  }
145     default:
146         return error("初等项异常");
147     }
148 }
149 
150 
main.cpp
 1 #include"Analyse.h"
 2 int main()
 3 {
 4     table["pi"= 3.1415926535897932385;
 5     table["e"]  = 2.7182818284590452354;
 6 
 7     while(cin){
 8         get_token();
 9         if(curr_tok == END)break;
10         if(curr_tok == PRINT)continue;
11         cout<<expr(false)<<'\n';
12     }
13 
14     return no_of_errors;
15 }