Advertisement
Leeen

2

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