Analizator leksykalny - C Programming

Analizator leksykalny - Czyta ze standardowego ciągu wejściowego . I Drukuje standardowe wyjście tej dywizji podczas tokenized .


  1. // ANALIZATOR LEKSYKALNY
  2. //
  3. // Wczytuje ze standardowego wejscia ciag znakow.
  4. // Drukuje na standardowe wyjscie podzial tego ciagu na leksemy.
  5.  
  6.  
  7. #include<stdio.h>
  8. #include<stdlib.h>
  9.  
  10. #define max_dl_leksemu 100
  11.  
  12. typedef enum { FALSE = 0, TRUE = 1 }  Boolean;
  13.  
  14. typedef enum { STAN_POCZ    =  0,
  15.                STAN_A       =  1,
  16.                STAN_K       =  2,
  17.                STAN_AD      =  3,
  18.                STAN_AS      =  4,
  19.                STAN_KA      =  5,
  20.                STAN_ADA     =  6,
  21.                STAN_ASI     =  7,
  22.                STAN_KAM     =  8,
  23.                STAN_KAMI    =  9,
  24.                STAN_KAMIL   = 10,
  25.                STAN_KAMILA  = 11,
  26.                STAN_ADAM    = 12,
  27.                STAN_ASIA    = 13,
  28.                STAN_NIEOKR  = 14  }  Stany;
  29.  
  30. typedef enum { ZNAK_A       =  0,
  31.                ZNAK_D       =  1,
  32.                ZNAK_M       =  2,
  33.                ZNAK_S       =  3,
  34.                ZNAK_I       =  4,
  35.                ZNAK_K       =  5,
  36.                ZNAK_L       =  6,
  37.                ZNAK_NIEOKR  = 10  }  Znaki;
  38. // MEZCZYZNA i KOBIETA
  39. typedef enum { MEZCZYZNA    = 0,
  40.                KOBIETA      = 1 }  Jednostki;
  41.  
  42. struct leksem
  43.   {
  44.     Jednostki jed;             // rodzaj leksemu
  45.     int dlug;                  // dlugosc leksemu  ( 1 <= dlug <= max_dl_leksemu )
  46.     char zaw[max_dl_leksemu];  // chary skladajace sie na leksem
  47.   };
  48.  
  49.  
  50. void  blad (char s[], char ch)
  51.     // sygnalizacja bledu; drukuje napis  s  i char  ch
  52.     // a nastepnie sie zatrzymuje
  53.   {
  54.     printf ("!!! %s  '%c' !!!\n\n", s, ch);
  55.     exit(1);
  56.   }
  57.  
  58.  
  59. Znaki  kategoria (char ch)
  60.     // ta funkcja grupuje chary z wejscia w elementy typu  Znaki ;
  61.     // to znaczy zapomina o roznicy miedzy literami malymi i duzymi,
  62.     // wszystkim cyfrom przypisuje  ZNAK_CYF ,
  63.     // nielegalnym znakom przypisuje  ZNAK_NIEOKR
  64.   {
  65.     if (ch == 'a' || ch == 'A')  return ZNAK_A;     else
  66.     if (ch == 'd' || ch == 'D')  return ZNAK_D;     else
  67.     if (ch == 'm' || ch == 'M')  return ZNAK_M;     else
  68.     if (ch == 's' || ch == 'S')  return ZNAK_S;     else
  69.     if (ch == 'i' || ch == 'I')  return ZNAK_I;     else
  70.     if (ch == 'k' || ch == 'K')  return ZNAK_K;     else
  71.     if (ch == 'l' || ch == 'L')  return ZNAK_L;
  72.     else  return ZNAK_NIEOKR;
  73.   }
  74.  
  75. // poprawic na ilosci tabelki
  76. Stany  tab_symb[12][8];
  77.   // -- tabela symboli czyli zakodowany automat; indeksowana stanami
  78.   // od STAN_POCZ do STAN_SEPAR oraz znakami od ZNAK_B do ZNAK_NIEOKR
  79.  
  80. char  wejscie;
  81.   // char przeczytany na zapas z wejscia
  82.  
  83.  
  84. void  leks (struct leksem* lk)
  85.     // zasadnicza funkcja programu;
  86.     // jej wywolanie powoduje wczytanie odpowiedniej liczby charow z
  87.     // wejscia i zlozenie z nich leksemu (lub sygnalizacja bledu);
  88.     // zakladamy, ze w momencie wywolania w zmiennej globalnej  wejscie
  89.     // jest juz wczytany jeden char z wejscia;
  90.     // po zakonczeniu dzialania tej funkcji w tej zmiennej jest juz
  91.     // wczytany jeden char na zapas
  92.   {
  93.     Stany  q, q1;
  94.     Znaki  z;
  95.     Boolean  koniec;
  96.     q1 = STAN_POCZ; lk->dlug = 0; koniec = FALSE;
  97.     do
  98.       { z = kategoria(wejscie);
  99.         q = q1; q1 = tab_symb[q][z];
  100.         if (q1 == STAN_NIEOKR)  { /* blad */ q1 = q; koniec = TRUE; }  else
  101.         // zmienic na ostatni z ktorego nie wychodza strzalki
  102.         if (q1 > STAN_NIEOKR)
  103.           {   /* koniec leksemu */
  104.             lk->zaw[lk->dlug] = wejscie; lk->dlug++; scanf("%c", &wejscie);
  105.               /* Uwaga: brak sygnalizacji przepelnienia tablicy  lk->zaw  */
  106.             koniec = TRUE;
  107.           }
  108.         else
  109.           { lk->zaw[lk->dlug] = wejscie; lk->dlug++; scanf("%c", &wejscie);
  110.               /* Uwaga: brak sygnalizacji przepeďż˝nienia tablicy  lk->zaw  */
  111.           }
  112.         }
  113.     while (! koniec);
  114.       // po zakonczeniu powyzszej petli w  q1  jest stan, na ktorym
  115.       // automat zakonczyc dzialanie; pozostaje sprawdzic, czy to jest
  116.       // stan akceptujacy i co akceptujacy
  117.  
  118. // USTAWIC TRESCI
  119.     switch (q1)
  120.       { case STAN_POCZ   : blad("Nieoczekiwany znak", wejscie); break;
  121.         case STAN_A      : blad("Mialo byc 'asia','ada' lub 'adam' a jest", wejscie); break;
  122.         case STAN_K     : blad("Mialo byc 'kasia','kamil' lub 'kamila' a jest", wejscie); break;
  123.         case STAN_AD      : blad("Mialo byc 'ada' lub 'adam'", wejscie); break;
  124.         case STAN_AS     : blad("Mialo byc 'asia' lub 'kasia'", wejscie); break;
  125.         case STAN_KA  : blad("Mialo byc 'kasia','kamil' lub 'kamila' a jest", wejscie); break;
  126.         case STAN_ASI  : blad("Mialo byc 'asia' lub 'kasia' a jest", wejscie); break;
  127.         case STAN_KAM  : blad("Mialo byc 'kamil' lub 'kamila' a jest", wejscie); break;
  128.         case STAN_KAMI  : blad("Mialo byc 'kamil' lub 'kamila' a jest", wejscie); break;
  129.         // 5 stanow konczacych : KOBIETA lub MEZCZYZNA
  130.         case STAN_ADA   : lk->jed = KOBIETA; break;
  131.         case STAN_ADAM  : lk->jed = MEZCZYZNA; break;
  132.         case STAN_KAMIL  : lk->jed = MEZCZYZNA; break;
  133.         case STAN_KAMILA   : lk->jed = KOBIETA; break;
  134.         case STAN_ASIA : lk->jed = KOBIETA; break;
  135.         case STAN_NIEOKR : blad("Nieoczekiwany znak", wejscie); break;
  136.       }
  137.   }
  138.  
  139.  
  140. void  wydruk (struct leksem lk)
  141.     // wydruk pojedynczego leksemu
  142.   {
  143.     int i;
  144.     printf("LEKSEM:  ");
  145.     switch (lk.jed)
  146.         // MEZCZYZNA ALBO KOBIETA
  147.       { case MEZCZYZNA  : printf("mezczyzna      '"); break;
  148.         case KOBIETA   : printf("kobieta   '"); break;
  149.       }
  150.     for (i=0; i<lk.dlug; i++)  printf("%c", lk.zaw[i]);
  151.     printf("'\n");
  152.   }
  153.  
  154.  
  155. int main ()
  156.   {
  157.     //------------------------------------------------------
  158.     // Inicjalizacja tabeli symboli:
  159.  
  160.     Stany q;  Znaki z;  struct leksem  lk;
  161.         // uzupelnienia
  162.     for (= STAN_POCZ; q <= STAN_NIEOKR; q++)
  163.       for (= ZNAK_A; z <= ZNAK_NIEOKR; z++)
  164.         tab_symb[q][z] = STAN_NIEOKR;
  165.  
  166.     /*for (q = STAN_CGW; q <= STAN_CGWGW; q++)
  167.       for (z = ZNAK_B; z <= ZNAK_NIEOKR; z++)
  168.         tab_symb[q][z] = STAN_CGW;
  169. */
  170.     tab_symb[STAN_POCZ][ZNAK_A] = STAN_A;
  171.     tab_symb[STAN_POCZ][ZNAK_K] = STAN_K;
  172.     tab_symb[STAN_A][ZNAK_D] = STAN_AD;
  173.     tab_symb[STAN_A][ZNAK_S] = STAN_AS;
  174.     tab_symb[STAN_K][ZNAK_A] = STAN_KA;
  175.     tab_symb[STAN_AD][ZNAK_A] = STAN_ADA;
  176.     tab_symb[STAN_AS][ZNAK_I] = STAN_ASI;
  177.     tab_symb[STAN_KA][ZNAK_M] = STAN_KAM;
  178.     tab_symb[STAN_KA][ZNAK_S] = STAN_AS;
  179.     tab_symb[STAN_ADA][ZNAK_M] = STAN_ADAM;
  180.     tab_symb[STAN_ASI][ZNAK_A] = STAN_ASIA;
  181.     tab_symb[STAN_KAM][ZNAK_I] = STAN_KAMI;
  182.     tab_symb[STAN_KAMI][ZNAK_L] = STAN_KAMIL;
  183.     tab_symb[STAN_KAMIL][ZNAK_A] = STAN_KAMILA;
  184.  
  185.     //------------------------------------------------------
  186.     // Inne inicjalizacje:
  187.  
  188.     printf("\n"); scanf("%c", &wejscie); printf("\n");
  189.  
  190.     //------------------------------------------------------
  191.     // Analiza leksykalna:
  192.  
  193.      while (wejscie != '\n')  { leks(&lk); wydruk(lk); }
  194.      printf("\n");
  195.  
  196.     //------------------------------------------------------
  197.  
  198.      return 0;
  199.   }


Learn More :