Advertisement
Leeen

отяп 3

Jun 2nd, 2019
516
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.08 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. {
  13.     S,
  14.     Id,         //идентификатор
  15.     Co,         //число
  16.     K_w,        //ключевое слово
  17.     L,          // <
  18.     R,          // >
  19.     Eq,         // =
  20.     As,         // <= >= ==
  21.     Add,        // + -
  22.     Unk,        // неопознанный элемент
  23. };
  24. enum SyntaxState
  25. {
  26.     OUT,
  27.     IFS,
  28.     OPERAND,
  29.     LOGIC_OPERATOR,
  30.     THENS,
  31.     OPERATOR,
  32.     ELSES,
  33.     ENDS,
  34.     ERROR
  35. };
  36.  
  37. enum LexType { IF, THEN, ELSE, END, Contrast, Eqate, Addition, Constant, Ident, UnknownToken };
  38.  
  39. struct SyntaxResult
  40. {
  41.     SyntaxResult(bool isSuccesful)
  42.     {
  43.         this->isSuccessful = isSuccesful;
  44.     }
  45.  
  46.     char *errorMessage;
  47.     bool isSuccessful;
  48. };
  49. struct Lex
  50. {
  51.     LexType type;
  52.     char* str;
  53. };
  54.  
  55. const State LexMatrix[10][8] =
  56. {
  57.     //   a-Z     0-9     <       >      =       +/-
  58.         K_w,    Co,     L,      R,      Eq,     Co,     S,      Unk,     //старт  
  59.         Id,     Id,     Unk,    Unk,    Unk,    Unk,    S,      Unk,     //идентификатор  
  60.         Unk,    Co,     Unk,    Unk,    Unk,    Unk,    S,      Unk,     //число  
  61.         K_w,    Id,     Unk,    Unk,    Unk,    Unk,    S,      Unk,     //ключевое слово  
  62.         Unk,    Unk,    Unk,    As,     As,     Unk,    S,      Unk,     // <  
  63.         Unk,    Unk,    Unk,    Unk,    As,     Unk,    S,      Unk,     // >  
  64.         Unk,    Unk,    Unk,    Unk,    As,     Unk,    S,      Unk,     // =  
  65.         Unk,    Unk,    Unk,    Unk,    Unk,    Unk,    S,      Unk,     // <= >= ==  
  66.         Unk,    Unk,    Unk,    Unk,    Unk,    Unk,    S,      Unk,     // + -  
  67.         Unk,    Unk,    Unk,    Unk,    Unk,    Unk,    S,      Unk,     // неопознанный элемент
  68. };
  69.  
  70. const SyntaxState SyntaxMatrix[9][10] =
  71. {
  72.     //IF        THEN    ELSE    END     Contrast        Eqate           Addition    Constant    Ident       UnknownToken
  73.     IFS,        ERROR,  ERROR,  ERROR,  ERROR,          ERROR,          ERROR,      ERROR,      ERROR,      ERROR,      // OUT
  74.     ERROR,      ERROR,  ERROR,  ERROR,  ERROR,          ERROR,          ERROR,      OPERAND,    OPERAND,    ERROR,      // IF
  75.     ERROR,      THENS,  ERROR,  ERROR,  LOGIC_OPERATOR, LOGIC_OPERATOR, ERROR,      ERROR,      ERROR,      ERROR,      // OPERAND
  76.     ERROR,      ERROR,  ERROR,  ERROR,  ERROR,          ERROR,          ERROR,      OPERAND,    OPERAND,    ERROR,      // LOGIC_OPERATOR
  77.     ERROR,      ERROR,  ELSES,  ENDS,   ERROR,          ERROR,          ERROR,      OPERATOR,   OPERATOR,   ERROR,      // THEN
  78.     ERROR,      ERROR,  ELSES,  ENDS,   OPERATOR,       OPERATOR,       OPERATOR,   OPERATOR,   OPERATOR,   ERROR,      // OPERATOR
  79.     ERROR,      ERROR,  ERROR,  ERROR,  ERROR,          ERROR,          ERROR,      OPERATOR,   OPERATOR,   ERROR,      // ELSE
  80.     IFS,        ERROR,  ERROR,  ERROR,  ERROR,          ERROR,          ERROR,      ERROR,      ERROR,      ERROR,      // END
  81.     IFS,        ERROR,  ERROR,  ERROR,  ERROR,          ERROR,          ERROR,      ERROR,      ERROR,      ERROR       // END
  82. };
  83.  
  84. int LexCollumn(char a) // вычисление столбца матрицы переходов            
  85. {
  86.     if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'))
  87.         return 0;
  88.     if (a >= '0' && a <= '9')
  89.         return 1;
  90.     if (a == '<')
  91.         return 2;
  92.     if (a == '>')
  93.         return 3;
  94.     if (a == '=')
  95.         return 4;
  96.     if (a == '+' || a == '-')
  97.         return 5;
  98.     if (a == ' ' || a == '\t' || a == '\n' || a == '\r' || a == '\0')
  99.         return 6;
  100.     return 7;
  101. }
  102.  
  103.  
  104. bool equals(string& str1, char* str2)
  105. {
  106.     int lenght2 = strlen(str2);
  107.     if (lenght2 != str1.size())
  108.         return 0;
  109.     for (int i = 0; i < lenght2; ++i)
  110.         if (str1[i] != str2[i])
  111.             return 0;
  112.     return 1;
  113. }
  114.  
  115. Lex classifierLex(char* lex, State state) {
  116.     Lex lexem;
  117.     lexem.str = lex;
  118.  
  119.     if (state == K_w)
  120.     {
  121.         lexem.type = Ident;
  122.  
  123.         if (equals(keyWord[0], lex))
  124.             lexem.type = IF;
  125.         if (equals(keyWord[1], lex))
  126.             lexem.type = THEN;
  127.         if (equals(keyWord[2], lex))
  128.             lexem.type = ELSE;
  129.         if (equals(keyWord[3], lex))
  130.             lexem.type = END;
  131.  
  132.  
  133.     }
  134.     else if (state == L || state == R || state == As) {
  135.         lexem.type = Contrast;
  136.     }
  137.  
  138.     else if (state == Eq) {
  139.         lexem.type = Eqate;
  140.     }
  141.  
  142.     else if (state == Add) {
  143.         lexem.type = Addition;
  144.     }
  145.  
  146.     else if (state == Id)
  147.     {
  148.         lexem.type = Ident;
  149.     }
  150.     else if (state == Co)
  151.     {
  152.         lexem.type = Constant;
  153.     }
  154.     else if (state == Unk)
  155.     {
  156.         lexem.type = UnknownToken;
  157.     }
  158.     return lexem;
  159. }
  160.  
  161. vector<Lex>* LexAnalysis(char* str) //Функция лексического анализа
  162. {
  163.     vector<Lex>* v = new vector<Lex>();
  164.     int position = 0;                                                   //текущая позиция в строке
  165.     int start = 0;                                                          //позиция начала лексемы
  166.     State curr_state = S;                                                   //текущее состояние
  167.     Lex lexema;                                                         //текущая лексема
  168.     while (str[position] != '\0') {
  169.         if (curr_state == S)                                                    //Инициализация лексемы
  170.             start = position;
  171.  
  172.         State previous = curr_state;
  173.         curr_state = LexMatrix[curr_state][LexCollumn(str[position])];                        //Переход по матрице состояний
  174.  
  175.         if (curr_state == S)
  176.         {
  177.             int length = position - start;
  178.             if (length)
  179.             {
  180.                 char* word = new char[length + 1];
  181.                 strncpy_s(word, length + 1, str + start, length);       //вычленение подстроки и запись в лексему
  182.                 Lex currentLex = classifierLex(word, previous);
  183.                 v->push_back(currentLex);                                       //запись лексемы в список
  184.             }
  185.         }
  186.         position++;
  187.     }
  188.  
  189.     return v;
  190. }
  191.  
  192. char* getStateName(SyntaxState state) {
  193.     char* name = new char();
  194.     switch (state)
  195.     {
  196.     case 0:name = (char*)"ничего"; break;
  197.     case 1:name = (char*)"if"; break;
  198.     case 2:name = (char*)"<констранта или идентификатор>"; break;
  199.     case 3:name = (char*)"<логический оператор>"; break;
  200.     case 4:name = (char*)"then"; break;
  201.     case 5:name = (char*)"<оператор>"; break;
  202.     case 6:name = (char*)"else"; break;
  203.     case 7:name = (char*)"end"; break;
  204.     }
  205.     return name;
  206. }
  207.  
  208. void getErrorMessage(SyntaxState prev, Lex current) {
  209.     cout << "Введено: " << current.str;
  210.     cout << " но требовалось: ";
  211.     for (int i = 0; i < 9; ++i)
  212.     {
  213.         SyntaxState state = SyntaxMatrix[prev][i];
  214.         if (state != ERROR)
  215.         {
  216.             cout << getStateName(state) << " ";
  217.         }
  218.     }
  219.     cout << endl;
  220. }
  221.  
  222. SyntaxState getStatetByTpe(LexType t) {
  223.     switch (t)
  224.     {
  225.     case IF: return IFS;
  226.     case THEN: return THENS;
  227.     case ELSE: return ELSES;
  228.     case END: return ENDS;
  229.     case Contrast: return LOGIC_OPERATOR;
  230.     case Eqate: return OPERATOR;
  231.     case Addition: return OPERATOR;
  232.     case Constant: return OPERAND;
  233.     case Ident: return OPERAND;
  234.     case UnknownToken: return ERROR;
  235.     }
  236. }
  237.  
  238. void SyntaxAnalysis(vector<Lex> *lexems) {
  239.     SyntaxState currentState = OUT;
  240.     for (int i = 0; i < lexems->size(); ++i)
  241.     {
  242.         SyntaxState previous = currentState;
  243.         currentState = SyntaxMatrix[currentState][lexems->at(i).type];
  244.         if (currentState == ERROR)
  245.         {
  246.             int g = i;
  247.             getErrorMessage(previous, lexems->at(g));
  248.             while (currentState != IFS && g < lexems->size())
  249.             {
  250.                 currentState = SyntaxMatrix[currentState][lexems->at(g).type];
  251.                 g++;
  252.             }
  253.         }
  254.         if (currentState == ENDS) {
  255.             cout << "+" << endl;
  256.         }
  257.     }
  258. }
  259.  
  260. char* inputFileText() {
  261.     ifstream fin("input.txt", ios::binary);
  262.  
  263.     char* text;
  264.     if (!fin)
  265.         return inputFileText();
  266.     else
  267.     {
  268.         fin.seekg(0, ios::end);
  269.         int length = fin.tellg();
  270.         char* text = new char[length + 2];
  271.         fin.seekg(0, ios::beg);
  272.         fin.read(text, length);
  273.         text[length] = ' ';
  274.         text[length + 1] = '\0';
  275.         return text;
  276.     }
  277. }
  278. int main()
  279. {
  280.     setlocale(LC_ALL, "Russian");
  281.     char *text = inputFileText();
  282.     vector<Lex>* lexems = LexAnalysis(text);
  283.     SyntaxAnalysis(lexems);
  284.  
  285.     system("pause");
  286.     return 0;
  287. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement