|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
На основі поточного стануСкористаємося можливостями конструкції switch мови програмування С. Як елемент управління скінченого автомата візьмемо поточний стан скінченого автомата (на початку програми q0=0). int automat (FILE*fp) { int с, q=0; // початковий стан автомата while((c=fgetch(fp))!=EOF) { if (index_litera(c) = = -1) break; switch(q) {case 0: if (c>='1' && c<='9") {q=1; break;} if (c= =' ' || c= ='\n' || c= ='\t' || c= ='\r') break; if (c= ='0') { q=6; break;} // помилка – недопустимий початок лексеми my_error(); return 0; case 1: if (c>='0' && c<='9') break; // в заключному стані return 1; case 6: if (c= ='Х' || c= ='x') {q=12; break;} if (c>='0' && c<='7') {q=7; break;} // в заключному стані return 1; case 12: if ((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f')) {q=13; break;} // помилка – невірне продовження шістнадцяткової константи my_error (); return 0; // -------------------------------------------------------------------- // в такому стилі програмуємо далі // -------------------------------------------------------------------- }// кінець конструкції switch // перевіримо на заключний стан if (is_final (row)) printf (" Лексема вірна - %s", text); else printf (''Лексема помилкова-%s", text); }// кінець циклу зчитування літер }// кінець функції automat Наведений вище приклад функції automat, в якій в основу управління покладено поточний стан скінченого автомата, спробуємо певною мірою оптимізувати. З тексту модуля видно, що основні операції – це операції порівняння та перевірка належності поточної вхідної літери діапазону літер. При цьому враховується конкретна властивість кодової таблиці ASCI: коди латинських літер та цифр займають певні діапазони. Щоб функція automat не залежала від властивостей кодової таблиці, запропонуємо новий варіант її реалізації. Розділимо літери кодової таблиці на класи: - проміжок, \n, \v, \r, \t, \b – літери, які розділяють лексеми; - 1, 2, 3,..7 – вісімкові цифри (крім 0); - 0,...9,A,..F,a,..f — шістнадцяткові цифри; - 0 – вісімковий або десятковий нуль - клас, до якого входять літери ASCI: \, . Як бачимо, в загальному випадку класи можуть перетинатися. Розглянемо таблицю, об'ємом 256 елементів, в якій буде відмічатися належність літер до окремих класів. # include <stdio.h> #define DECIMAL 0x01 #define OCTAL 0x02 #define EMPTY 0x80 #define LITERA 0x04 char decimal[]=’0123456789’; char hesh_digit[] = ‘0123456789ABCDEFabcdef’; char octal[] = ‘01234567’; char empty[] = ‘ \n\r\t\v\r\b’; char litera[]= ‘ABCDEFGHIJKLMNOPQRSTUVUXYZ_abcdefghijklmnopqrstuvuxyz’ char vector_upr [256]; // початкова ініціалізація void set_class (char * str, int code) { int i, len = strlen(str); for (i=0; i<len; i + +) vector_upr [(int)*(str+i)] |= code; } int automat (FILE * fp) { int c, q =0; // початковий стан автомата while ((c = fgetch(fp))! = EOF) { class_litera = vector_upr [(int) (c)]; if (!class_litera) break; // літера не належить множині sigma switch (q) { case 0: if (class_litera & DECIMAL) { q=1; break;} if (c == ‘0’) {q=6; break; } if (class_litera & EMPTY) break; return ERROR; // в такому стилі програмуємо далі … …. … ….. } } } main () { int i; FILE*fp; char file_name[80]; REPEAT: printf("Вкажіть ім'я файла з лексеми:"); if(scant("%s", file_name) == 0) return 0; //відмовляється працювати if(fp = fopen (file_name,"rt") == NULL) { printf ("файл %s не відкрито.\ n"); goto REPEAT;} for (i = 0; i < 256; i++) *(vector_upr + i) = 0; set_class(decimal, DECIMAL); set_class(octal, OCTAL); set class(litera, LITERA); set class(empty, EMPTY); while (! eof (fp)) if (automat(fp) == ERROR) printf (" Лексема вірна - %s", text); else printf (''Лексема помилкова-%s", text); }// кінець main Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.01 сек.) |