Switch(where)//Змінна стану автомата

{

case А:

//перевірка умов на дугах і петлях і;

//виконання переходів і дій

break;

...

case Z:

//перевірка умов на дугах і петлях і;

//виконання переходів і дій

break;

};

Розглянемо процес програмної реалізації СА детальніше.

Розв'яжемо задачу про видалення з тексту коментаря програми, що написана мовою Паскаль. Нагадаємо, що коментарем називається послідовність символів, вміщена в спеціальні дужки: (*…*).

Видалення коментаря з тексту проводиться шляхом збереження основного тексту й незбереження тексту коментаря. Символи читаються й записуються, поки не зустрінуть початок коментаря. Потім початок коментаря та його символи просто прочитуються без збереження. Після досягнення закінчення коментаря знову читаємо та зберігаємо символи. Розберемо цей процес детальніше.

Якщо поточним прочитаним символом є "(", то далі, можливо, ітимуть символи, що утворюватимуть коментар, тобто можливий перехід у стан початку коментаря. Це залежить від наступного прочитаного символу. Якщо прочитаний символ "*", то "(" і "*" не зберігаються, і процес читання продовжується без збереження поточних символів. Інакше "(" зберігаємо й читаємо (зі збереженням) символи далі. Читання триває до появи символу "*". Це означає, що, можливо, далі йтиме стан закінчення коментаря. Якщо наступний прочитаний символ ")", то коментар закінчений, інакше продовжуємо читати й не зберігати прочитаний текст.

Можна виділити стани, у яких перебуває наша програма.

Стан "поза коментарем". У цьому стані читаємо й записуємо символи тексту.

Стан можливого початку коментаря. Прочитано символ "(". При читанні наступного символу можливі такі ситуації: поточним є прочитаний символ "*". У цьому випадку "(" і "*" не зберігаються, і програма переходить у стан "усередині коментаря"; поточним є будь-який інший символ. У цьому випадку зберігаємо символ "(" і переходимо в стан "поза коментарем".

Стан "усередині коментаря". Якщо прочитано поточний символ "*", то переходимо в стан можливого закінчення коментаря, інакше залишаємося в початковому стані, тобто продовжуємо читати без збереження тексту.

Стан можливого закінчення коментаря. Прочитано символ "*". При читанні наступного символу можливі такі ситуації: поточним є прочитаний символ "*". У цьому випадку необхідно зберегти попередній символ і залишитися в стані можливого закінчення коментаря; поточним є будь-який інший символ. У цьому випадку здійснюємо перехід у стан "усередині коментаря".

Складемо діаграму станів (рис. 9.5).

Рис. 9.5  

Позначимо через а читання будь-якого символу, окрім "("; b –будь-якого символу, окрім "(" і "*"; d – будь-якого символу, окрім "*" і ")"; А – стан "поза коментарем"; B – стан можливого початку коментаря; С – стан "усередині коментаря"; D – стан можливого кінця коментаря.

Деталізуємо автоматний алгоритм:

static char where='A';

int NonStop=1;

While(NonStop)

{

Switch(where)

{

case 'A':

//обробка стану А;

break;

case 'B':

//обробка стану B;

break;

case 'C':

//обробка стану З;

break;

case 'D':

//обробка стану D;

break;

}

}

Локальній події взаємно однозначно відповідає перехід з поточного стану в інший. Якщо жодна з обчислюваних у даному стані локальних подій не настала, то зберігається поточний стан. Цьому відповідає логічна умова, що заперечує умову переходів в інші стани.

За локальною подією програма переходить у наступному циклі в новий або залишається в старому стані. Однак перш ніж перейти в новий стан, вона має здійснити деяку дію на переході.

Правильна програма, що реалізовує СА, має містити дію закінчення циклу, щоб уникнути зациклення в одному стані.

Введемо такі позначення:

a поза коментарем – out;

a можливий початок коментаря – beg_com;

a усередині коментаря – in_com;

a можливий кінець коментаря – end_com.

При читанні першого символу СА знаходиться в початковому стані – where=out. Подальші дії здійснюються залежно від значення where. Наприклад, якщо where=out і current='/', то переходимо в стан "початок коментаря" – змінюється стан СА, тобто треба змінній where надатизначення beg_com. Якщо читається будь-який інший символ, то необхідно його записати у вихідний файл, і СА залишиться в поточ­ному стані.

Out:switch(current)

{

case '/':where=beg_com;break;

default:putc(current,f_out);

}

Нехай, наприклад, СА перебуває у стані "початок коментаря". Якщо поточний прочитаний символ '/', то записуємо його у вихідний файл і не змінюємо стан СА; якщо поточний символ '*', то переходимо в стан "усередині коментаря", і where=in_com. При читанні будь-якого іншого символу друкуємо його у вихідний файл і переходимо у стан "поза коментарем" where=out.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: