Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 42.38 KB | None | 0 0
  1. #include "analysing.h"
  2. #include "input.h"
  3. #include "coloring.h"
  4. #include "token_processing.h"
  5. #include "counting.h"
  6. #include "token.h"
  7.  
  8.  
  9. /* keywords_amount for keyword_analyser func */
  10. enum {KEYWORDS_AMOUNT = 14, KEYWORDS_MAX_LENGTH = 14};
  11.  
  12. char *keywords[KEYWORDS_AMOUNT] =
  13.         {
  14.                 "unsigned",
  15.                 "void",
  16.                 "volatile",
  17.                 "while",
  18.                 "_Alignas",
  19.                 "_Alignof",
  20.                 "_Atomic",
  21.                 "_Bool",
  22.                 "_Complex",
  23.                 "_Generic",
  24.                 "_Imaginary",
  25.                 "_Noreturn",
  26.                 "_Static_assert",
  27.                 "_Thread_local"
  28.         };
  29.  
  30.  
  31. /* punctuators_amount for punctuator_analyser func */
  32. enum {PUNCTUATORS_AMOUNT = 33, PUNCTUATOR_MAX_LENGTH = 4};
  33.  
  34. char *punctuators[PUNCTUATORS_AMOUNT] =
  35.         {
  36.                 "<",
  37.                 "<<",
  38.                 "<=",
  39.                 "<<=",
  40.                 ">",
  41.                 ">>",
  42.                 ">=",
  43.                 ">>=",
  44.                 "=",
  45.                 "==",
  46.                 "|",
  47.                 "||",
  48.                 "|=",
  49.                 "&",
  50.                 "&&",
  51.                 "&=",
  52.                 "!",
  53.                 "!=",
  54.                 "*",
  55.                 "*=",
  56.                 "+",
  57.                 "++",
  58.                 "+=",
  59.                 "^",
  60.                 "^=",
  61.                 "/",
  62.                 "/=",
  63.                 "%",
  64.                 "%=",
  65.                 "-",
  66.                 "--",
  67.                 "-=",
  68.                 "~",
  69.         };
  70.  
  71.  
  72.  
  73.  /* COMPONENT-FUNCTIONS BLOCK */
  74.  
  75.  static int
  76.  is_white_space(int symb) {
  77.      /* DESCRIPTION:
  78.   * is_white_space() checks symb, if it is white_space character or not
  79.   * RETURN VALUES:
  80.      * 0, if it is not white_space
  81.      * 1  else
  82.  */
  83.      /* 0, if it is not white_space
  84.       * 1  else
  85.       */
  86.      enum { WHITE_SPACE_AMOUNT = 6 };
  87.      const char WHITE_SPACE_ARRAY[WHITE_SPACE_AMOUNT] = {' ', '\t', '\n', '\v', '\f', '\r'};
  88.      for (int i=0; i < WHITE_SPACE_AMOUNT; i++) {
  89.          if (symb == WHITE_SPACE_ARRAY[i]) {
  90.              return 1;
  91.          }
  92.      }
  93.      return 0;
  94.  }
  95.  
  96. static int
  97. is_nondigit(int symb) {
  98.     /*
  99. * RETURN VALUES:
  100.    * 1, if symb is nondigit
  101.    * 0, else
  102. */
  103.     if ((isalpha(symb)) || (symb == '_')) return 1;
  104.     else return 0;
  105. }
  106.  
  107.  
  108.  
  109.  
  110. static Token *
  111. number_analyser() {
  112.     /*
  113.  * DESCRIPTION:
  114.  * number_analyser() attempts to read symbols from stdin until EOF
  115.  * if first digit has reached, then saves it in Token->buffer, and changes Token->type
  116.  * after first digit was found, if current symbol != digit, then saves it in Token->buffer, and changes Token->type
  117.  * "standard color key".
  118.  * RETURN VALUES:
  119.      * 0 - if digit was found
  120.      * 1 - if EOF was found
  121.      * 2 - if some kind of error was found
  122.      * 3 - if digit was not found
  123. */
  124.     char curr_symb, is_first_digit = 1;
  125.     size_t buffer_size = 0;
  126.     Token *number_token = calloc(1, sizeof(*number_token));
  127.     char *buffer = calloc(1, sizeof(*buffer));
  128.     while ((fread(&curr_symb, 1, sizeof(char), input_file)) > 0) {
  129.         buffer_size++;
  130.         if (isdigit(curr_symb)) {
  131.             if (is_first_digit) {
  132.                 is_first_digit = 0;
  133.             }
  134.             buffer = realloc(buffer, buffer_size);
  135.             buffer[buffer_size - 1] = (char) curr_symb;
  136.         } else {
  137.             if (!is_first_digit) {
  138.                 if (fseek(input_file, -1, SEEK_CUR) == -1) {
  139.                     number_token->type = -2;
  140.                     free(buffer);
  141.                     return number_token;
  142.                 }
  143.                 buffer = realloc(buffer, buffer_size);
  144.                 buffer[buffer_size-1] = '\0';
  145.                 number_token->buffer = calloc(buffer_size, sizeof(char));
  146.                 strncpy(number_token->buffer, buffer, buffer_size);
  147.                 number_token->type = NUMBER;
  148.                 free(buffer);
  149.                 return number_token;
  150.             }
  151.             if (fseek(input_file, -1, SEEK_CUR) == -1) {
  152.                 number_token->type = -2;
  153.                 free(buffer);
  154.                 return number_token;
  155.             }
  156.             number_token->type = -3;
  157.             free(buffer);
  158.             return number_token;
  159.         }
  160.     }
  161.      buffer_size++;
  162.      buffer = realloc(buffer, buffer_size);
  163.      buffer[buffer_size-1] = '\0';
  164.      number_token->buffer = calloc(buffer_size, sizeof(char));
  165.      strncpy(number_token->buffer, buffer, buffer_size);
  166.      number_token->type = NUMBER;
  167.      free(buffer);
  168.     return number_token;
  169. }
  170.  
  171.  
  172. static Token *
  173. comment_analyser() {
  174.     /*
  175.  * DESCRIPTION:
  176.     * comment_analyser() attempts to read symbols from stdin until EOF
  177.     * if it has found "comment token(or pattern)", then saves it in Token->buffer, and changes Token->type
  178.  * RETURN VALUES:
  179.     * 0, if somekind of comment was found
  180.     * 1, if EOF was reached
  181.     * 2, if somekind of error was found
  182.     * 3, if comment was not found
  183. */
  184.  
  185.     char curr_symb;
  186.     int state1 = 0, state2 = 0;
  187.     size_t buffer_size = 0;
  188.     char *buffer = calloc(1, sizeof(buffer));
  189.     Token *comment_token = calloc(1, sizeof(*comment_token));
  190.     while ((fread(&curr_symb, 1, sizeof(char), input_file)) > 0) {
  191.         buffer_size++;
  192.         if ((curr_symb == '/') && (state1 == 0) && (state2 == 0)) {
  193.             state1 = 1;
  194.             state2 = 1;
  195.             continue;
  196.         } else if ((state1 == 0) && (state2 == 0)) {
  197.             if (fseek(input_file, -1, SEEK_CUR) == -1) {
  198.                 comment_token->type = -2;
  199.                 free(buffer);
  200.                 return comment_token;
  201.             }
  202.             comment_token->type = -3;
  203.             free(buffer);
  204.             return comment_token;
  205.         }
  206.         if ((state1 == 1) || (state2 == 1)) {
  207.             if ((curr_symb != '/') && (curr_symb != '*')) {
  208.                 state1 = 0;
  209.                 state2 = 0;
  210.                 if (fseek(input_file, -buffer_size, SEEK_CUR) == -1) {
  211.                     comment_token->type = -2;
  212.                     free(buffer);
  213.                     return comment_token;
  214.                 }
  215.                 comment_token->type = -3;
  216.                 free(buffer);
  217.                 return comment_token;
  218.             }
  219.             else {
  220.                 if (curr_symb == '/') {
  221.                     state1 = 2;
  222.                     state2 = 0;
  223.                     buffer = realloc(buffer, buffer_size);
  224.                     buffer[buffer_size - 2] = '/';
  225.                     buffer[buffer_size - 1] = '/';
  226.                 }
  227.                 else {
  228.                     state1 = 0;
  229.                     state2 = 2;
  230.                     buffer = realloc(buffer, buffer_size);
  231.                     buffer[buffer_size - 2] = '/';
  232.                     buffer[buffer_size - 1] = '*';
  233.                 }
  234.             }
  235.             continue;
  236.         }
  237.  
  238.         if (state1 == 2) {
  239.             if (curr_symb == '\n') {
  240.                 state1 = 0;
  241.                 if (fseek(input_file, -1, SEEK_CUR) == -1) {
  242.                     comment_token->type = -2;
  243.                     free(buffer);
  244.                     return comment_token;
  245.                 }
  246.                 buffer = realloc(buffer, buffer_size);
  247.                 buffer[buffer_size-1] = '\0';
  248.                 comment_token->buffer = calloc(buffer_size, sizeof(char));
  249.                 strncpy(comment_token->buffer, buffer, buffer_size);
  250.                 free(buffer);
  251.                 comment_token->type = COMMENT;
  252.                 return comment_token;
  253.             } else if (curr_symb == '\\') {
  254.                 state1 = 3;
  255.                 buffer = realloc(buffer, buffer_size);
  256.                 buffer[buffer_size - 1] = (char) curr_symb;
  257.             } else {
  258.                 buffer = realloc(buffer, buffer_size);
  259.                 buffer[buffer_size - 1] = (char) curr_symb;
  260.             }
  261.             continue;
  262.         }
  263.         if (state2 == 2) {
  264.             if (curr_symb == '*') {
  265.                 state2 = 3;
  266.                 state1 = -1;
  267.             }
  268.             buffer = realloc(buffer, buffer_size);
  269.             buffer[buffer_size - 1] = (char) curr_symb;
  270.             continue;
  271.         }
  272.         if (state1 == 3) {
  273.             state1 = 2;
  274.             buffer = realloc(buffer, buffer_size);
  275.             buffer[buffer_size - 1] = (char) curr_symb;
  276.             continue;
  277.         }
  278.         if (state2 == 3) {
  279.             if (curr_symb == '/') {
  280.                 buffer = realloc(buffer, buffer_size);
  281.                 buffer[buffer_size - 1] = '/';
  282.                 state2 = 0;
  283.                 buffer_size++;
  284.                 buffer = realloc(buffer, buffer_size);
  285.                 buffer[buffer_size-1] = '\0';
  286.                 comment_token->buffer = calloc(buffer_size, sizeof(char));
  287.                 strncpy(comment_token->buffer, buffer, buffer_size);
  288.                 comment_token->type = COMMENT;
  289.                 free(buffer);
  290.                 return comment_token;
  291.             }
  292.             if (curr_symb != '*') {
  293.                 state2 = 2;
  294.             }
  295.             buffer = realloc(buffer, buffer_size);
  296.             buffer[buffer_size - 1] = (char) curr_symb;
  297.             continue;
  298.         }
  299.         if (fseek(input_file, -1, SEEK_CUR) == -1) {
  300.             comment_token->type = -2;
  301.             free(buffer);
  302.             return comment_token;
  303.         }
  304.         comment_token->type = -3;
  305.         free(buffer);
  306.         return comment_token;
  307.     }
  308.     if (buffer_size == 0) {
  309.         comment_token->type = -3;
  310.         return comment_token;
  311.     }
  312.     if (buffer_size < 2) {
  313.         if (fseek(input_file, -buffer_size, SEEK_CUR) == -1) {
  314.             comment_token->type = -2;
  315.             free(buffer);
  316.             return comment_token;
  317.         }
  318.         comment_token->type = -3;
  319.         free(buffer);
  320.         return comment_token;
  321.     }
  322.     buffer_size++;
  323.     buffer = realloc(buffer, buffer_size);
  324.     buffer[buffer_size-1] = '\0';
  325.     comment_token->buffer = calloc(buffer_size, sizeof(char));
  326.     strncpy(comment_token->buffer, buffer, buffer_size);
  327.     comment_token->type = COMMENT;
  328.     free(buffer);
  329.     return comment_token;
  330. }
  331.  
  332.  
  333. static Token *
  334. punctuator_analyser(char **PUNCTUATORS, int PUNCTUATOR_MAX_LENGTH) {
  335.     /*
  336.  * DESCRIPTION:
  337.     * punctuator_analyser() attempts to read symbols from stdin until EOF
  338.     * it uses PUNCTUATORS array, which contains all available pattern of punctuators
  339.     * if it has found "punctuator token(or pattern)" then saved it in Token->buffer, and changes Token->type
  340.  * RETURN VALUES:
  341.      * 0, if punctuator was found and printed
  342.      * 1, if EOF was reached
  343.      * 2, if somekind of error was found
  344.      * 3, if no punctuator was found
  345. */
  346.     size_t buffer_size = 0;
  347.     char *buffer = calloc(PUNCTUATOR_MAX_LENGTH, sizeof(buffer));
  348.     Token *punctuator_token = calloc(1, sizeof(*punctuator_token));
  349.     buffer_size = fread(buffer, sizeof(char), PUNCTUATOR_MAX_LENGTH, input_file);
  350.     if (buffer_size == 0) {
  351.         punctuator_token->type = -3;
  352.         free(buffer);
  353.         if (fseek(input_file, -buffer_size, SEEK_CUR) == -1) {
  354.             punctuator_token->type = -2;
  355.             return punctuator_token;
  356.         }
  357.         return punctuator_token;
  358.     }
  359.     int punctuator_curr_length = buffer_size;
  360.     for (int i = 0; i < punctuator_curr_length; i++) {
  361.         for (int k = 0; k < PUNCTUATORS_AMOUNT; k++) {
  362.             if (strncmp(PUNCTUATORS[k], buffer, (size_t) punctuator_curr_length - i) == 0) {
  363.                 buffer_size = punctuator_curr_length - i;
  364.                 if (fseek(input_file, -punctuator_curr_length + buffer_size, SEEK_CUR) == -1) {
  365.                     punctuator_token->type = -2;
  366.                     return punctuator_token;
  367.                 }
  368.                 buffer_size++;
  369.                 buffer = realloc(buffer, buffer_size);
  370.                 buffer[buffer_size - 1] = '\0';
  371.                 punctuator_token->buffer = calloc(buffer_size, sizeof(char));
  372.                 strncpy(punctuator_token->buffer, buffer, buffer_size);
  373.                 punctuator_token->type = PUNCTUATOR;
  374.                 free(buffer);
  375.                 return punctuator_token;
  376.             }
  377.         }
  378.     }
  379.         punctuator_token->type = -3;
  380.         free(buffer);
  381.         if (fseek(input_file, -buffer_size, SEEK_CUR) == -1) {
  382.             punctuator_token->type = -2;
  383.             return punctuator_token;
  384.         }
  385.         return punctuator_token;
  386. }
  387.  
  388.  
  389. static Token *
  390. keyword_analyser(char **KEYWORDS, int KEYWORDS_MAX_LENGTH) {
  391.     /* DESCRIPTION:
  392.     * keyword_analyser() attempts to read symbols from stdin until EOF
  393.     * it uses KEYWORDS array, which contains all available pattern of punctuators
  394.     * if it has found "keyword token(or pattern)" then saves it in Token->buffer, and changes Token->type
  395.  * RETURN VALUES:
  396.      * 0, if keyword was found and printed
  397.      * 1, if EOF was reached
  398.      * 2, if somekind of error was found
  399.      * 3, if no keyword was found
  400.   Important:
  401.     * at the end of keyword must be at least one white space, if keyword ends without white spaces - don't print
  402.   EXAMPLE:
  403.      * 1)*EOF* - end of file
  404.      * input:_Imaginary*EOF*
  405.      * output:
  406.      * 2)*WHITESPACE* - white space symbol
  407.      * input:_Imaginary*WHITESPACE**EOF*
  408.      * output:_Imaginary*WHITESPACE*
  409.  */
  410.  
  411.     short int indexes[KEYWORDS_AMOUNT];          /* 1, if start of keyword matches with KEYWORDS i-th row
  412.                                                     0, else*/
  413.     for (int i=0; i < KEYWORDS_AMOUNT; i++) {
  414.         indexes[i] = 1;
  415.     }
  416.     int keyword_to_print[KEYWORDS_MAX_LENGTH];
  417.     for (int i=0; i < KEYWORDS_MAX_LENGTH; i++) {
  418.         keyword_to_print[i] = 0;
  419.     }
  420.     char curr_symb;
  421.     char is_first_keyword = 1;
  422.     char is_at_least_one_full_keyword = 0;
  423.     char was_printed = 0; // if on symb_was_read-step one symbol of keyword was printed
  424.     int amount_symb_was_read = 0;
  425.     int length_of_current_keyword = 0;
  426.     int is_indexes_array_of_zeros = 0;
  427.     size_t buffer_size = 0;
  428.     char *buffer = calloc(1, sizeof(buffer));
  429.     Token *keyword_token = calloc(1, sizeof(*keyword_token));
  430.     for (; amount_symb_was_read < KEYWORDS_MAX_LENGTH + 1; amount_symb_was_read++) {
  431.         is_indexes_array_of_zeros = 1; // for check if there is at leats one 1
  432.         for (int i = 0; i < KEYWORDS_AMOUNT; i++) {
  433.             if (indexes[i] != 0) {
  434.                 is_indexes_array_of_zeros = 0;
  435.             }
  436.         }
  437.         if (is_indexes_array_of_zeros) {
  438.             if (fseek(input_file, -amount_symb_was_read, SEEK_CUR) == -1) {
  439.                 keyword_token->type = -2;
  440.                 free(buffer);
  441.                 return keyword_token;
  442.             }
  443.             keyword_token->type = -3;
  444.             free(buffer);
  445.             return keyword_token;
  446.         }
  447.         was_printed = 0;
  448.         if ((fread(&curr_symb, 1, sizeof(char), input_file)) == 0) {
  449.             if (is_at_least_one_full_keyword) {
  450.                 buffer_size = length_of_current_keyword;
  451.                 buffer = realloc(buffer, length_of_current_keyword);
  452.                 for (int i = 0; i < length_of_current_keyword; i++) {
  453.                     buffer[i] = (char) keyword_to_print[i];
  454.                 }
  455.             } else {
  456.  
  457.             }
  458.             if (fseek(input_file, -amount_symb_was_read + length_of_current_keyword, SEEK_CUR) == -1) {
  459.                 keyword_token->type = -2;
  460.                 free(buffer);
  461.                 return keyword_token;
  462.             }
  463.             buffer_size++;
  464.             buffer = realloc(buffer, buffer_size);
  465.             buffer[buffer_size-1] = '\0';
  466.             keyword_token->buffer = calloc(buffer_size, sizeof(char));
  467.             strncpy(keyword_token->buffer, buffer, buffer_size);
  468.             keyword_token->type = KEYWORD;
  469.             free(buffer);
  470.             return keyword_token;
  471.         }
  472.         for (int i=0; i < KEYWORDS_AMOUNT; i++) {
  473.             int curr_length = strlen(KEYWORDS[i]);
  474.             if ((KEYWORDS[i][amount_symb_was_read] == curr_symb) && (curr_length >= amount_symb_was_read) && (indexes[i] == 1)) {
  475.                 if ((amount_symb_was_read == 0) && (is_first_keyword)) {
  476.                     is_first_keyword = 0;
  477.                 }
  478.                 if (strlen(KEYWORDS[i]) == (amount_symb_was_read + 1)) {
  479.                     is_at_least_one_full_keyword = 1;
  480.                 }
  481.                 if (!was_printed) {
  482.                     keyword_to_print[length_of_current_keyword] = curr_symb;
  483.                     length_of_current_keyword++;
  484.                     was_printed = 1;
  485.                 }
  486.             } else {
  487.                 if ((is_white_space(curr_symb)) && (curr_length >= amount_symb_was_read) && (indexes[i] != 0)) {
  488.                     buffer_size = length_of_current_keyword;
  489.                     buffer = realloc(buffer, buffer_size);
  490.                     for (int k = 0; k < length_of_current_keyword; k++) {
  491.                         buffer[k] = (char) keyword_to_print[k];
  492.                     }
  493.                     if (fseek(input_file, -1, SEEK_CUR) == -1) {
  494.                         keyword_token->type = -2;
  495.                         free(buffer);
  496.                         return keyword_token;
  497.                     }
  498.                     buffer_size++;
  499.                     buffer = realloc(buffer, buffer_size);
  500.                     buffer[buffer_size-1] = '\0';
  501.                     keyword_token->buffer = calloc(buffer_size, sizeof(char));
  502.                     strncpy(keyword_token->buffer, buffer, buffer_size);
  503.                     keyword_token->type = KEYWORD;
  504.                     free(buffer);
  505.                     return keyword_token;
  506.                 }
  507.                 indexes[i] = 0;
  508.             }
  509.         }
  510.     }
  511.     if (fseek(input_file, -amount_symb_was_read + length_of_current_keyword, SEEK_CUR) == -1) {
  512.         keyword_token->type = -2;
  513.         free(buffer);
  514.         return keyword_token;
  515.     }
  516.     if (buffer_size == 0) {
  517.         keyword_token->type = -3;
  518.         free(buffer);
  519.         return keyword_token;
  520.     }
  521.     return NULL;
  522. }
  523.  
  524.  
  525.  
  526.  
  527. static Token *
  528. identifier_analyser() {
  529.     /* DESCRIPTION:
  530.  * identifier_analyser() attempts to read symbols from stdin until EOF
  531.  * if it has found "identifier token(or pattern)" then saves it in Token->buffer, and changes Token->type
  532.  *
  533.  * RETURN VALUES:
  534.     * 0, if identifier was found and printed
  535.     * 1, if EOF was reached
  536.     * 2, if somekind of error was found
  537.     * 3, if no identifier was found
  538. */
  539.  
  540.     char curr_symb;
  541.     int amount_symb_was_read = 0;
  542.     int state1 = 0;
  543.     Token *identifier_token = calloc(1, sizeof(*identifier_token));
  544.     char *buffer = calloc(1, sizeof(*buffer));
  545.     while ((fread(&curr_symb, 1, sizeof(char), input_file)) > 0) {
  546.         amount_symb_was_read++;
  547.         if (state1 == 0) {
  548.             if (is_nondigit(curr_symb)) {
  549.                 state1 = 1;
  550.                 continue;
  551.             } else {
  552.                 if (fseek(input_file, -amount_symb_was_read, SEEK_CUR) == -1) {
  553.                     identifier_token->type = -2;
  554.                     free(buffer);
  555.                     return identifier_token;
  556.                 }
  557.                 identifier_token->type = -3;
  558.                 free(buffer);
  559.                 return identifier_token;
  560.             }
  561.         }
  562.         if (state1 == 1) {
  563.             if ((is_nondigit(curr_symb)) || (isdigit(curr_symb)))  {
  564.  
  565.             } else {
  566.                 if (fseek(input_file, -amount_symb_was_read, SEEK_CUR) == -1) {
  567.                     identifier_token->type = -2;
  568.                     free(buffer);
  569.                     return identifier_token;
  570.                 }
  571.                 identifier_token->buffer = calloc(amount_symb_was_read, sizeof(char));
  572.                 identifier_token->type = IDENTIFIER;
  573.                 for(int i = 0; i < amount_symb_was_read-1; i++) {
  574.                     fread(&identifier_token->buffer[i], 1, sizeof(char), input_file);
  575.                 }
  576.                 identifier_token->buffer[amount_symb_was_read-1] = '\0';
  577.                 free(buffer);
  578.                 return identifier_token;
  579.             }
  580.         }
  581.     }
  582.     if (fseek(input_file, -amount_symb_was_read, SEEK_CUR) == -1) {
  583.         identifier_token->type = -2;
  584.         free(buffer);
  585.         return identifier_token;
  586.     }
  587.     if (state1 == 1) {
  588.         identifier_token->buffer = calloc((size_t) amount_symb_was_read + 1, sizeof(char));
  589.         identifier_token->type = IDENTIFIER;
  590.         for (int i = 0; i < amount_symb_was_read; i++) {
  591.             fread(&identifier_token->buffer[i], 1, sizeof(char), input_file);
  592.         }
  593.         identifier_token->buffer[amount_symb_was_read] = '\0';
  594.         free(buffer);
  595.         return identifier_token;
  596.     }
  597.     if (amount_symb_was_read == 0) {
  598.         identifier_token->type = -3;
  599.         free(buffer);
  600.         return identifier_token;
  601.     }
  602.     free(buffer);
  603.     identifier_token->type = -3;
  604.     return identifier_token;
  605. }
  606.  
  607.  
  608. static int
  609. is_hexadecimal_digit(int symb) {
  610.     /* DESCRIPTION:
  611.         * is_hexadecimal_digit checks symb, if it is hexadecimal digit or not
  612.     * RETURN VALUES:
  613.         * 0, if it is not white_space
  614.         * 1,  else
  615.     */
  616.     enum {HEXADECIMAL_DIGITS_AMOUNT = 22};
  617.     const char HEXADECIMAL_DIGITS[HEXADECIMAL_DIGITS_AMOUNT] = {
  618.             '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a',
  619.             'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'
  620.     };
  621.     for (int i=0; i < HEXADECIMAL_DIGITS_AMOUNT; i++) {
  622.         if (symb == HEXADECIMAL_DIGITS[i]) {
  623.             return 1;
  624.         }
  625.     }
  626.     return 0;
  627. }
  628.  
  629.  
  630. static Token *
  631. ucn_analyser() {
  632.     /* DESCRIPTION:
  633.  * ucn_analyser() attempts to read symbols from stdin until EOF
  634.  * if it has found "universal character token(or pattern)" then saves it in Token->buffer, and changes Token->type
  635.  *
  636.  * RETURN VALUES:
  637.     * 0, if Universal character name was found and printed
  638.     * 1, if EOF was reached
  639.     * 2, if somekind of error was found
  640.     * 3, if no Universal character name was found
  641. */
  642.     char curr_symb;
  643.     int amount_symb_was_read = 0;
  644.     int print_u_or_U = 'u'; // if 'u' - print u, if 1 - print 'U'
  645.     int state1 = 0;
  646.     Token *ucn_token = calloc(1, sizeof(*ucn_token));
  647.     char *buffer = calloc(1, sizeof(char));
  648.     while ((fread(&curr_symb, 1, sizeof(char), input_file)) > 0) {
  649.         amount_symb_was_read++;
  650.         if (state1 == 0) {
  651.             if (curr_symb == '\\') {
  652.                 state1 = 1;
  653.                 continue;
  654.             } else {
  655.                 if (fseek(input_file, -amount_symb_was_read, SEEK_CUR) == -1) {
  656.                     ucn_token->type = -2;
  657.                     free(buffer);
  658.                     return ucn_token;
  659.                 }
  660.                 ucn_token->type = -3;
  661.                 free(buffer);
  662.                 return ucn_token;
  663.             }
  664.         }
  665.         if (state1 == 1) {
  666.             if (curr_symb == 'u') {
  667.                 print_u_or_U = 'u';
  668.                 state1 = 2;
  669.                 continue;
  670.             }
  671.             if (curr_symb == 'U') {
  672.                 print_u_or_U = 1;
  673.                 state1 = 2;
  674.                 continue;
  675.             }
  676.             if (fseek(input_file, -amount_symb_was_read, SEEK_CUR) == -1) {
  677.                 ucn_token->type = -2;
  678.                 free(buffer);
  679.                 return ucn_token;
  680.             }
  681.             ucn_token->type = -3;
  682.             free(buffer);
  683.             return ucn_token;
  684.         }
  685.         if (state1 == 2) {
  686.             if (is_hexadecimal_digit(curr_symb)) {
  687.                 buffer = realloc(buffer, amount_symb_was_read);
  688.                 buffer[amount_symb_was_read - 3] = '\\';
  689.                 buffer[amount_symb_was_read - 2] = (char) print_u_or_U;
  690.                 buffer[amount_symb_was_read - 1] = curr_symb;
  691.                 state1 = 3;
  692.                 continue;
  693.             } else {
  694.                 if (fseek(input_file, -amount_symb_was_read, SEEK_CUR) == -1) {
  695.                     ucn_token->type = -2;
  696.                     free(buffer);
  697.                     return ucn_token;
  698.                 }
  699.                 ucn_token->type = -3;
  700.                 free(buffer);
  701.                 return ucn_token;
  702.             }
  703.         }
  704.         if (state1 == 3) {
  705.             if (is_hexadecimal_digit(curr_symb)) {
  706.                 buffer = realloc(buffer, amount_symb_was_read);
  707.                 buffer[amount_symb_was_read - 1] = curr_symb;
  708.             } else {
  709.                 if (fseek(input_file, -1, SEEK_CUR) == -1) {
  710.                     ucn_token->type = -2;
  711.                     free(buffer);
  712.                     return ucn_token;
  713.                 }
  714.                 buffer = realloc(buffer, amount_symb_was_read);
  715.                 buffer[amount_symb_was_read - 1] = '\0';
  716.                 ucn_token->buffer = calloc(amount_symb_was_read, sizeof(char));
  717.                 strncpy(ucn_token->buffer, buffer, amount_symb_was_read);
  718.                 ucn_token->type = 8;
  719.                 free(buffer);
  720.                 return ucn_token;
  721.             }
  722.         }
  723.     }
  724.     amount_symb_was_read++;
  725.     buffer = realloc(buffer, amount_symb_was_read);
  726.     buffer[amount_symb_was_read - 1] = '\0';
  727.     ucn_token->buffer = calloc((size_t) amount_symb_was_read, sizeof(char));
  728.     strncpy(ucn_token->buffer, buffer, amount_symb_was_read);
  729.     ucn_token->type = -3;
  730.     free(buffer);
  731.     return ucn_token;
  732. }
  733.  
  734.  
  735. static int
  736. white_space_print_skip() {
  737.     /* DESCRIPTION:
  738.  * white_space_print_skip() attempts to read one symbol from stdin
  739.  * and checks if it is white_space character, then prints it
  740.  * RETURN VALUES:
  741.     * 0, if this symb is white_space
  742.     * 1, if EOF
  743.     * 2, if some kind of error was found
  744.     * 3, if symb is not white_space
  745. */
  746.     /* 0, if this symb is white_space
  747.      * 1, if EOF
  748.      * 2, if some kind of error was found
  749.      * 3, if symb is not white_space*/
  750.     char curr_symb;
  751.     if ((fread(&curr_symb, 1, sizeof(char), input_file)) > 0) {
  752.         if (!is_white_space(curr_symb)) {
  753.             if (fseek(input_file, -1, SEEK_CUR) == -1) {
  754.                 return 2;
  755.             }
  756.             return 3;
  757.         } else {
  758.             putchar(curr_symb);
  759.         }
  760.     } else return 1;
  761.     return 0;
  762. }
  763.  
  764.  
  765.  
  766. static Token *
  767. string_literal_analyser() {
  768.     /* DESCRIPTION:
  769.     * string_literal_analyser() attempts to read symbols from stdin until EOF
  770.     * if it has found "string_literal token(or pattern)" then saves it in Token->buffer, and changes Token->type
  771.  * RETURN VALUES:
  772.     * 0, if string_literal was found and printed
  773.     * 1, if EOF was reached
  774.     * 2, if somekind of error was found
  775.     * 3, if no string_literal was found
  776.  * */
  777.  
  778.     char curr_symb;
  779.     int state = 0;
  780.     size_t buffer_size = 0;
  781.     Token *string_literal_token = calloc(1, sizeof(*string_literal_token));
  782.     char *buffer = calloc(1, sizeof(*buffer));
  783.     while ((fread(&curr_symb, 1, sizeof(char), input_file)) > 0) {
  784.         buffer_size++;
  785.         if (state == 0) {
  786.             if (curr_symb == '\"') {
  787.                 buffer[buffer_size - 1] = (char) curr_symb;
  788.  
  789.                 state = 1;
  790.                 continue;
  791.             } else if ((curr_symb == 'L') || (curr_symb == 'U') || (curr_symb == 'u')) {
  792.                 int curr_prefix = curr_symb;
  793.                 if ((curr_symb == 'L') || (curr_symb == 'U')) {
  794.                     fread(&curr_symb, 1, sizeof(char), input_file);
  795.                     buffer_size++;
  796.                     if (curr_symb != '\"') {
  797.                         if (fseek(input_file, -2, SEEK_CUR) == -1) {
  798.                             string_literal_token->type = -2;
  799.                             free(buffer);
  800.                             return string_literal_token;
  801.                         }
  802.                         string_literal_token->type = -3;
  803.                         free(buffer);
  804.                         return string_literal_token;
  805.                     } else {
  806.                         buffer = realloc(buffer, buffer_size);
  807.                         buffer[buffer_size - 2] = (char) curr_prefix;
  808.                         buffer[buffer_size - 1] = '\"';
  809.                         state = 1;
  810.                         continue;
  811.                     }
  812.                 } else { //curr_symb == u
  813.                     fread(&curr_symb, 1, sizeof(char), input_file);
  814.                     buffer_size++;
  815.                     if ((curr_symb != '8') && (curr_symb != '\"')) {
  816.                         if (fseek(input_file, -2, SEEK_CUR) == -1) {
  817.                             string_literal_token->type = -2;
  818.                             free(buffer);
  819.                             return string_literal_token;
  820.                         }
  821.                         string_literal_token->type = -3;
  822.                         free(buffer);
  823.                         return string_literal_token;
  824.                     } else {
  825.                         if (curr_symb == '\"') {
  826.                             buffer = realloc(buffer, buffer_size);
  827.                             buffer[buffer_size - 2] = (char) curr_prefix;
  828.                             buffer[buffer_size - 1] = '\"';
  829.                             state = 1;
  830.                             continue;
  831.                         }
  832.                         if (curr_symb == '8') {
  833.                             fread(&curr_symb, 1, sizeof(char), input_file);
  834.                             buffer_size++;
  835.                             if (curr_symb == '\"') {
  836.                                 buffer = realloc(buffer, buffer_size);
  837.                                 buffer[buffer_size - 3] = (char) curr_prefix;
  838.                                 buffer[buffer_size - 2] = '8';
  839.                                 buffer[buffer_size - 1] = '\"';
  840.                                 state = 1;
  841.                                 continue;
  842.                             } else {
  843.                                 if (fseek(input_file, -buffer_size, SEEK_CUR) == -1) {
  844.                                     string_literal_token->type = -2;
  845.                                     free(buffer);
  846.                                     return string_literal_token;
  847.                                 }
  848.                                 string_literal_token->type = -3;
  849.                                 free(buffer);
  850.                                 return string_literal_token;
  851.                             }
  852.                         }
  853.                     }
  854.                 }
  855.             } else {
  856.                 if (fseek(input_file, -1, SEEK_CUR) == -1) {
  857.                     string_literal_token->type = -2;
  858.                     free(buffer);
  859.                     return string_literal_token;
  860.                 }
  861.                 string_literal_token->type = -3;
  862.                 free(buffer);
  863.                 return string_literal_token;
  864.             }
  865.         }
  866.         if (state == 1) {
  867.             buffer = realloc(buffer, buffer_size);
  868.             buffer[buffer_size - 1] = (char) curr_symb;
  869.             if (curr_symb == '\\') {
  870.                 state = 2;
  871.                 continue;
  872.             } else if (curr_symb == '\"') {
  873.                 buffer_size++;
  874.                 buffer = realloc(buffer, buffer_size);
  875.                 buffer[buffer_size-1] = '\0';
  876.                 string_literal_token->buffer = calloc(buffer_size, sizeof(char));
  877.                 strncpy(string_literal_token->buffer, buffer, buffer_size);
  878.                 string_literal_token->type = STRING_LITERAL;
  879.                 free(buffer);
  880.                 return string_literal_token;
  881.             } else if (curr_symb == '\n') {
  882.                 buffer_size++;
  883.                 buffer = realloc(buffer, buffer_size);
  884.                 buffer[buffer_size-1] = '\0';
  885.                 string_literal_token->buffer = calloc(buffer_size, sizeof(char));
  886.                 strncpy(string_literal_token->buffer, buffer, buffer_size);
  887.                 string_literal_token->type = STRING_LITERAL;
  888.                 free(buffer);
  889.                 return string_literal_token;
  890.             } else {
  891.                 state = 1;
  892.                 continue;
  893.             }
  894.         }
  895.         if (state == 2) {
  896.             buffer = realloc(buffer, buffer_size);
  897.             buffer[buffer_size - 1] = (char) curr_symb;
  898.             if (curr_symb == '\\') {
  899.                 state = 2;
  900.                 continue;
  901.             }
  902.             else if (curr_symb == '\n') {
  903.                 buffer_size++;
  904.                 buffer = realloc(buffer, buffer_size);
  905.                 buffer[buffer_size-1] = '\0';
  906.                 string_literal_token->buffer = calloc(buffer_size, sizeof(char));
  907.                 strncpy(string_literal_token->buffer, buffer, buffer_size);
  908.                 string_literal_token->type = STRING_LITERAL;
  909.                 free(buffer);
  910.                 return string_literal_token;
  911.             }
  912.             else {
  913.                 state = 1;
  914.                 continue;
  915.             }
  916.         }
  917.     }
  918.     string_literal_token->type = STRING_LITERAL;
  919.     buffer_size++;
  920.     buffer = realloc(buffer, buffer_size);
  921.     buffer[buffer_size-1] = '\0';
  922.     string_literal_token->buffer = calloc(buffer_size, sizeof(char));
  923.     strncpy(string_literal_token->buffer, buffer, buffer_size);
  924.     free(buffer);
  925.     return string_literal_token;
  926. }
  927.  
  928. static Token *
  929. char_consts_analyser() {
  930.     /* DESCRIPTION:
  931.    * char_consts_analyser() attempts to read symbols from stdin until EOF
  932.    * if it has found "char_consts token(or pattern)" then saves it in Token->buffer, and changes Token->type
  933. * RETURN VALUES:
  934.    * 0, if char_consts was found and printed
  935.    * 1, if EOF was reached
  936.    * 2, if somekind of error was found
  937.    * 3, if no char_consts was found
  938. * */
  939.     char curr_symb;
  940.     int state = 0;
  941.     size_t buffer_size = 0;
  942.     Token *char_consts_token = calloc(1, sizeof(*char_consts_token));
  943.     char *buffer = calloc(1, sizeof(*buffer));
  944.     while ((fread(&curr_symb, 1, sizeof(char), input_file)) > 0) {
  945.         buffer_size++;
  946.         if (state == 0) {
  947.             if (curr_symb == '\'') {
  948.                 buffer = realloc(buffer, buffer_size);
  949.                 buffer[buffer_size - 1] = (char) curr_symb;
  950.                 state = 1;
  951.                 continue;
  952.             } else if ((curr_symb == 'L') || (curr_symb == 'U') || (curr_symb == 'u')) {
  953.                 int curr_prefix = curr_symb;
  954.                 fread(&curr_symb, 1, sizeof(char), input_file);
  955.                 buffer_size++;
  956.                 if (curr_symb == '\'') {
  957.                     buffer = realloc(buffer, buffer_size);
  958.                     buffer[buffer_size - 2] = (char) curr_prefix;
  959.                     buffer[buffer_size - 1] = '\'';
  960.                     state = 1;
  961.                     continue;
  962.                 } else {
  963.                     if (fseek(input_file, -2, SEEK_CUR) == -1) {
  964.                         char_consts_token->type = -2;
  965.                         free(buffer);
  966.                         return char_consts_token;
  967.                     }
  968.                     char_consts_token->type = -3;
  969.                     free(buffer);
  970.                     return char_consts_token;
  971.                 }
  972.             } else {
  973.                 if (fseek(input_file, -1, SEEK_CUR) == -1) {
  974.                     char_consts_token->type = -2;
  975.                     free(buffer);
  976.                     return char_consts_token;
  977.                 }
  978.                 char_consts_token->type = -3;
  979.                 free(buffer);
  980.                 return char_consts_token;
  981.             }
  982.         }
  983.         if (state == 1) {
  984.             buffer = realloc(buffer, buffer_size);
  985.             buffer[buffer_size - 1] = (char) curr_symb;
  986.             if (curr_symb == '\\') {
  987.                 state = 2;
  988.                 continue;
  989.             } else if (curr_symb == '\'') {
  990.                 buffer_size++;
  991.                 buffer = realloc(buffer, buffer_size);
  992.                 buffer[buffer_size-1] = '\0';
  993.                 char_consts_token->buffer = calloc(buffer_size, sizeof(char));
  994.                 strncpy(char_consts_token->buffer, buffer, buffer_size);
  995.                 char_consts_token->type = CHAR_CONST;
  996.                 free(buffer);
  997.                 return char_consts_token;
  998.             } else if (curr_symb == '\n') {
  999.                 buffer_size++;
  1000.                 buffer = realloc(buffer, buffer_size);
  1001.                 buffer[buffer_size-1] = '\0';
  1002.                 char_consts_token->buffer = calloc(buffer_size, sizeof(char));
  1003.                 strncpy(char_consts_token->buffer, buffer, buffer_size);
  1004.                 char_consts_token->type = CHAR_CONST;
  1005.                 free(buffer);
  1006.                 return char_consts_token;
  1007.             } else {
  1008.                 state = 1;
  1009.                 continue;
  1010.             }
  1011.         }
  1012.         if (state == 2) {
  1013.             buffer = realloc(buffer, buffer_size);
  1014.             buffer[buffer_size - 1] = (char) curr_symb;
  1015.             if (curr_symb == '\\') {
  1016.                 state = 2;
  1017.                 continue;
  1018.             }
  1019.             else if (curr_symb == '\n') {
  1020.                 buffer_size++;
  1021.                 buffer = realloc(buffer, buffer_size);
  1022.                 buffer[buffer_size-1] = '\0';
  1023.                 char_consts_token->buffer = calloc(buffer_size, sizeof(char));
  1024.                 strncpy(char_consts_token->buffer, buffer, buffer_size);
  1025.                 char_consts_token->type = CHAR_CONST;
  1026.                 free(buffer);
  1027.                 return char_consts_token;
  1028.             }
  1029.             else {
  1030.                 state = 1;
  1031.                 continue;
  1032.             }
  1033.         }
  1034.     }
  1035.     //EOF
  1036.     char_consts_token->type = CHAR_CONST;
  1037.     buffer_size++;
  1038.     buffer = realloc(buffer, buffer_size);
  1039.     buffer[buffer_size-1] = '\0';
  1040.     char_consts_token->buffer = calloc(buffer_size, sizeof(char));
  1041.     strncpy(char_consts_token->buffer, buffer, buffer_size);
  1042.     char_consts_token->type = CHAR_CONST;
  1043.     free(buffer);
  1044.     return char_consts_token;
  1045. }
  1046.  
  1047.  
  1048.  
  1049. Token *
  1050. analysing_stage() {
  1051.     char symb;
  1052.     int check;
  1053.     Token *current_token;
  1054.     while (fread(&check, 1, sizeof(char), input_file) > 0) {
  1055.         if (fseek(input_file, -1, SEEK_CUR) == -1) {
  1056.             perror("fseek error: ");
  1057.             return NULL;
  1058.         }
  1059.         while (white_space_print_skip() == 0);
  1060.         if (white_space_print_skip() == 1) {
  1061.             break;
  1062.         }
  1063.  
  1064.         current_token = comment_analyser();
  1065.         if (current_token->type == 7) {
  1066.             return current_token;
  1067.         } else if (current_token->type == -2) {
  1068.             free(current_token);
  1069.             perror("***Comment analyser***");
  1070.             return NULL;
  1071.         }
  1072.         if (current_token != NULL) {
  1073.             if (current_token->buffer != NULL) {
  1074.                 free(current_token->buffer);
  1075.             }
  1076.             free(current_token);
  1077.         }
  1078.  
  1079.         current_token = string_literal_analyser();
  1080.         if (current_token->type == 5) {
  1081.             return current_token;
  1082.         } else if (current_token->type == -2) {
  1083.             if (current_token->buffer != NULL) {
  1084.                 free(current_token->buffer);
  1085.             }
  1086.             free(current_token);
  1087.             perror("***String literal analyser***");
  1088.             return NULL;
  1089.         }
  1090.         if (current_token != NULL) {
  1091.             if (current_token->buffer != NULL) {
  1092.                 free(current_token->buffer);
  1093.             }
  1094.             free(current_token);
  1095.         }
  1096.  
  1097.         current_token = char_consts_analyser();
  1098.         if (current_token->type == 4) {
  1099.             return current_token;
  1100.         } else if (current_token->type == -2) {\
  1101.             free(current_token);
  1102.             perror("***Char consts analyser***");
  1103.             return NULL;
  1104.         }
  1105.         if (current_token != NULL) {
  1106.             if (current_token->buffer != NULL) {
  1107.                 free(current_token->buffer);
  1108.             }
  1109.             free(current_token);
  1110.         }
  1111.  
  1112.         current_token = keyword_analyser(keywords, KEYWORDS_MAX_LENGTH);
  1113.         if (current_token->type == 1) {
  1114.             return current_token;
  1115.         } else if (current_token->type == -2) {
  1116.             free(current_token);
  1117.             perror("***Keyword analyser***");
  1118.             return NULL;
  1119.         }
  1120.         if (current_token != NULL) {
  1121.             if (current_token->buffer != NULL) {
  1122.                 free(current_token->buffer);
  1123.             }
  1124.             free(current_token);
  1125.         }
  1126.  
  1127.         current_token = ucn_analyser();
  1128.         if (current_token->type == 8) {
  1129.             return current_token;
  1130.         } else if (current_token->type == -2) {
  1131.             free(current_token);
  1132.             perror("***Ucn analyser***");
  1133.             return NULL;
  1134.         }
  1135.         if (current_token != NULL) {
  1136.             if (current_token->buffer != NULL) {
  1137.                 free(current_token->buffer);
  1138.             }
  1139.             free(current_token);
  1140.         }
  1141.  
  1142.         current_token = identifier_analyser();
  1143.         if (current_token->type == 2) {
  1144.             return current_token;
  1145.         } else if (current_token->type == -2) {
  1146.             free(current_token);
  1147.             perror("***Identifier analyser***");
  1148.             return NULL;
  1149.         }
  1150.         if (current_token != NULL) {
  1151.             if (current_token->buffer != NULL) {
  1152.                 free(current_token->buffer);
  1153.             }
  1154.             free(current_token);
  1155.         }
  1156.  
  1157.         current_token = number_analyser();
  1158.         if (current_token->type == 3) {
  1159.             return current_token;
  1160.         } else if (current_token->type == -2) {
  1161.             free(current_token);
  1162.             perror("***Number analyser***");
  1163.             return NULL;
  1164.         }
  1165.         if (current_token != NULL) {
  1166.             if (current_token->buffer != NULL) {
  1167.                 free(current_token->buffer);
  1168.             }
  1169.             free(current_token);
  1170.         }
  1171.  
  1172.         current_token = punctuator_analyser(punctuators, PUNCTUATOR_MAX_LENGTH);
  1173.         if (current_token->type == 6) {
  1174.             return current_token;
  1175.         } else if (current_token->type == -2) {
  1176.             free(current_token);
  1177.             perror("***Punctuator analyser***");
  1178.             return NULL;
  1179.         }
  1180.         if (current_token != NULL) {
  1181.             if (current_token->buffer != NULL) {
  1182.                 free(current_token->buffer);
  1183.             }
  1184.             free(current_token);
  1185.         }
  1186.  
  1187.         /* if not of the 7 patterns, then print without color */
  1188.         if ((fread(&symb, 1, sizeof(char), input_file)) == 0) {
  1189.             perror("getchar error: ");
  1190.             return NULL;
  1191.         }
  1192.         putchar(symb);
  1193.     }
  1194.     current_token = calloc(1, sizeof(*current_token));
  1195.     current_token->type = 0;
  1196.     return current_token;
  1197. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement