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  }