Advertisement
Guest User

Untitled

a guest
Apr 16th, 2014
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.36 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <cstdio>
  5. using namespace std;
  6. const int DELIMITER = 1;
  7. const int VARIABLE = 2;
  8. const int NUMBER = 3;
  9. const int MAX = 200;
  10. const int kount_vars = 50;
  11. class calculator
  12. {
  13. private:
  14.     char *vkaz_vuraz; // вказує на вираз
  15.     char potochna_lexem[MAX]; // зберігає поточну лексему
  16.     int current_type_lexem; // зберігає тип лексеми
  17.     long double vars[kount_vars]; // зберігає значення змінних
  18.     void operation_1(long double &result);
  19.     void operation_2(long double &result);
  20.     void operation_3(long double &result);
  21.     void operation_4(long double &result);
  22.     void operation_5(long double &result);
  23.     void operation_6(long double &result);
  24.     void atom(long double &result);
  25.     void get_potochna_lexem();
  26.     void putback();
  27.     void error(int error);
  28.     long double find_var(char *s);
  29.     int is_Delim(char c);
  30. public:
  31.     calculator();
  32.     long double operation_(char *exp);
  33. };
  34.  
  35. calculator::calculator(){
  36.     vkaz_vuraz = NULL;//вказує на вираз
  37.     for(int i = 0; i < kount_vars; ++i) vars[i] = 0.0;//обнуляємо змінні
  38. }
  39. // Початкова точка аналізатора
  40. long double calculator::operation_(char *exp)//передаємо те що зчитали
  41. {
  42.     long double result;
  43.     vkaz_vuraz = exp;
  44.     get_potochna_lexem();
  45.     if (!*potochna_lexem){
  46.         puts("No expression"); // вираз пустий
  47.         return 0;
  48.     }
  49.     operation_1(result);
  50.     if (*potochna_lexem) puts("Syntax Error"); // остання лексема повинна бути 0-символом
  51.     return result;
  52. }
  53. // отримує наступну лексему.
  54. void calculator::get_potochna_lexem()
  55. {
  56.     char *temp;
  57.     current_type_lexem = 0;
  58.     temp = potochna_lexem;
  59.     *temp = '\0';
  60.     if (!*vkaz_vuraz) return; // в кінці виразу
  61.     while(isspace(*vkaz_vuraz)) ++vkaz_vuraz; // пропуск роздільника
  62.     if (strchr("+-*/%^=()", *vkaz_vuraz)){
  63.         current_type_lexem = DELIMITER; // перехід до наступного символу
  64.         *temp++ = *vkaz_vuraz++;
  65.     }
  66.     else if (isalpha(*vkaz_vuraz))
  67.     {
  68.         while(!is_Delim(*vkaz_vuraz))
  69.             *temp++ = *vkaz_vuraz++;
  70.         current_type_lexem = VARIABLE;
  71.     }
  72.     else if(isdigit(*vkaz_vuraz))
  73.     {
  74.         while (!is_Delim(*vkaz_vuraz))
  75.             *temp++ = *vkaz_vuraz++;
  76.         current_type_lexem = NUMBER;
  77.     }
  78.     *temp = '\0';
  79. }
  80. // присвоювання
  81. void calculator::operation_1(long double &result)
  82. {
  83.     int slot;
  84.     char tcurrent_lexem;
  85.     char temp_potochna_lexem[80];
  86.     if(current_type_lexem == VARIABLE)
  87.     {
  88.         // зберігає стару лексему
  89.         strcpy(temp_potochna_lexem, potochna_lexem);
  90.         tcurrent_lexem = current_type_lexem; // знаходимо індекс змінної
  91.         slot = toupper(*potochna_lexem) - 'A';
  92.         get_potochna_lexem();
  93.         if (*potochna_lexem != '=')
  94.         {
  95.             char *t;
  96.             t = potochna_lexem;
  97.             for(; *t; t++) vkaz_vuraz--; // повертає поточну лексему
  98.             // відновлює стару – присвоювання не відбувається
  99.             strcpy(potochna_lexem, temp_potochna_lexem);
  100.             current_type_lexem = tcurrent_lexem;
  101.         }
  102.         else
  103.         {
  104.             get_potochna_lexem(); //вилучаємо наступну частину виразу exp
  105.             operation_2(result);
  106.             vars[slot] = result;
  107.             return;
  108.         }
  109.     }
  110.     operation_2(result);
  111. }
  112.  
  113. // додаємо або віднімаємо два терма
  114. void calculator::operation_2(long double &result)
  115. {
  116.     char op;
  117.     long double temp;
  118.     operation_3(result);
  119.     while((op = *potochna_lexem) == '+' || op == '-')
  120.     {
  121.         get_potochna_lexem();
  122.         operation_3(temp);
  123.         if(op == '-') result = result - temp;
  124.         else if(op == '+') result = result + temp;
  125.     }
  126. }
  127.  
  128. // множимо або ділимо два фактори
  129. void calculator::operation_3(long double &result)
  130. {
  131.     register char op;
  132.     long double temp;
  133.     operation_4(result);
  134.     while ((op = *potochna_lexem) == '*' || op == '/' || op == '%')
  135.     {
  136.         get_potochna_lexem();
  137.         operation_4(temp);
  138.         if(op == '*') result = result * temp;
  139.         else if(op == '/') result = result / temp;
  140.         else if(op == '%') result = (int) result % (int) temp;
  141.     }
  142. }
  143.  
  144.  
  145. // піднесення до степеня
  146. void calculator::operation_4(long double &result)
  147. {
  148.     long double temp, ex;
  149.     register int t;
  150.     operation_5(result);
  151.     if (*potochna_lexem== '^')
  152.     {
  153.         get_potochna_lexem();
  154.         operation_4(temp);
  155.         ex = result;
  156.         if (temp==0.0)
  157.         {
  158.             result = 1.0;
  159.             return;
  160.         }
  161.         for(t=(int)temp-1; t>0; --t) result = result * (long double)ex;
  162.     }
  163. }
  164.  
  165. //Виконання унарних операцій + чи -.
  166. void calculator::operation_5(long double &result)
  167. {
  168.     register char op;
  169.     op = 0;
  170.     if ((current_type_lexem == DELIMITER) && (*potochna_lexem=='+' || *potochna_lexem == '-'))
  171.     {
  172.         op = *potochna_lexem;
  173.         get_potochna_lexem();
  174.     }
  175.     operation_6(result);
  176.     if (op=='-')
  177.         result = -result;
  178. }
  179. // аналіз виразу, який містить дужки
  180. void calculator::operation_6(long double &result)
  181. {
  182.     if ((*potochna_lexem == '('))
  183.     {
  184.         get_potochna_lexem();
  185.         operation_2(result);
  186.         if (*potochna_lexem != ')') puts("Unbalanced Parentheses");
  187.         get_potochna_lexem();
  188.     }
  189.     else{
  190.         if(current_type_lexem == VARIABLE){
  191.         if(!isalpha(*potochna_lexem)) puts("Unbalanced Parentheses");
  192.         else result = vars[toupper(*potochna_lexem) - 'A'];
  193.         get_potochna_lexem();
  194.         }
  195.         else if(current_type_lexem == NUMBER){
  196.         result = atof(potochna_lexem);
  197.         get_potochna_lexem();
  198.         }
  199.         else printf("Syntax Error\n");
  200.     }
  201. }
  202.  
  203. // вилучає число або значення змінної
  204. int calculator::is_Delim (char c)
  205. {
  206.     if (strchr(" +-/*%^=()", c) || (c == 9)  || (c == '\r' || c == 0)) return 1;
  207.     return 0;
  208. }
  209.  
  210. int main()
  211. {
  212.     //puts("Hello Yuriy Vitaliyovitch\n");
  213.     puts("Your calculating machine started");
  214.     puts(" Enter \'?\' for more commands!");
  215.     calculator ob;
  216.     string entr;
  217.     while(true)
  218.     {
  219.         printf("Enter expression: \n>");
  220.         getline(cin, entr);
  221.         if(entr.size() > (size_t)MAX) printf(" Expression must have less characters\n");
  222.         else
  223.         {
  224.             int flag = 0;
  225.             int bracket = 0;
  226.             int l = 0;
  227.             int r = 0;
  228.             for(size_t i = 0; i < entr.size(); ++i){
  229.                 if(entr[i] == '(') ++l;
  230.                 if(entr[i] == ')') ++r;
  231.                 if(r > l) bracket = max(bracket, r - l);
  232.             }
  233.             if(bracket != 0) flag = 1;
  234.             for(int i = 0; i < bracket; ++i) entr = '(' + entr;
  235.             l = 0; r = 0;
  236.             for(size_t i = 0; i < entr.size(); ++i)
  237.                 if(entr[i] == '(') ++l;
  238.                 else if(entr[i] == ')') ++r;
  239.             if(r != l){
  240.                 if(r > l) while(l++ < r) entr = '(' + entr;
  241.                 else if(l > r) while(r++ < l) entr = entr + ')';
  242.                 flag = 1;
  243.             }
  244.             if(flag){
  245.                 cout << "Mu zminuemo vash vuraz na krashche" << endl;
  246.                 cout << "Os shcho mu otrumalu" << endl;
  247.                 cout << entr << endl;
  248.             }
  249.             char *entry = new char[entr.length() + 1];
  250.             strcpy(entry, entr.c_str());
  251.             if(*entry == '?') printf("@ - information\n? - help\n. - exit\n");
  252.             else if(*entry == '@') printf("Calculator ver 1.0.1\nOperations:\n+,-,*,/,^,(,)\n");
  253.             else if (*entry == '.') return 0;
  254.             else{
  255.                 cout<<"Answer: ";
  256.                 long double ans;
  257.                 ans = ob.operation_(entry);
  258.                 if(ans == (long long)(ans)) cout << (long long)(ans);
  259.                 else cout << ans;
  260.                 cout << "\n\n";
  261.             }
  262.         }
  263.     }
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement