Wykład 2

Transkrypt

Wykład 2
Konstrukcja kompilatorów
Wykład 2
Wykład 2
●
●
●
●
●
Na tym wykładzie zajmiemy się analizą
leksykalną
Analiza leksykalną to pierwszy krok na
drodze do uzyskania kompilatora
Analiza leksykalna ma również inne,
pożyteczne zastosowania
Analizator leksykalny bazuje na wyrażeniach
regularnych/automatach skończonych
Trochę teorii jeszcze nikomu nie zaszkodziło
Analiza leksykalna
●
●
●
●
●
Analiza leksykalna służy wyróżnieniu
pewnych obiektów ze strumienia znaków
wejściowych
Obiekty te będziemy nazywali tokenami lub
leksemami
Do opisu tych obiektów używamy wyrażeń
regularnych lub automatów skończonych
Automaty skończone opisują te same klasy
obiektów co wyrażenia regularne
Dlatego automaty skończone pozostawimy
teoretykom (Hopcroft, Ullman, Teoria automatów i języków formalnych)
Przykład automatu
skończonego
Automat skończony c.d.
●
Automat skończony składa się z:
–
–
–
–
●
stanów
przejść między stanami
stanu początkowego
stanu akceptującego
Mówimy, że automat akceptuje dane słowo
gdy kolejne znaki tego słowa pozwalają
przejść od stanu początkowego do stanu
akceptującego
Wyrażenie regularne
●
●
●
●
Wyrażenie regularne również opisuje pewne
słowa
Jeżeli słowo odpowiada wyrażeniu
regularnemu, to mówimy, że słowo to zostało
dopasowane (ang. match)
Każdemu wyrażeniu regularnemu odpowiada
automat skończony i vice versa
Istnieje wiele automatów skończonych
akceptujących te same ciągi znaków →
minimalizacja!
Wyrażenia regularne c.d.
●
Przykłady wyrażeń regularnych:
–
–
–
–
–
–
–
–
–
●
slowo
sl[a-z]wo
sl(a)+(w)?o
sl(a)*wo
sla{3}wo
sl[a-z]{3,5}wo
^sl[a-z]?w{4,}o
sl[^b-z]wo$
sl[abgr]wo
Wyrażenia regularne nie umieją liczyć!!!
Wyrażenia reg. a aut. sk. 1
Wyrażenia reg. a aut. sk. 2
Wyrażenia reg. a aut. sk. 3
Wyrażenia reg. a aut. sk. 4
●
●
●
Zamiana wyrażenia regularnego na automat
skończony następuje automatycznie
Istnieją efektywne, nudne algorytmy
eliminacji lambda-przejść i minimalizacji
automatów
Ponieważ są do tego programy nie będziemy
tego zgłębiać
Wyrażenia regularne c.d.
●
●
●
●
Wyrażenia regularne potrafią być bardziej
skomplikowane niż przedstawione wcześniej
Wszystkie dodatkowe właściwości wyrażeń
powstają w wyniku dodania stanowości
Stanowość nie da się przetłumaczyć na
automat skończony ale jest bardzo
użyteczna
W generatorze analizatorów leksykalnych
flex przykładem stanowości są wzorce
zależne od kontekstu
Przykłady użytecznych wyr. reg.
●
Identyfikator
–
●
Liczba całkowita (ze znakiem)
–
●
[+-]?[0-9]+
Liczba zmiennoprzecinkowa
–
●
[a-zA-Z_][a-zA-Z_0-9]*
[+-]?([0-9]+|[0-9]*.[0-9]+)
Przykład konstrukcji, która nie da się dobrze
opisać wyrażeniem regularnym – komentarz
w języku C:
–
–
/* to jest komentarz / he he * ha ha */
/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/
Przykłady ... 2
●
●
Znajdź błąd w powyższym wyrażeniu
regularnym dot. komentarzy w C...
Poniżej rozwiązanie przy użyciu stanów
(INITIAL i comment)
int line_num = 1;
"/*"
BEGIN(comment);
<comment>[^*\n]*
that’s not a ’*’ */
<comment>"*"+[^*/\n]*
followed by ’/’s */
<comment>\n
<comment>"*"+"/"
/* eat anything
/* eat up ’*’s not
++line_num;
BEGIN(INITIAL);
Generator analizatorów
leksykalnych
flex(1)
flex
●
●
●
●
flex na podstawie pliku zapisanego w
odpowiednim formacie generuje analizator
leksykalny będący programem w języku C
następnie musimy skompilować powstały
program kompilatorem C i zlinkować z
biblioteką flexową (-lfl)
Powstały program wynikowy jest
analizatorem leksykalnym
Więcej przykładów: man 1 flex
Koniec
Pytania? Sugestie?