• Nie Znaleziono Wyników

Wyrażenia regularne i konwersje automatów

N/A
N/A
Protected

Academic year: 2021

Share "Wyrażenia regularne i konwersje automatów"

Copied!
18
0
0

Pełen tekst

(1)

Wyrażenia regularne i konwersje automatów

Marcin Orchel

1 Wstęp

1.1 Wyrażenia regularne

Wyrażenia regularne to jeden ze sposobów reprezentacji języka formalnego. Każde wy- rażenie regularne można przedstawić za pomocą gramatyki regularnej i odwrotnie.

Definicja wyrażenia regularnego. Dany jest alfabet Σ. Wyrażeniami regularnymi są:

• ε - wyrażenie regularne oznaczające następujący język formalny {ε},

• ∅ - wyrażenie regularne oznaczające język formalny: ∅,

• a - wyrażenie regularne oznaczające język formalny {a}, gdzie a ∈ Σ. Ponadto wyrażeniami regularnymi są:

• RS - wyrażenie regularne oznaczające konkatenację dwóch zbiorów A i B wyrażo- nych za pomocą wyrażeń regularnych R i S odpowiednio: {αβ|α ∈ A and β ∈ B},

• R|S - wyrażenie regularne oznaczające alternatywę dwóch zbiorów A i B wyrażo- nych za pomocą wyrażeń regularnych R i S,

• R - wyrażenie regularne oznaczające gwiazdę Kleene’go na zbiorze A wyrażonym za pomocą wyrażenia regularnego R, to znaczy jest to zbiór wszystkich słów z R oraz słów powstałych przez konkatenację słów z języka R, zawierający również łańcuch pusty.

Ponadto w wyrażeniach regularnych można używać nawiasów pomocnych w definiowaniu priorytetów działań. Standardowe priorytety są następujące od najwyższego: gwiazda Kleenego, konkatenacja, alternatywa. Przykłady wyrażeń regularnych: a|boznacza zbiór ε, a, b, bb, bbb, ..., (a|b) oznacza zbiór wszystkich słów z symbolami a oraz b, łącznie z łańcuchem pustym, ab(c|ε) oznacza zbiór wszystkich słów rozpoczynających się od a, później zero lub więcej symboli b, i na końcu opcjonalnie c. Często w definicjach wyrażeń regularnych spotyka się następujące redundantne symbole:

• R+ oznacza zbiór wszystkich słów z R oraz słów powstałych przez konkatenację słów z wyrażenia R nie zawierający łańcucha pustego. R+ może być zapisany przy pomocy symbolu jako RR.

(2)

• R? może być zapisany jako (R|ε).

• R - zbiór wszystkich słów z Σ, które nie należą do R. Zapis tego zbioru może być bardziej skomplikowany.

1.1.1 Standard IEEE POSIX Basic Regular Expressions (BRE)

Wyrażenia regularne w standardzie BRE posiadają symbole oraz następujące metasym- bole i metasekwencje znaków:

• . - oznacza dowolny pojedynczy symbol oprócz znaku nowej linii, w nawiasach kwadratowych oznacza po prostu kropkę

• [] - oznacza pojedynczy symbol, który jest zawarty w nawiasach, np [abc], [a − z].

Zauważmy, że nie ma możliwości zapisywania słów w nawiasach kwadratowych.

Jeśli − występuje tuż po nawiasie początkowym lub przed nawiasem końcowym to oznacza ona pauzę. Aby uzyskać pauzę położoną wewnątrz nawiasów trzeba użyć strategii escapowania, to znaczy zamiast pauzy napisać \−.

• [] - oznacza pojedynczy symbol, który nie jest zdefiniowany w nawiasach, np [abc]

- oznacza każdy symbol, który nie jest ani a, ani b, ani c. Np. [a − z] oznacza wszystkie symbole, które nie są małymi literkami.

- oznacza początek łańcucha, kiedy analizujemy linie oznacza początek linii

• $ - oznacza koniec łańcucha, kiedy analizujemy linie oznacza koniec linii

• \(\) - oznaczone podwyrażenie (blok, grupa), napis wewnątrz tych nawiasów może być użyty później za pomocą odwołania \1, . . . , \9

• \n - odwołanie do grupy, \1, . . . , \9, wykorzystanie odwołań powoduje, że dostaje- my język, który nie jest regularny

- zero lub więcej razy poprzedzający element, np. ab*c oznacza {ac, abc, abbc, . . .}, [xyz] oznacza ε, x, y, z, zx, zyx, ..., . oznacza dowolny łańcuch

• \{m, n\} - oznacza wystąpienie od m do n razy poprzedzającego elementu: a\{3, 5\} to {aaa, aaaa, aaaaa}.

Przykłady: [hc]at - oznacza słowo hat lub cat występujące na początku linii. [hc]at$

- oznacza słowo hat lub cat występujące na końcu linii.

1.1.2 Standard Extended Regular Expressions (ERE)

Wyrażenia regularne w standardzie ERE. Różnice w stosunku do BRE. Brak możliwości używania grup.

• ? - oznacza wystąpienie elementu poprzedzającego zero lub jeden raz, np. ba?

oznacza b lub ba.

(3)

• + - oznacza wystąpienie elementu poprzedzającego jeden lub więcej razy, np. ba+

oznacza {ba, baa, baaa, . . .}.

• | - oznacza alternatywę np. abc|def oznacza {abc, def }.

Przykłady: [hc] + at - oznacza {hat, cat, hhat, chat, . . .} [hc]?at - oznacza {hat, cat, at} Niektóre zakresy liczb lub liter można zapisywać za pomocą klasy definiowanej w standardzie, przykładowo: [A − za − z] można zapisać jako [: alpha :] - oznacza znaki alfanumeryczne, [0 − 9] można zapisać jako [: digit :] - oznacza cyfry, itd.

1.1.3 Wyrażenia regularne w Perlu

Wyrażenia regularne w Perlu są bardziej rozbudowane w porównaniu ze standardami BRE i ERE. Różnice: \ - escapowanie za pomocą \ oznacza zawsze znak niealfanume- ryczny. W perlu możliwe jest zdefiniowanie leniwego dopasowania, w przeciwieństwie do zachłannego dopasowania: dany łańcuch: ala < ma >< kota >, zachłanne dopasowanie za pomocą wyrażenia < .∗ >: < ma >< kota >, leniwe dopasowanie za pomocą wyraże- nia < .∗ >: < ma >. Jak inaczej osiągnąć łańcuch < ma >? Np. za pomocą wyrażenia

< [>] >. Leniwe dopasowanie oznaczane jest jako < .? >, znak zapytania po gwiazd- ce. W praktyce spotyka się wiele rozszerzeń wyrażeń regularnych. Takie wyrażenia z rozszerzeniami często nie dają się przedstawić w ogólności za pomocą wyrażenia regu- larnego, dlatego nazywa się je dla odróżnienia wzorcami, np. wyrażenia z grupami nie da się przedstawić w ogólności za pomocą wyrażeń regularnych. Zastosowanie wyrażeń regularnych do operacji tekstowych

• Wyszukiwanie linii, które zawierają co najmniej jedno słowo akceptowane przez wyrażenie regularne.

• Zastępowanie słów w tekście akceptowanych przez dane wyrażenie regularne.

• Sprawdzanie czy dane słowo jest akceptowane przez wyrażenie regularne.

• Usuwanie linii zawierających słowa akceptowane przez dane wyrażenie regularne.

• Usuwanie linii nie zawierających słowa akceptowanego przez dane wyrażenie regu- larne.

• Usuwanie linii nie akceptowanych przez wyrażenie regularne.

• Usuwanie linii akceptowanych przez wyrażenie regularne.

1.2 Konwersje automatów

1.2.1 Konwersja automatu do wyrażenia regularnego Mamy dany automat:

(4)

q0

start q2

q1

b a

a

a

a

b b

Rysunek 1: Przykładowy automat.

q0

start q2

q1 b

a

a

a

a + b b

Rysunek 2: Przykładowy automat.

W pierwszym kroku należy sprawdzić czy automat posiada jeden stan końcowy. Jeśli posiada ich więcej, to należy utworzyć nowy stan końcowy i poprowadzić do niego ε- tranzycje ze stanów końcowych. Ponadto stosujemy zapis łączący tranzycje ze sobą, np.

jeśli mamy tranzycje a i b od danego stanu do innego tego samego dla obu tranzycji to obydwie tranzycje zastępujemy jedną o nazwie a + b. Zapis a + b jest równoważny zapisowi a|b. W rozważanym przykładzie będzie jedno takie zastąpienie Rys.2.

Następnie dodajemy tranzycje z pustym zbiorem napisów pomiędzy stanami bez tranzycji. W przykładzie konieczne są 3 takie tranzycje i otrzymujemy Rys.3.

Następnie należy usunąć wszystkie stany, które nie są stanem początkowym i stana- mi końcowymi. Podczas usuwania tych stanów należy zmodyfikować zbiór tranzycji nie dochodzących do usuwanych stanów, tak aby realizowały wszystkie ścieżki przechodzące przez usuwany stan. Nowe tranzycje mogą zawierać zamiast pojedynczych symboli sło- wa wraz ze znakami specjalnymi + oraz. Operacje na zbiorze pustym są nastepujące:

(5)

q0

start q2

q1

b a

a

a

a + b

∅ ∅ b

Rysunek 3: Przykładowy automat.

Tabela 1: Tabela tranzycji

Od Do Wyrażenie

q0 q0 a

q0 q1 b

q1 q0 (a + b)aa q1 q1 (a + b)ab

konkatenacja zbioru pustego z dowolnym wyrażeniem jest zbiorem pustym, unia zbio- ru pustego i wyrażenia jest tym wyrażeniem, gwiazdka na zbiorze pustym jest słowem pustym ε. W tym przykładzie usuwamy stan q2. Po tej operacji otrzymujemy Rys. 4.

Tabelka z zastępowaniem tranzycji Tabela1.

Na podstawie tego automatu odczytujemy ostatecznie wyrażenie regularne. Zaczy- namy od stanu q0. Stosując tranzycję do stanu q0 otrzymujemy wyrażenie regularne a. Następnie stosujemy tranzycję do stanu q1i otrzymujemy: ab. Następnie stosujemy tran- zycję do stanu q1 wielokrotnie: ab((a + b)ab). Następnie stosujemy tranzycję ze stanu q1 do stanu q0 i otrzymujemy ab((a + b)ab)(a + b)aa. Ponieważ możemy powtórzyć to przejście wielokrotnie to mamy (ab((a + b)ab)(a + b)aa). Na końcu musimy przejść do stanu końcowego, a zatem otrzymujemy (ab((a + b)ab)(a + b)aa)ab((a + b)ab). 1.2.2 Konwersja wyrażenia regularnego do niedeterministycznego automatu Przykładowo mamy dane wyrażenie regularne: ab(a + b). Najpierw tworzony jest au- tomat, gdzie jest jedna tranzycja o nazwie będącej tym wyrażeniem Rys. 5. Następnie rozbijamy tę tranzycję biorąc pod uwagę wszystkie konkatenacje. Powstaną 3 nowe tran- zycje odpowiadające a, b oraz a + b. Tworzymy stan początkowy i końcowy i łańcuch pomiędzy nowymi tranzycjami Rys.6: Następnie rozbijamy wyrażenie (a + b). Najpierw zastępujemy wyrażenie w nawiasach samym wyrażeniem Rys.7. Następnie musimy utwo-

(6)

q0 start

q1 b

a

(a + b)aa (a + b)ab

Rysunek 4: Przykładowy automat.

q0

start q1

ab(a + b)

Rysunek 5: Przykładowy automat.

q0

start q2

q3

q4

q5

q6

q7

q1

ε

a

ε b

ε (a + b)

ε

Rysunek 6: Przykładowy automat.

(7)

q0

start q2

q3

q4

q5 q6

q7 q1

ε

a

ε b

ε a + b

ε

Rysunek 7: Przykładowy automat.

rzyć 4 nowe stany i dwie ścieżki jedna dla a, a druga dla b od stanu q6do q7i otrzymujemy Rys. 8. Następnie rozbijamy wyrażenie a i otrzymujemy Rys.9.

1.2.3 Konwersja NFA do DFA

Dany jest przykładowy niedeterministyczny automat skończony:

Automat ten jest niedeterministyczny ponieważ:

• ze stanu q0 wychodzą dwie tranzycje a

• ze stanu q0 wychodzą dwie tranzycje b,

• ze stanu q1 wychodzą dwie tranzycje a,

• istnieje ε-tranzycja ze stanu q2. Rozpoczynamy konstrukcję DFA:

1. Tworzymy stan p0 automatu DFA odpowiadający stanowi q0 automatu NFA. Ze stanu q0 po przeczytaniu terminala a możemy przejść do stanów q1, lub q2 lub q0. Dlatego tworzymy stan p1 z informacją, że odpowiada on stanom q0,q1,q2 z DFA. Natomiast po przeczytaniu terminala b możemy dojść do stanów q1 lub q3. Ponieważ w DFA stan q3był stanem końcowym, a stan p2odpowiada m.in. stanowi q3, a więc stan p2 również będzie końcowy Rys.11.

2. Następnie analizujemy nowo powstały stan p1. Za pomocą tranzycji a możemy dojść z niego do stanów q1, q3, q2, q0. Tworzymy stan p3 odpowiadający tym stanom. Stan p3 odpowiada m.in. stanowi końcowemu q3, a więc również będzie końcowy. Za pomocą tranzycji b możemy dojść do q1 lub q3. Stan odpowiadający

(8)

q0

start q2

q3 q4

q5 q6

q7 q8

q9 q10

q11

q1 ε

a

ε b

ε ε ε

b a

ε ε

ε

Rysunek 8: Przykładowy automat.

(9)

q0

start q2

q3 q4

q5 q6

q7 q8

q9 q10

q11 q12

q13

q1 ε

ε ε

ε

a

ε

ε b

ε ε ε

b a

ε ε

ε

Rysunek 9: Przykładowy automat.

(10)

q0

start q1

q2 q3

a b

a b

a a

a

b ε

Rysunek 10: Przykładowy automat.

p0[0]

start p1[1,2,0]

p2[1,3]

a

b

Rysunek 11: Przykładowy automat.

(11)

p0[0]

start p1[1,2,0]

p2[1,3] p3[1,3,2,0] a

b a

b

Rysunek 12: Przykładowy automat.

tym stanom już istnieje, jest to stan q2, dlatego nie tworzymy nowego stanu, tylko prowadzimy tranzycję b do istniejącego Rys.12.

3. Następnie analizujemy stan p3. Po tranzycji a lub b możemy dojść do stanów q1, q3, q2, q0 Rys.13.

4. Analizujemy stan p2. Po tranzycji a możemy dojść do q1,q3, a po tranzycji b możemy dojść do q0, q2. Jako że nie ma stanu, który odpowiada tym stanom tworzymy nowy stan p4 Rys. 14.

5. Analizujemy stan p4. Za pomocą tranzycji a możemy dojść do q0, q1, q2. Za pomocą tranzycji b możemy dojść do q1,q3 Rys.15.

1.2.4 Minimalizacja liczby stanów DFA

Dany jest przykładowy automat Rys.16. Najpierw budujemy drzewo stanów. Na począt- ku tworzymy stan główny, któremu odpowiadają wszystkie stany automatu wyjściowego DFA. Następnie rozdzielamy ten stan na dwa, jednemu z nich odpowiadają stany końco- we DFA, a drugiemu pozostałe stany DFA Rys. 17. W każdym kroku będziemy próbo- wali zbiór stanów DFA odpowiadający wybranemu stanowi w drzewie podzielić na dwa podzbiory, z których będą utworzone odpowiednio dwa nowe stany w drzewie. Podział polega na tym, że dla wybranego typu tranzycji jeden podzbiór zawiera stany DFA, z których istnieją tranzycje wybranego typu do pozostałych stanów drzewa. A drugi pod- zbiór to pozostałe stany DFA w wybranym stanie drzewa. Podział jest możliwy, kiedy oba podzbiory są niepuste. Jeśli istnieją różne możliwości podziału ze względu na wybra- ny typ tranzycji to wybieramy dowolnie jeden z podziałów. Jeśli dla żadnego stanu i dla żadnej tranzycji podział już nie jest możliwy otrzymaliśmy końcowe drzewo, z którego budujemy automat minimalny DFA. Automat minimalny będzie składał się ze stanów bedącymi liściami tego drzewa. Tranzycje między stanami automatu minimalnego będą odpowiadały odpowiednim tranzycjom z wyjściowego automatu.

(12)

p0[0]

start p1[1,2,0]

p2[1,3] p3[1,3,2,0] a

b a

b

a b

Rysunek 13: Przykładowy automat.

p0[0]

start p1[1,2,0]

p2[1,3] p3[1,3,2,0]

p4[0,2]

a

b a

b

a b b

a

Rysunek 14: Przykładowy automat.

(13)

p0[0]

start p1[1,2,0]

p2[1,3] p3[1,3,2,0]

p4[0,2]

a

b a

b

a b b

a

b

a

Rysunek 15: Przykładowy automat.

q0

start q1

q2 q6

q3

q5 q4

a

b a

b

a b

a b

b

a a

b a

b

Rysunek 16: Przykładowy automat.

(14)

0,1,2,3,4,5,6

N onf inal 0,1,2,3,4,5 F inal 6

Rysunek 17: Drzewo stanów.

0,1,2,3,4,5,6

N onf inal[a]0,1,2,3,4,5

1,2,3,5 0,4

F inal 6

Rysunek 18: Drzewo stanów.

W podanym przykładzie algorytm będzie wyglądał następująco: Na początku pró- bujemy rozdzielić grupę N onf inal. Bierzemy pod uwagę wszystkie terminale po kolei i sprawdzamy czy istnieją tranzycje z tymi terminalami do pozostałych grup. Weźmy pod uwagę terminal b. Z grupy N onf inal nie ma żadnej tranzycji b do grupy F inal, więc bierzemy pod uwagę kolejny terminal, a. Do grupy F inal istnieją dwie tranzycje a, ze stanów q0 i q4. A więc grupę N onf inal rozdzielamy na dwie, w jednej znajdą się stany q0 i q4, a w drugiej wszystkie pozostałe stany: q1, q2, q3, q5 Rys. 18. Grupa 0, 4 nie może być rozdzielona, ponieważ gdy wybierzemy zarówno tranzycje a jak i b, to wychodzą one do pozostałych grup z obu stanów 0, 4, a więc jeden z podzbiorów byłby pusty. Teraz próbujemy rozdzielić grupę 1, 2, 3, 5. Do grupy 0, 4 dochodzą od niej tranzycje a oraz b.

Wybieramy jedną z nich, np. b. Tranzycje b odchodzą ze stanów 2, 3, 5. A więc tworzy- my podzbiór 2, 3, 5, oraz podzbiór z pozostałymi stanami, a więc podzbiór ze stanem 1 Rys.19. Grupy 2, 3, 5 nie możemy już rozdzielić, ponieważ gdy wybierzemy typ tranzycji a to nie ma takich tranzycji od tej grupy na zewnątrz. Gdy wybierzemy typ tranzycji b, to ze wszystkich stanów 2, 3, 5 wychodzą tranzycje b na zewnątrz grupy, a więc podział nie jest możliwy. Kończymy budowę drzewa stanów, ponieważ żadnego liścia nie można już rozdzielić. Wszystkie liście tworzą stany zminimalizowanego automatu pozostało dodać tranzycje pomiędzy tymi stanami. Dodajemy każdą tranzycję z wyjściowego automatu.

0,1,2,3,4,5,6

N onf inal[a]0,1,2,3,4,5

1,2,3,5

2,3,5 1 0,4

F inal 6

Rysunek 19: Drzewo stanów.

(15)

q2[0,4]

start q1[1]

q0[2,3,5] q3[6] b

a

b a

b

a a

b

Rysunek 20: Przykładowy automat.

q0

start b q1 q2

a

a

b

Rysunek 21: Przykładowy automat.

Ostatecznie otrzymujemy automat Rys.20.

1.2.5 Konwersja automatu DFA do gramatyki regularnej

Mamy dany przykładowy DFA Rys. 21. W pierwszym kroku każdemu stanowi zostaje przyporządkowany unikalny symbol nieterminalny, przy czym stanowi q0zostaje przypo- rządkowany symbol startowy S Rys.22. Każdej tranzycji odpowiada jedna produkcja w gramatyce prawostronnie liniowej. Tranzycji a ze stanu q0odpowiada produkcja S → aS, itp. Ponadto dla każdego stanu końcowego dodajemy tranzycje do ε. Ostatecznie otrzy-

q0[S]

start b q1[A] q2[B]

a

a

b

Rysunek 22: Przykładowy automat.

(16)

q0[S]

start q2

q1[B]

ε b

a a

b a

Rysunek 23: Przykładowy automat.

mujemy:

1. S → aS 2. A → ε 3. B → bA 4. S → bA 5. A → aB

1.2.6 Konwersja gramatyki regularnej do FA Mamy daną gramatykę:

• S → aB

• S → bS

• S → ε

• B → aS

• B → bB

• B → a

Dla każdego nieterminala tworzymy osobny stan, oraz dodatkowo tworzymy stan, który będzie stanem końcowym. Dla ε-produkcji oraz dla produkcji, które po prawej stronie mają terminal prowadzimy tranzycje do stanu końcowego. W rezultacie otrzymujemy Rys. 23.

(17)

q0

start

q1 q2

q3 q4

ε

b a

b a

ε a

b

a b

Rysunek 24: Zadanie.

2 Zadania

2.1 Zadania podstawowe

1. Przekonwertuj podany NFA do DFA Rys.24. Wyprowadź gramatykę dla tego auto- matu. Przekonwertuj z powrotem gramatykę do automatu. Wyprowadź wyrażenie regularne dla tego automatu. Z powrotem przekonwertuj wyrażenie regularne do automatu. Zminimalizuj liczbę stanów wyprowadzonego DFA.

2. Dla poniższej gramatyki wyprowadź FA:

(a) S → A (b) S → aS

(c) A → ε (d) A → aB

(e) B → bA

2.2 Zadania dodatkowe

1. Jedno losowo wybrane przez upel zadanie z zestawu 9 ze stronyhttp://kompilatory.

agh.edu.pl/automaty/zadania/Zadania09.pdf

2. Jedno losowo wybrane przez upel zadanie z zestawu 10 ze stronyhttp://kompilatory.

agh.edu.pl/automaty/zadania/Zadania10.pdf

3. Jedno losowo wybrane przez upel zadanie z zestawu 11 ze stronyhttp://kompilatory.

agh.edu.pl/automaty/zadania/Zadania11.pdf

4. Jedno losowo wybrane przez upel zadanie z zestawu 13 ze stronyhttp://kompilatory.

agh.edu.pl/automaty/zadania/Zadania13.pdf

(18)

Literatura

[1] U. J. D. Hopcroft John E., Rajeev Motwani, Wprowadzenie do teorii automatów, języków i obliczeń. Wydawnictwo Naukowe PWN, 2012.

Cytaty

Powiązane dokumenty

W tymże przekroju istnieje przedział domknięty niezerowej długo- ści, w którym to, jak się okaże, znajduje sie nieskończenie wiele wyrazów ciągu {ξ n }, co czyni p

‡ Stan początkowy posiada ε przejście do stanu akceptującego (a więc akceptowany jest ciąg ε) oraz do stanu początkowego automatu dla wyrażenia R1.. ‡ Stan akceptujący

Znaleźć równania prostych zawierających boki oraz współrzędne pozostałych wierzchołków..

Algorytmy i Struktury

Praca własna: Wykonaj trzy przykłady (jeden wiersz)

Dane są rzuty zestopniowane dwóch prostych przecinających się oraz rzut punktu A.. Przez ten punkt poprowadzić płaszczyznę b równoległą do płaszczyzny utworzonej przez

– Je suis veuf mais j’habite avec mon fils, ma belle-fille et ma petite- fille Mathilde. La cave –

1) Dla relacji binarnej w zbiorze X={a,b,c,d,e,f,g} opisanej zadaną tablicą zbudować diagram Hassego i za jego pomocą wyznaczyć zbiór ograniczeń górnych i zbór ograniczeń