Advertisement
Leeen

отяп 2 переделанный под 3

May 27th, 2019
572
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.00 KB | None | 0 0
  1. #include "pch.h"
  2. #include <iostream>
  3. #include <fstream>
  4. #include <vector>
  5.  
  6. using namespace std;
  7.  
  8. string keyWord[4] = { "if", "then", "else", "end" };
  9.  
  10.  
  11. enum State {
  12.     S,
  13.     Id,         //идентификатор
  14.     Op,         //число
  15.     K_w,        //ключевое слово
  16.     L,          // <
  17.     R,          // >
  18.     W,          // =
  19.     As,         // <= >= ==
  20.     Ao,         // + -
  21.     Unk,        // неопознанный элемент
  22. };
  23. enum LexType { Keyword, SpecialSymbol, Constant, Ident, UnknownToken };
  24.  
  25.  
  26.  
  27. struct Lex
  28. {
  29.     LexType type;
  30.     char* str;
  31. };
  32.  
  33. const State matrix[10][8] =
  34. {
  35.     //   a-Z     0-9     <       >      =       +/-
  36.         K_w,    Op,     L,      R,      W,      Op,     S,      Unk,     //старт  
  37.         Id,     Id,     Unk,    Unk,    Unk,    Unk,    S,      Unk,     //идентификатор  
  38.         Unk,    Op,     Unk,    Unk,    Unk,    Unk,    S,      Unk,     //число  
  39.         K_w,    Id,     Unk,    Unk,    Unk,    Unk,    S,      Unk,     //ключевое слово  
  40.         Unk,    Unk,    Unk,    As,     As,     Unk,    S,      Unk,     // <  
  41.         Unk,    Unk,    Unk,    Unk,    As,     Unk,    S,      Unk,     // >  
  42.         Unk,    Unk,    Unk,    Unk,    As,     Unk,    S,      Unk,     // =  
  43.         Unk,    Unk,    Unk,    Unk,    Unk,    Unk,    S,      Unk,     // <= >= ==  
  44.         Unk,    Unk,    Unk,    Unk,    Unk,    Unk,    S,      Unk,     // + -  
  45.         Unk,    Unk,    Unk,    Unk,    Unk,    Unk,    S,      Unk,     // неопознанный элемент
  46. };
  47.  
  48.  
  49.  
  50.  
  51. int collumn(char a) // вычисление столбца матрицы переходов               
  52. {
  53.     if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'))
  54.         return 0;
  55.     if (a >= '0' && a <= '9')
  56.         return 1;
  57.     if (a == '<')
  58.         return 2;
  59.     if (a == '>')
  60.         return 3;
  61.     if (a == '=')
  62.         return 4;
  63.     if (a == '+' || a == '-')
  64.         return 5;
  65.     if (a == ' ' || a == '\t' || a == '\n' || a == '\r' || a == '\0')
  66.         return 6;
  67.     return 7;
  68. }
  69.  
  70. bool equals(string& str1, char* str2)
  71. {
  72.     int lenght2 = strlen(str2);
  73.     if (lenght2 != str1.size())
  74.         return 0;
  75.     for (int i = 0; i < lenght2; ++i)
  76.         if (str1[i] != str2[i])
  77.             return 0;
  78.     return 1;
  79. }
  80.  
  81. Lex classifierLex(char* lex, State state) {
  82.     Lex lexem;
  83.     lexem.str = lex;
  84.  
  85.     if (state == K_w)
  86.     {
  87.         lexem.type = Ident;
  88.         for (int i = 0; i < 6; ++i)
  89.             if (equals(keyWord[i], lex))
  90.                 lexem.type = Keyword;
  91.     }
  92.     else if (state == L || state == R || state == W || state == As) {
  93.         lexem.type = SpecialSymbol;
  94.     }
  95.    
  96.     else if (state == Id)
  97.     {
  98.         lexem.type = Ident;
  99.     }
  100.     else if (state == Op)
  101.     {
  102.         lexem.type = Constant;
  103.     }
  104.     else if (state == Unk)
  105.     {
  106.         lexem.type = UnknownToken;
  107.     }
  108.     return lexem;
  109. }
  110.  
  111. vector<Lex>* LexAnalysis(char* str) //Функция лексического анализа
  112. {
  113.     vector<Lex>* v = new vector<Lex>();
  114.     int position = 0;                                                   //текущая позиция в строке
  115.     int start = 0;                                                          //позиция начала лексемы
  116.     State curr_state = S;                                                   //текущее состояние
  117.     Lex lexema;                                                         //текущая лексема
  118.     while (str[position] != '\0') {
  119.         if (curr_state == S)                                                    //Инициализация лексемы
  120.             start = position;
  121.  
  122.         State previous = curr_state;
  123.         curr_state = matrix[curr_state][collumn(str[position])];                        //Переход по матрице состояний
  124.  
  125.         if (curr_state == S)
  126.         {
  127.             int length = position - start;
  128.             if (length) {
  129.                 char* word = new char[length + 1];
  130.                 strncpy_s(word, length + 1, str + start, length);       //вычленение подстроки и запись в лексему
  131.                 Lex currentLex = classifierLex(word, previous);
  132.                 v->push_back(currentLex);                                       //запись лексемы в список
  133.             }
  134.         }
  135.         position++;
  136.     }
  137.  
  138.     return v;
  139. }
  140.  
  141. void print(vector<Lex>* v, LexType p)
  142. {
  143.     for (int i = 0; i < v->size(); ++i)
  144.         if (p == v->at(i).type)
  145.             cout << v->at(i).str << ' ';
  146.     cout << endl;
  147. }
  148.  
  149. int main()
  150. {
  151.     setlocale(LC_ALL, "Russian");
  152.     ifstream ifs("input.txt", ios::binary);                         //поток ввода, binary - без форматирования
  153.     if (!ifs.is_open())
  154.         return 0;
  155.     ifs.seekg(0, ios::end);
  156.     int length = ifs.tellg();                           //получаем текущую позицию курсора
  157.     char* str = new char[length + 2];                   //выделяем память под входные данные, оставляем два символа для пробела и \0
  158.     ifs.seekg(0, ios::beg);                             //перемещение указателя на начало
  159.     ifs.read(str, length);                              //читаем length символов в строку str
  160.     str[length] = ' ';
  161.     str[length + 1] = '\0';
  162.     vector<Lex>* v = LexAnalysis(str);
  163.     delete[] str;
  164.     ifs.close();
  165.     if (!v->size())
  166.     {
  167.         cout << "Файл пуст";
  168.     }
  169.     else
  170.     {
  171.         for (int i = 0; i < v->size(); ++i) {
  172.             cout << v->at(i).str << "\t- ";
  173.             if (v->at(i).type == Ident)
  174.                 cout << "Идентификатор";
  175.             else if (v->at(i).type == Constant)
  176.                 cout << "Константа";
  177.             else if (v->at(i).type == SpecialSymbol)
  178.                 cout << "Специальный символ";
  179.             else if (v->at(i).type == Keyword)
  180.                 cout << "Ключевое слово";
  181.             else if (v->at(i).type == UnknownToken)
  182.                 cout << "Некорректная лексема";
  183.             cout << endl;
  184.         }                   // таблица лексем
  185.         cout << "Идентификаторы:" << endl;
  186.         print(v, Ident);
  187.         cout << "Константы:" << endl;
  188.         print(v, Constant);
  189.         for (int i = 0; i < v->size(); ++i)
  190.             delete[] v->at(i).str;                                      //удаляем строки из памяти                                                 //очищаем вектор
  191.     }
  192.     delete v;                                                           //удаляем указатель на вектор
  193.     system("pause");
  194.     return 0;
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement