Advertisement
Leeen

отяп 2

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