Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- using namespace std;
- struct perem //список переменных
- {
- char name;
- int value;
- perem* next;
- };
- perem* list;
- class Compile
- {
- private:
- char name;
- //perem* list;
- bool analyze_ok;
- bool memory_and_initial_ok;
- bool calculate_ok;
- ifstream in();
- bool bukva(char x);
- bool cif(char x);
- bool oper(char x);
- bool empty_list(perem* top);
- void push(perem*& top, char x);
- void show_list(perem* top);
- //void show_list(perem*& top);
- void show_list_and_value(perem* top);
- //void show_list_and_value(perem*& top);
- bool exist(perem* top, char x);
- int convert_int(int* number);
- void find_and_set_value(perem*& top, char x, int* numb);
- //void find_and_set_value(perem* top, char x, int* numb);
- void find_and_set_value1(perem*& top, char x, int numb);
- //void find_and_set_value1(perem* top, char x, int numb);
- int find_and_get_value(perem* top, char x);
- int number(char x);
- public:
- Compile();
- void analyze();
- void memory();
- void compile();
- void calculate();
- };
- int Compile::number(char x)
- {
- if (x == '-') return -1;
- if (x == '+') return 1;
- if (x == '0') return 0;
- if (x == '1') return 1;
- if (x == '2') return 2;
- if (x == '3') return 3;
- if (x == '4') return 4;
- if (x == '5') return 5;
- if (x == '6') return 6;
- if (x == '7') return 7;
- if (x == '8') return 8;
- if (x == '9') return 9;
- }
- bool Compile::bukva(char x) // Является ли символ буквой
- {
- if ((x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z'))
- return true;
- return false;
- }
- bool Compile::cif(char x) //Является ли символ цифрой
- {
- if ((x == '0') || (x == '1') || (x == '2') || (x == '3') || (x == '4') || (x == '5') || (x == '6') || (x == '7') || (x == '8') || (x == '9'))
- return true;
- return false;
- }
- bool Compile::oper(char x)
- {
- if ((x == '*') || (x == '-') || (x == '+') || (x == '/'))
- return true;
- return false;
- }
- bool Compile::empty_list(perem* top)
- {
- return top == NULL;
- }
- void Compile::push(perem*& top, char x)
- {
- perem* p;
- p = new perem;
- p->name = x;
- p->next = top;
- top = p;
- }
- void Compile::show_list(perem* top)
- {
- perem* p;
- p = top;
- while (p)
- {
- cout << p->name << " ";
- p = p->next;
- }
- cout << endl;
- }
- void Compile::show_list_and_value (perem* top)
- {
- perem* p;
- p = top;
- while (p)
- {
- cout << p->name << " = ";
- cout << p->value << endl;
- p = p->next;
- }
- cout << endl;
- }
- bool Compile::exist(perem* top, char x)
- {
- char prov;
- prov = x;
- perem* p = top;
- while (p)
- {
- if (p->name == prov)
- return true;
- p = p->next;
- }
- return false;
- }
- int Compile::convert_int(int* number)
- {
- int summ;
- summ = number[1] * 10000 + number[2] * 1000 + number[3] * 100 + number[4] * 10 + number[5];
- return summ * number[0];//определяет знак переменной
- }
- void Compile::find_and_set_value(perem*& top, char x, int*numb)
- {
- char prov;
- prov = x;
- perem* p = top;
- while (p)
- {
- if (p->name == prov)
- {
- p->value = convert_int(numb);
- }
- p = p->next;
- }
- }
- void Compile::find_and_set_value1(perem*& top, char x, int numb)
- {
- char prov;
- prov = x;
- perem* p = top;
- while (p)
- {
- if (p->name == prov)
- {
- p->value = numb;
- }
- p = p->next;
- }
- }
- int Compile::find_and_get_value (perem* top, char x)
- {
- char prov;
- prov = x;
- perem* p = top;
- while (p)
- {
- if (p->name == prov)
- {
- return p->value;
- }
- p = p->next;
- }
- }
- Compile::Compile()
- {
- }
- void Compile::analyze()
- {
- char x;
- char a;
- int i = 0;
- int p = 5; //количество знаков
- int pk = 0;//количество знаков на данный момент
- int q = 1;//начальное состояние
- int misstake=0;
- int cifinch = 0;//количество цифр в числе
- ifstream in("code.txt");
- while ((in >> a) && q != 0)
- {
- i++;
- x = a;
- switch (q)
- {
- case 1:
- {
- if (bukva(x))
- {
- q = 2;
- break;
- }
- else { cout << "Ошибка! Имя переменной должно быть буквой! Вместо " << i << " символа ожидалась буква." << endl; misstake++; break; }
- }
- case 2:
- {
- if (x == ':')
- {
- q = 3; break;
- }
- else { cout << "Синтаксическая ошибка! Вместо " << i << " символа ожидался символ :" << endl; misstake++; ; break; }
- }
- case 3:
- {
- pk = 0;
- if (x == '=')
- {
- q = 4; break;
- }
- else { cout << "Синтаксическая ошибка! Вместо " << i << " символа ожидался символ =" << endl; misstake++; break; }
- }
- case 4:
- {
- if (pk > p)
- {
- cout << "Слишком много операторов в одном выражении. Место ошибки: " << i << " символ. Максимальное количество операторов: " << p << endl;
- q = 0; break;
- }
- cifinch = 0;
- if (bukva(x))
- {
- q = 5; break;
- }
- else if (x == '+' || x == '-')
- {
- q = 7; break;
- }
- else { cout << "Синтаксическая ошибка! Вместо " << i << " символа ожидается переменная или знак +/-" << endl; misstake++; break; }
- }
- case 5:
- {
- if (x == ';')
- {
- q = 6; break;
- }
- else if (oper(x))
- {
- pk++;
- q = 4; break;
- }
- else { cout << "Синтаксическая ошибка! Вместо " << i << " символа ожидается ; для завершения операции, или оператор." << endl; misstake++; break; }
- }
- case 6:
- {
- if (x == ' ')
- {
- q = 1; break;
- }
- else if (bukva(x))
- {
- q = 2; break;
- }
- else { cout << "Синтаксическая ошибка! Вместо " << i << " символа ожидается пробел или переменная." << endl; misstake++; break; }
- }
- case 7:
- {
- if (cif(x) && cifinch < 5)
- {
- cifinch++; q = 7; break;
- }
- else if (!cif(x) && cifinch < 5)
- {
- cout << "Ошибка! Число должно состоять из 5 цифр, введено только " << cifinch << ". Добавьте цифры на место " << i << " символа." << endl;
- misstake++;
- break;
- }
- if (x == ';')
- {
- q = 6; break;
- }
- else if (oper(x))
- {
- pk++;
- q = 4; break;
- }
- else { cout << "Синтаксическая ошибка! Вместо " << i << " символа ожидается ; для завершения операции, или оператор." << endl; misstake++; break; }
- }
- default:break;
- }
- }
- if (misstake > 0)
- {
- analyze_ok = false;
- cout << "Всего в коде найдено " << misstake << " синтаксических(-е)(-ая) ошибок(-ки)(-ка).\n(Перечислены выше)" << endl;
- }
- else
- {
- analyze_ok = true;
- cout << "Код программы соответствует синтаксису языка. Все хорошо." << endl;
- }
- in.close();
- }
- void Compile::memory()
- {
- list = NULL;
- ifstream in("code.txt");
- char a;
- char x;
- int cifinch = 0;
- int q = 1;
- if (analyze_ok)
- {
- memory_and_initial_ok = false;
- while (in >> a)
- {
- x = a;
- switch (q)
- {
- case 1:
- {
- if (bukva(x))
- {
- push(list, x);
- q = 2;
- break;
- }
- }
- case 2:
- {
- if (x == ':')
- {
- q = 3; break;
- }
- }
- case 3:
- {
- if (x == '=')
- {
- q = 4; break;
- }
- }
- case 4:
- {
- cifinch = 0;
- if (bukva(x))
- {
- q = 5; break;
- }
- else if (x == '+' || x == '-')
- {
- q = 7; break;
- }
- }
- case 5:
- {
- if (x == ';')
- {
- q = 6; break;
- }
- else if (oper(x))
- {
- q = 4; break;
- }
- }
- case 6:
- {
- if (x == ' ')
- {
- q = 1; break;
- }
- else if (bukva(x))
- {
- push(list, x);
- q = 2; break;
- }
- }
- case 7:
- {
- if (cif(x) && cifinch < 5)
- {
- cifinch++; q = 7; break;
- }
- if (x == ';')
- {
- q = 6; break;
- }
- else if (oper(x))
- {
- q = 4; break;
- }
- }
- default:break;
- }
- }
- if (!empty_list(list))
- {
- cout << "Выделение памяти прошло успешно." << endl;
- memory_and_initial_ok = true;
- cout << "Список переменных:" << endl;
- show_list(list);
- }
- }
- in.close();
- }
- void Compile::calculate()
- {
- if ((memory_and_initial_ok) && analyze_ok)
- {
- calculate_ok = false;
- char a, x;
- int p = 5; //количество знаков
- int pk = 0;//количество знаков на данный момент
- int q = 1;//начальное состояние
- int misstake = 0;
- int temp_value2;
- char operat = '0';
- char temp_name;//временное имя переменной
- int temp_value1;
- int temp_value[6];
- int cifinch = 0;//количество цифр в числе
- ifstream in("code.txt");
- while (in >> a)
- {
- x = a;
- switch (q)
- {
- case 1:
- {
- if (bukva(x))
- {
- q = 2;
- temp_name = x;
- break;
- }
- }
- case 2:
- {
- if (x == ':')
- {
- q = 3; break;
- }
- }
- case 3:
- {
- pk = 0;
- if (x == '=')
- {
- q = 4; break;
- }
- }
- case 4:
- {
- cifinch = 0;
- if (operat != '0')
- {
- if (pk > 1)
- {
- if (bukva(x))
- {
- if (exist(list, x))
- {
- temp_value2 = find_and_get_value(list, x);
- if (operat == '*')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, find_and_get_value(list, temp_name) * temp_value2);
- }
- if (operat == '-')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, find_and_get_value(list, temp_name) - temp_value2);
- }
- if (operat == '+')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, find_and_get_value(list, temp_name) + temp_value2);
- }
- if (operat == '/')
- {
- if (temp_value2 == 0)
- {
- cout << "ОБНАРУЖЕНО ДЕЛЕНИЕ НА НОЛЬ" << endl;
- exit(1);
- }
- operat = '0';
- find_and_set_value1(list, temp_name, find_and_get_value(list, temp_name) / temp_value2);
- }
- }
- else
- {
- cout << "Переменная " << x << " не инициализирована!" << endl;
- misstake++;
- }
- q = 5; break;
- }
- else if (x == '+' || x == '-')
- {
- temp_value[0] = number(x);
- q = 7; break;
- }
- }
- if (bukva(x))
- {
- if (exist(list, x))
- {
- temp_value2 = find_and_get_value(list, x);
- if (operat == '*')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, temp_value1 * temp_value2);
- }
- if (operat == '-')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, temp_value1 - temp_value2);
- }
- if (operat == '+')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, temp_value1 + temp_value2);
- }
- if (operat == '/')
- {
- if (temp_value2 == 0)
- {
- cout << "ОБНАРУЖЕНО ДЕЛЕНИЕ НА НОЛЬ" << endl;
- exit(1);
- }
- operat = '0';
- find_and_set_value1(list, temp_name, temp_value1 / temp_value2);
- }
- }
- else
- {
- cout << "Переменная " << x << " не инициализирована!" << endl;
- misstake++;
- }
- q = 5; break;
- }
- else
- {
- temp_value[0] = number(x);
- q = 7; break;
- }
- }
- else if (bukva(x))
- {
- if (exist(list, x))
- temp_value1 = find_and_get_value(list, x);
- else
- {
- cout << "Переменная " << x << " не инициализирована!" << endl;
- misstake++;
- }
- q = 5; break;
- }
- else if (x == '+' || x == '-')
- {
- temp_value[0] = number(x);
- q = 7; break;
- }
- }
- case 5:
- {
- operat = '0';
- if ((x == ';')&&pk==0)
- {
- find_and_set_value1(list, temp_name, temp_value1);
- q = 6; break;
- }
- if (x == ';')
- {
- q = 6; break;
- }
- else if (oper(x))
- {
- pk++;
- if (x == '*')
- {
- operat = '*';
- }
- if (x == '-')
- {
- operat = '-';
- }
- if (x == '+')
- {
- operat = '+';
- }
- if (x == '/')
- {
- operat = '/';
- }
- q = 4; break;
- }
- }
- case 6:
- {
- //find_and_set_value1(list, temp_name, temp_value1);
- if (x == ' ')
- {
- q = 1; break;
- }
- else if (bukva(x))
- {
- temp_name = x;
- q = 2; break;
- }
- }
- case 7:
- {
- if (pk > 1)
- {
- if (operat != '0')
- {
- temp_value2 = convert_int(temp_value);
- if (cif(x) && cifinch < 5)
- {
- cifinch++;
- temp_value[cifinch] = number(x);
- q = 7; break;
- }
- if (operat == '*')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, find_and_get_value(list,temp_name) * temp_value2);
- }
- if (operat == '-')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, find_and_get_value(list, temp_name) - temp_value2);
- }
- if (operat == '+')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, find_and_get_value(list, temp_name) + temp_value2);
- }
- if (operat == '/')
- {
- if (temp_value2 == 0)
- {
- cout << "ОБНАРУЖЕНО ДЕЛЕНИЕ НА НОЛЬ" << endl;
- exit(1);
- }
- operat = '0';
- find_and_set_value1(list, temp_name, find_and_get_value(list, temp_name) / temp_value2);
- }
- }
- else if (cif(x) && cifinch < 5)
- {
- cifinch++;
- temp_value[cifinch] = number(x);
- q = 7; break;
- }
- if ((x == ';') && pk == 0)
- {
- find_and_set_value(list, temp_name, temp_value);
- q = 6; break;
- }
- if (x == ';')
- {
- q = 6; break;
- }
- if (oper(x))
- {
- temp_value1 = convert_int(temp_value);
- pk++;
- if (x == '*')
- {
- operat = '*';
- }
- if (x == '-')
- {
- operat = '-';
- }
- if (x == '+')
- {
- operat = '+';
- }
- if (x == '/')
- {
- operat = '/';
- }
- q = 4; break;
- }
- }
- if (operat != '0')
- {
- temp_value2 = convert_int(temp_value);
- if (cif(x) && cifinch < 5)
- {
- cifinch++;
- temp_value[cifinch] = number(x);
- q = 7; break;
- }
- if (operat == '*')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, temp_value1 * temp_value2);
- if (pk < 1)
- {
- q = 6; break;
- }
- else
- {
- q = 7;
- }
- }
- if (operat == '-')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, temp_value1 - temp_value2);
- if (pk < 1)
- {
- q = 6; break;
- }
- else
- {
- q = 7;
- }
- }
- if (operat == '+')
- {
- operat = '0';
- find_and_set_value1(list, temp_name, temp_value1 + temp_value2);
- if (pk < 1)
- {
- q = 6; break;
- }
- else
- {
- q = 7;
- }
- }
- if (operat == '/')
- {
- if (temp_value2 == 0)
- {
- cout << "ОБНАРУЖЕНО ДЕЛЕНИЕ НА НОЛЬ" << endl;
- exit(1);
- }
- operat = '0';
- find_and_set_value1(list, temp_name, temp_value1 / temp_value2);
- if (pk < 1)
- {
- q = 6; break;
- }
- else
- {
- q = 7;
- }
- }
- }
- else if (cif(x) && cifinch < 5)
- {
- cifinch++;
- temp_value[cifinch] = number(x);
- q = 7; break;
- }
- if ((x == ';')&&pk==0)
- {
- find_and_set_value(list, temp_name, temp_value);
- q = 6; break;
- }
- if (x == ';')
- {
- q = 6; break;
- }
- if (oper(x))
- {
- temp_value1 = convert_int(temp_value);
- pk++;
- if (x == '*')
- {
- operat = '*';
- }
- if (x == '-')
- {
- operat = '-';
- }
- if (x == '+')
- {
- operat = '+';
- }
- if (x == '/')
- {
- operat = '/';
- }
- q = 4; break;
- }
- }
- default:break;
- }
- }
- in.close();
- if (misstake > 0)
- {
- calculate_ok = false;
- cout << "Всего в коде найдено " << misstake << " ошибок вычисления." << endl;
- }
- else
- {
- calculate_ok = true;
- if (!empty_list(list))
- {
- cout << "Вычисления прошли успешно: " << endl;
- calculate_ok = true;
- cout << "Список переменных и соответствующих им значений:" << endl;;
- show_list_and_value(list);
- }
- }
- }
- }
- void Compile::compile()
- {
- this->analyze();
- this->memory();
- this->calculate();
- if (this->analyze_ok && this->memory_and_initial_ok && this->calculate_ok)
- {
- cout << "Компиляция завершена успешно! " << endl;
- }
- }
- int main()
- {
- setlocale(LC_ALL, "ru");
- Compile A;
- A.compile();
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement