Transcript LEX

Slide 1

LEX
Generator analizatorów
leksykalnych


Slide 2

GENERATOR L E X
Zadaniem generatora LEX jest
wygenerowanie kodu źródłowego
analizatora leksykalnego (domyślnie) w
języku C;
Kod źródłowy generowany jest przez
LEX’a w oparciu o plik zawierający
wszystkie reguły przetwarzania;
Plik z regułami tworzony jest przez
samego użytkownika;
2


Slide 3

GENERATOR L E X
Schemat organizacji działania LEX’a:
scan.l
LEX

scan.c
GCC
scane.exe

plik.txt
WYNIK

3


Slide 4

GENERATOR L E X
flex –l scan.l (użycie generatora
LEX)

gcc scan.c -o scan.exe (kompilacja
C++)

scan.exe < plik.txt (analiza plik.txt)
4


Slide 5

GENERATOR L E X
Ważną cechą analizatora jest możliwość
wykorzystania go do większych aplikacji;
Każdy wygenerowany kod źródłowy
zawiera bowiem funkcję, dzięki której
można podłączyć analizator leksykalny do
innych aplikacji. Funkcja o której mowa to
yylex();
5


Slide 6

TWORZENIE PLIKU REGUŁ
Każdy plik ze specyfikacją dla programu
LEX powinien składać się z trzech sekcji;
Pierwsza sekcja to sekcja definicji;

W sekcji definicji umieszczamy, jak sama
nazwa wskazuje, definicje i deklaracje
zmiennych, stałych, deklaracje stanów
oraz makra procesora;
6


Slide 7

TWORZENIE PLIKU REGUŁ
Sekcja definicji może zawierać fragment
kodu, który system przepisze
bezpośrednio do analizatora leksykalnego;
Kod ten musi być odpowiednio
„opakowany”;
Otwarcie fragmentu bezpośrednio
przepisywanego do analizatora powinno
być poprzedzone znacznikiem %{,
natomiast jej zamknięcie %};
7


Slide 8

TWORZENIE PLIKU REGUŁ
Przykład budowy sekcji definicji:
%{
#include
int zmienna;
int yylex();
int zmienna_druga=1;
%}
8


Slide 9

TWORZENIE PLIKU REGUŁ
Druga sekcja to sekcja przetwarzania;

W sekcji przetwarzania umieszczamy
wszelkie reguły postępowania, zgodnie z
którymi wygenerowany będzie analizator;
Reguły postępowania to inaczej przepisy
na to co analizator ma zrobić gdy
napotyka na określony „problem” (symbol);
9


Slide 10

TWORZENIE PLIKU REGUŁ
Budowa reguły przetwarzania opiera się
na dwóch zasadniczych częściach: wzorca
i operacji;
Jej budowa wygląda więc:
wzorzec
operacja
Wzorzec jest zapisywany jako wyrażenie
regularne;
Operacja jest blokiem instrukcji języka C;
10


Slide 11

TWORZENIE PLIKU REGUŁ
Przykład budowy reguły przetwarzania:

(a+b)*a(a+b)2 cout<<‘’W słowie A trzeci
symbol od końca
jest równy a’’;

11


Slide 12

WYRAŻENIA REGULARNE
Podamy teraz kilka symboli używanych
do zapisu wyrażeń regularnych
występujących we wzorcach reguł
przetwarzania:

1. Symbole linii:
^…- początek linii;
…$ - koniec linii;

12


Slide 13

WYRAŻENIA REGULARNE
2. Symbole operacji logicznych:
ab - konkatenacja;
a|b - alternatywa;
a* - domknięcie zwrotne (domknięcie);
a+ - domknięcie dodatnie (domknięcie po
odjęciu słowa pustego);
a? – opcjonalność (symbol „a” nie występuje
lub występuje jeden raz);
13


Slide 14

WYRAŻENIA REGULARNE
3. Powtarzanie symbolu:

a{n} – powtórzenie symbolu „a” n – razy;
a{n,m} – zakres powtarzania symbolu (czyli
an,…,am);
() – określają stopień ważności (c(a|d)|(e+)
);
14


Slide 15

WYRAŻENIA REGULARNE
4. Klasy znaków:

[a-z] - oznacza dowolny znak z zakresu od
małej litery „a” do małej litery „z”;
[^a-z] – oznacza dowolny znak spoza klasy
[a-z] (jak gdyby „negacja”
zakresu);
[a-zXY] – oznacza dowolny znak z zakresu
[a-z] lub wielką literę X lub Y;
[0-9] – oznacza dowolną cyfrę od 0 do 9;


Slide 16

WYRAŻENIA REGULARNE
4. Klasy znaków (c.d.):
. - oznacza dowolny znak nie będący
znakiem końca linii;
\... – poprzedza sekwencje specjalne
(podobnie jak w C) np.:
\n – oznacza znak końca linii;
\t – oznacza znak tabulatora;
16


Slide 17

TWORZENIE PLIKU REGUŁ
Przykład budowy reguły przetwarzania:

(a+b)*a(a+b)2 cout<<‘’W słowie A trzeci
symbol od końca
jest równy a’’;
Powinniśmy wpisać:
(a|b)*a(a|b){2} cout<<‘’W słowie A trzeci
symbol od końca
jest równy a’’;

17


Slide 18

WYRAŻENIA REGULARNE
Inne ważne zasady tworzenia wzorców:
Wzorce zawierające spacje ujmuje się w
cudzysłów;
Komentarz wpisuje się między znaczniki
/* a */;
Niedopasowane znaki są przepisywane
na wyjście;
18


Slide 19

Przykład
Wyrażenie regularne akceptujące adres strony
internetowej:

[Ww]{3} \. [A-Za-z0-9._-]+ \. [A-Za-z]{3} \. [Pp] [Ll]

19


Slide 20

Przykład
Wyrażenie regularne akceptujące słowa kluczowe
w Adzie begin i end:
[A-Za-z]{3,5}
[A-Za-z]{5} | [A-Za-z]{3}
[Bb][Ee][Gg][Ii][Nn] | [Ee][Nn][Dd]
20


Slide 21

Przykład
Wyrażenie regularne akceptujące wszelkie
identyfikatory (zmienne, stałe ) w C:

[A-Za-z _ ] [A-Za-z0-9 _ ]*

21


Slide 22

Przykład
Wyrażenie regularne akceptujące datę:
([0-9]{2} \- [0-9]{2} \- [0-9]{4}) |
([0-9]{2} \. [0-9]{2} \. [0-9]{4}) |
([0-9]{4} \- [0-9]{2} \- [0-9]{2}) |
([0-9]{4} \. [0-9]{2} \. [0-9]{2})
([0-9]{2} (\- | \.) [0-9]{2} (\- | \.) [0-9]{4}) |
([0-9]{4} (\- | \.) [0-9]{2} (\- | \.) [0-9]{2})

22


Slide 23

Przykład
Wyrażenie regularne akceptujące wszelkie
adresy poczty e-mail:

[A-Za-z0-9 . _ -]+@[A-Za-z0-9 . _ ]+\.[A-Za-z]{2,4}

23


Slide 24

TWORZENIE PLIKU REGUŁ
Trzecią sekcją składową pliku ze
specyfikacją dla programu LEX jest sekcja
podprogramów;
W skład sekcji podprogramów mogą, jak
sama nazwa wskazuje, wchodzić definicje
funkcje, które będą następnie
wykorzystywane przez analizator
leksykalny;
24


Slide 25

TWORZENIE PLIKU REGUŁ
Deklaracja funkcji wchodzących w skład
tej sekcji poddana jest regułą tworzenia
funkcji w języku C;
Funkcja yywrap() – jest to funkcja o
specjalnym znaczeniu. Gdy wywołujemy
(uprzednio wygenerowany) analizator
leksykalny, funkcja yywrap() jest
wykonywana zawsze po przetworzeniu
danych wejściowych;
25


Slide 26

Przykład
Przykład funkcji znajdującej się w sekcji
podprogramów:
int main()
{
return yylex();
}
Wymaga ona oczywiście wcześniejszej
deklaracji yylex’a w postaci zwrotu:
int yylex();
26


Slide 27

TWORZENIE PLIKU REGUŁ
Przy tworzeniu pliku reguł przetwarzania
można korzystać z zmiennych globalnych;
Deklaracja tego typu zmiennych znajduje
się w pierwszej sekcji (sekcji definicji)
pliku;
Zmienne globalne, mogą być oczywiście
wykorzystywane w każdej następnej
sekcji, np. inkrementowane, zmieniane,
czy odczytywane;
27


Slide 28

TWORZENIE PLIKU REGUŁ
Oprócz zmiennych globalnych można także
korzystać ze zmiennych wbudowanych;
Mamy dwie szczególnie ważne zmienne
wbudowane yyleng i yytext;
Zmienna yyleng jest typu int i okresla długość
dopasowania;
Zmienna yytext jest znakiem (char) a dokładniej
ciągiem znaków, wskazuje na leskem (odnajduje
w strumieniu danych wejściowych, zapis który
pasował do wzorca);
28


Slide 29

TWORZENIE PLIKU REGUŁ
Pożyteczną rolę odgrywają także definicje
regularne;
Tworzenie definicji regularnej to inaczej
przypisanie wyrażeniu regularnemu
pewnego identyfikatora;
Identyfikator ten może być wykorzystany
później w polu wzorca;
Definicja regularna jest tworzona w sekcji
definicji;
29


Slide 30

Przykład
Definicje regularną umieszczamy co
prawda w sekcji definicji, jednakże po
bloku bezpośrednio przepisywanym do
analizatora;
Zobaczmy następujący przykład, który
pokazuje sposób korzystania z
zadeklarowanego identyfikatora;

30


Slide 31

Przykład
%{
#include
int yylex();
%}
identyfikator [Ii] [Ff]
%%
{identyfikator} {cout<<‘’ Wczytano leksem IF’’;}
%%
31


Slide 32

TWORZENIE PLIKU REGUŁ
Wszystkie trzy omówione sekcje składowe
pliku ze specyfikacją dla programu LEX
oddzielane są podwójnym znakiem
procenta - %%;

Schemat pliku ze specyfikacją reguł dla
programu LEX możemy więc
zademonstrować w tabeli:
32


Slide 33

TWORZENIE PLIKU REGUŁ
SEKCJA DEFINICJI
%%

SEKCJA REGUŁ PRZETWARZANIA
%%
SEKCJA PODPROGRAMÓW
...


Slide 34

NIEJEDNOZNACZNOŚĆ
Gdy przeanalizowaliśmy już zasadę
działania generatora LEX, możemy
przyjrzeć się istotnemu problemowi
niejednoznaczności przy działaniu LEX;
Przykład:
m* {cout<<‘’*’’;}
mmm {cout<<‘’+’’;}
Dostarczamy strumień danych postaci:
mmmmmmmmmm;mmm
34


Slide 35

NIEJEDNOZNACZNOŚĆ
ZASADA NAJDŁUŻSZEGO
DOPASOWANIA – określa, iż jeśli mamy
dwie lub więcej reguł dla których wzorce
są spełnione, to wybierana jest ta reguła
dla której dopasowanie wzorca jest
najdłuższe;
ZASADA WCZEŚNIEJSZEGO
DOPASOWANIA – mówi iż, gdy
dopasowania maja identyczną długość,
wybrana jest reguła, która została
umieszczona pierwsza w pliku
specyfikacji;

35


Slide 36

NIEJEDNOZNACZNOŚĆ
Stosując zatem zasadę pierwszą w
przykładzie, dane wyjściowe będą
wyglądały:
*;+
Gdybyśmy zaś mieli dane wejściowe
postaci
mmm
to stosując drugą zasadę dostaniemy na
wyjściu
+

36


Slide 37

RETRAKCJA
Pojęcie retrakcji wiąże się ze sposobem
działania analizatora;
Analizator przetwarza wiele wzorców
równolegle w poszukiwaniu najlepszego
(tzn. najdłuższego) . Porzuca on z czasem
wzorce mniej „obiecujące” koncentrując
się na wzorcach, które mogą dać dłuższe
dopasowania;
W sytuacji niepowodzenia wraca do
porzuconych wzorców;...
37


Slide 38

KONIEC

KONIEC WYKŁADU TRZECIEGO