Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdlib>
- #include <cstring>
- #include <cstdio>
- using namespace std;
- const int DELIMITER = 1;
- const int VARIABLE = 2;
- const int NUMBER = 3;
- const int MAX = 200;
- const int kount_vars = 50;
- class calculator
- {
- private:
- char *vkaz_vuraz; // вказує на вираз
- char potochna_lexem[MAX]; // зберігає поточну лексему
- int current_type_lexem; // зберігає тип лексеми
- long double vars[kount_vars]; // зберігає значення змінних
- void operation_1(long double &result);
- void operation_2(long double &result);
- void operation_3(long double &result);
- void operation_4(long double &result);
- void operation_5(long double &result);
- void operation_6(long double &result);
- void atom(long double &result);
- void get_potochna_lexem();
- void putback();
- void error(int error);
- long double find_var(char *s);
- int is_Delim(char c);
- public:
- calculator();
- long double operation_(char *exp);
- };
- calculator::calculator(){
- vkaz_vuraz = NULL;//вказує на вираз
- for(int i = 0; i < kount_vars; ++i) vars[i] = 0.0;//обнуляємо змінні
- }
- // Початкова точка аналізатора
- long double calculator::operation_(char *exp)//передаємо те що зчитали
- {
- long double result;
- vkaz_vuraz = exp;
- get_potochna_lexem();
- if (!*potochna_lexem){
- puts("No expression"); // вираз пустий
- return 0;
- }
- operation_1(result);
- if (*potochna_lexem) puts("Syntax Error"); // остання лексема повинна бути 0-символом
- return result;
- }
- // отримує наступну лексему.
- void calculator::get_potochna_lexem()
- {
- char *temp;
- current_type_lexem = 0;
- temp = potochna_lexem;
- *temp = '\0';
- if (!*vkaz_vuraz) return; // в кінці виразу
- while(isspace(*vkaz_vuraz)) ++vkaz_vuraz; // пропуск роздільника
- if (strchr("+-*/%^=()", *vkaz_vuraz)){
- current_type_lexem = DELIMITER; // перехід до наступного символу
- *temp++ = *vkaz_vuraz++;
- }
- else if (isalpha(*vkaz_vuraz))
- {
- while(!is_Delim(*vkaz_vuraz))
- *temp++ = *vkaz_vuraz++;
- current_type_lexem = VARIABLE;
- }
- else if(isdigit(*vkaz_vuraz))
- {
- while (!is_Delim(*vkaz_vuraz))
- *temp++ = *vkaz_vuraz++;
- current_type_lexem = NUMBER;
- }
- *temp = '\0';
- }
- // присвоювання
- void calculator::operation_1(long double &result)
- {
- int slot;
- char tcurrent_lexem;
- char temp_potochna_lexem[80];
- if(current_type_lexem == VARIABLE)
- {
- // зберігає стару лексему
- strcpy(temp_potochna_lexem, potochna_lexem);
- tcurrent_lexem = current_type_lexem; // знаходимо індекс змінної
- slot = toupper(*potochna_lexem) - 'A';
- get_potochna_lexem();
- if (*potochna_lexem != '=')
- {
- char *t;
- t = potochna_lexem;
- for(; *t; t++) vkaz_vuraz--; // повертає поточну лексему
- // відновлює стару – присвоювання не відбувається
- strcpy(potochna_lexem, temp_potochna_lexem);
- current_type_lexem = tcurrent_lexem;
- }
- else
- {
- get_potochna_lexem(); //вилучаємо наступну частину виразу exp
- operation_2(result);
- vars[slot] = result;
- return;
- }
- }
- operation_2(result);
- }
- // додаємо або віднімаємо два терма
- void calculator::operation_2(long double &result)
- {
- char op;
- long double temp;
- operation_3(result);
- while((op = *potochna_lexem) == '+' || op == '-')
- {
- get_potochna_lexem();
- operation_3(temp);
- if(op == '-') result = result - temp;
- else if(op == '+') result = result + temp;
- }
- }
- // множимо або ділимо два фактори
- void calculator::operation_3(long double &result)
- {
- register char op;
- long double temp;
- operation_4(result);
- while ((op = *potochna_lexem) == '*' || op == '/' || op == '%')
- {
- get_potochna_lexem();
- operation_4(temp);
- if(op == '*') result = result * temp;
- else if(op == '/') result = result / temp;
- else if(op == '%') result = (int) result % (int) temp;
- }
- }
- // піднесення до степеня
- void calculator::operation_4(long double &result)
- {
- long double temp, ex;
- register int t;
- operation_5(result);
- if (*potochna_lexem== '^')
- {
- get_potochna_lexem();
- operation_4(temp);
- ex = result;
- if (temp==0.0)
- {
- result = 1.0;
- return;
- }
- for(t=(int)temp-1; t>0; --t) result = result * (long double)ex;
- }
- }
- //Виконання унарних операцій + чи -.
- void calculator::operation_5(long double &result)
- {
- register char op;
- op = 0;
- if ((current_type_lexem == DELIMITER) && (*potochna_lexem=='+' || *potochna_lexem == '-'))
- {
- op = *potochna_lexem;
- get_potochna_lexem();
- }
- operation_6(result);
- if (op=='-')
- result = -result;
- }
- // аналіз виразу, який містить дужки
- void calculator::operation_6(long double &result)
- {
- if ((*potochna_lexem == '('))
- {
- get_potochna_lexem();
- operation_2(result);
- if (*potochna_lexem != ')') puts("Unbalanced Parentheses");
- get_potochna_lexem();
- }
- else{
- if(current_type_lexem == VARIABLE){
- if(!isalpha(*potochna_lexem)) puts("Unbalanced Parentheses");
- else result = vars[toupper(*potochna_lexem) - 'A'];
- get_potochna_lexem();
- }
- else if(current_type_lexem == NUMBER){
- result = atof(potochna_lexem);
- get_potochna_lexem();
- }
- else printf("Syntax Error\n");
- }
- }
- // вилучає число або значення змінної
- int calculator::is_Delim (char c)
- {
- if (strchr(" +-/*%^=()", c) || (c == 9) || (c == '\r' || c == 0)) return 1;
- return 0;
- }
- int main()
- {
- //puts("Hello Yuriy Vitaliyovitch\n");
- puts("Your calculating machine started");
- puts(" Enter \'?\' for more commands!");
- calculator ob;
- string entr;
- while(true)
- {
- printf("Enter expression: \n>");
- getline(cin, entr);
- if(entr.size() > (size_t)MAX) printf(" Expression must have less characters\n");
- else
- {
- int flag = 0;
- int bracket = 0;
- int l = 0;
- int r = 0;
- for(size_t i = 0; i < entr.size(); ++i){
- if(entr[i] == '(') ++l;
- if(entr[i] == ')') ++r;
- if(r > l) bracket = max(bracket, r - l);
- }
- if(bracket != 0) flag = 1;
- for(int i = 0; i < bracket; ++i) entr = '(' + entr;
- l = 0; r = 0;
- for(size_t i = 0; i < entr.size(); ++i)
- if(entr[i] == '(') ++l;
- else if(entr[i] == ')') ++r;
- if(r != l){
- if(r > l) while(l++ < r) entr = '(' + entr;
- else if(l > r) while(r++ < l) entr = entr + ')';
- flag = 1;
- }
- if(flag){
- cout << "Mu zminuemo vash vuraz na krashche" << endl;
- cout << "Os shcho mu otrumalu" << endl;
- cout << entr << endl;
- }
- char *entry = new char[entr.length() + 1];
- strcpy(entry, entr.c_str());
- if(*entry == '?') printf("@ - information\n? - help\n. - exit\n");
- else if(*entry == '@') printf("Calculator ver 1.0.1\nOperations:\n+,-,*,/,^,(,)\n");
- else if (*entry == '.') return 0;
- else{
- cout<<"Answer: ";
- long double ans;
- ans = ob.operation_(entry);
- if(ans == (long long)(ans)) cout << (long long)(ans);
- else cout << ans;
- cout << "\n\n";
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement