Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


На основі поточного стану




Скористаємося можливостями конструкції 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





Поделиться с друзьями:


Дата добавления: 2015-11-05; Мы поможем в написании ваших работ!; просмотров: 374 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Так просто быть добрым - нужно только представить себя на месте другого человека прежде, чем начать его судить. © Марлен Дитрих
==> читать все изречения...

2463 - | 2219 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.01 с.