Advertisement
Guest User

Untitled

a guest
Jul 15th, 2012
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.20 KB | None | 0 0
  1. #include "../../std_lib_facilities.h"
  2.  
  3. //------------------------------------------------------------------------------
  4.  
  5. const char number = '8';
  6. const char quit = 'q';
  7. const char print = ';';
  8. const string prompt = "> ";
  9. const string result = "= ";
  10.  
  11. class Token {
  12. public:
  13.     char kind;        // what kind of token
  14.     double value;     // for numbers: a value
  15.     Token(char ch)    // make a Token from a char
  16.         :kind(ch), value(0) { }    
  17.     Token(char ch, double val)     // make a Token from a char and a double
  18.         :kind(ch), value(val) { }
  19. };
  20.  
  21. //------------------------------------------------------------------------------
  22.  
  23. class Token_stream {
  24. public:
  25.     Token_stream();   // make a Token_stream that reads from cin
  26.     Token get();      // get a Token (get() is defined elsewhere)
  27.     void putback(Token t);    // put a Token back
  28.     void ignore(char c);
  29. private:
  30.     bool full;        // is there a Token in the buffer?
  31.     Token buffer;     // here is where we keep a Token put back using putback()
  32. };
  33.  
  34. //------------------------------------------------------------------------------
  35.  
  36. // The constructor just sets full to indicate that the buffer is empty:
  37. Token_stream::Token_stream()
  38. :full(false), buffer(0)    // no Token in buffer
  39. {
  40. }
  41.  
  42. //------------------------------------------------------------------------------
  43.  
  44. // The putback() member function puts its argument back into the Token_stream's buffer:
  45. void Token_stream::putback(Token t)
  46. {
  47.     if (full) error("putback() into a full buffer");
  48.     buffer = t;       // copy t to buffer
  49.     full = true;      // buffer is now full
  50. }
  51.  
  52. void Token_stream::ignore(char c)
  53. {
  54.     if (full && buffer.kind == c) {
  55.         full = false;
  56.         return;
  57.     }
  58.     full = false;
  59.    
  60.     char ch;
  61.     while (cin >> ch)
  62.         if (ch == c)
  63.             return;
  64. }
  65.  
  66. //------------------------------------------------------------------------------
  67.  
  68. Token Token_stream::get()
  69. {
  70.     if (full) {       // do we already have a Token ready?
  71.         // remove token from buffer
  72.         full=false;
  73.         return buffer;
  74.     }
  75.  
  76.     char ch;
  77.     cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)
  78.  
  79.     switch (ch) {
  80.     case print:    // for "print"
  81.     case quit:    // for "quit"
  82.     case '(':
  83.     case ')':
  84.     case '{':
  85.     case '}':
  86.     case '+':
  87.     case '-':
  88.     case '*':
  89.     case '/':
  90.     case '%':
  91.     case '!':
  92.         return Token(ch);        // let each character represent itself
  93.     case '.':
  94.     case '0': case '1': case '2': case '3': case '4':
  95.     case '5': case '6': case '7': case '8': case '9':
  96.         {    
  97.             cin.putback(ch);         // put digit back into the input stream
  98.             double val;
  99.             cin >> val;              // read a floating-point number
  100.             return Token(number,val);   // let '8' represent "a number"
  101.         }
  102.     default:
  103.         error("bad token");
  104.     }
  105. }
  106.  
  107. //------------------------------------------------------------------------------
  108.  
  109. Token_stream ts;        // provides get() and putback()
  110.  
  111. //------------------------------------------------------------------------------
  112.  
  113. void clean_up_mess()
  114. {
  115.     ts.ignore(print);
  116. }
  117.  
  118. double expression();    // declaration so that primary() can call expression()
  119.  
  120. //------------------------------------------------------------------------------
  121.  
  122. // deal with numbers and parentheses
  123. double primary()
  124. {
  125.     Token t = ts.get();
  126.     switch (t.kind) {
  127.     case '(':    // handle '(' expression ')'
  128.         {    
  129.             double d = expression();
  130.             t = ts.get();
  131.             if (t.kind != ')') error("')' expected");
  132.             return d;
  133.         }
  134.     case '{':    // handle '(' expression ')'
  135.         {    
  136.             double d = expression();
  137.             t = ts.get();
  138.             if (t.kind != '}') error("'}' expected");
  139.             return d;
  140.         }
  141.     case number:            // we use '8' to represent a number
  142.         return t.value;  // return the number's value
  143.     case '-':
  144.         return -primary();
  145.     case '+':
  146.         return primary();
  147.     //case 'q':
  148.     //  ts.putback(t);
  149.     //  break;
  150.     default:
  151.         error("primary expected: ");
  152.     }
  153. }
  154.  
  155. //------------------------------------------------------------------------------
  156.  
  157. // deal with !
  158. double fact()
  159. {
  160.     double left = primary();
  161.     Token t = ts.get();
  162.  
  163.     while(true) {
  164.         switch (t.kind) {
  165.         case '!':
  166.             {
  167.                 double leftint = left;
  168.                 double result = 1;
  169.                 for(int i = 1; i<=leftint; i++) {
  170.                     result *= i;
  171.                 }
  172.                 left = result;
  173.                 t = ts.get();
  174.                 break;
  175.             }
  176.         default:
  177.             ts.putback(t);
  178.             return left;
  179.         }
  180.     }
  181. }
  182.  
  183. //------------------------------------------------------------------------------
  184.  
  185. // deal with *, /, and %
  186. double term()
  187. {
  188.     double left = fact();
  189.     Token t = ts.get();        // get the next token from token stream
  190.  
  191.     while(true) {
  192.         switch (t.kind) {
  193.         case '*':
  194.             left *= fact();
  195.             t = ts.get();
  196.             break;
  197.         case '/':
  198.             {    
  199.                 double d = fact();
  200.                 if (d == 0) error("divide by zero");
  201.                 left /= d;
  202.                 t = ts.get();
  203.                 break;
  204.             }
  205.         case '%':
  206.             {
  207.                 double d = primary();
  208.                
  209.                 int i1 = int(left);
  210.                 if (i1 != left)
  211.                     error("left-hand operand of % not int");
  212.                
  213.                 int i2 = int(d);
  214.                 if (i2 != d)
  215.                     error("right-hand operand of % not int");
  216.                 if (i2 == 0)
  217.                     error("divide by zero");
  218.  
  219.                 left = i1 % i2;
  220.  
  221.                 t = ts.get();
  222.                 break;
  223.             }
  224.         default:
  225.             ts.putback(t);     // put t back into the token stream
  226.             return left;
  227.         }
  228.     }
  229. }
  230.  
  231. //------------------------------------------------------------------------------
  232.  
  233. // deal with + and -
  234. double expression()
  235. {
  236.     double left = term();      // read and evaluate a Term
  237.     Token t = ts.get();        // get the next token from token stream
  238.  
  239.     while(true) {    
  240.         switch(t.kind) {
  241.         case '+':
  242.             left += term();    // evaluate Term and add
  243.             t = ts.get();
  244.             break;
  245.         case '-':
  246.             left -= term();    // evaluate Term and subtract
  247.             t = ts.get();
  248.             break;
  249.         default:
  250.             ts.putback(t);     // put t back into the token stream
  251.             return left;       // finally: no more + or -: return the answer
  252.         }
  253.     }
  254. }
  255.  
  256. //------------------------------------------------------------------------------
  257.  
  258. void calculate()
  259. try
  260. {
  261.     while (cin) {
  262.         cout << prompt;
  263.         Token t = ts.get();
  264.         while (t.kind == print)
  265.             t=ts.get();
  266.         if (t.kind == quit) {
  267.             return;
  268.         }
  269.         ts.putback(t);
  270.         cout << result << expression() << endl;
  271.     }
  272. }
  273. catch (exception& e)
  274. {
  275.     cerr << e.what() << endl;
  276.     clean_up_mess();
  277. }
  278.  
  279. int main()
  280. try
  281. {
  282.     setlocale(LC_ALL,"");
  283.     cout << "Les opérateurs disonibles sont: +, -, *, /, %.\n";
  284.  
  285.     calculate();
  286.     keep_window_open();
  287.     return 0;
  288. }
  289. catch (exception& e) {
  290.     cerr << "error: " << e.what() << '\n';
  291.     keep_window_open("~~");
  292.     return 1;
  293. }
  294. catch (...) {
  295.     cerr << "Oops: unknown exception!\n";
  296.     keep_window_open("~~");
  297.     return 2;
  298. }
  299.  
  300. //------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement