Analiza leksykalna i generator LEX

Podobne dokumenty
L E X. Generator analizatorów leksykalnych

Generator analizatorów leksykalnych - Lex. Bartosz Bogacki.

KONSTRUKCJA KOMPILATORÓW

Analiza leksykalna 1. Teoria kompilacji. Dr inż. Janusz Majewski Katedra Informatyki

Podstawy Kompilatorów

Zadanie analizy leksykalnej

Analiza leksykalna 1. Języki formalne i automaty. Dr inż. Janusz Majewski Katedra Informatyki

Generatory analizatorów

Metody Kompilacji Wykład 1 Wstęp

Laboratorium z użyciem analizatora leksykalnego FLEX

Podstawy Kompilatorów

Generator skanerów Flex

Translacja wprowadzenie

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

Podstawy Kompilatorów

Ćwiczenia nr 11. Translatory. Wprowadzenie teoretyczne

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Program We Kompilator Wy Źródłowy

Podstawy Kompilatorów

Flex - generator analizatorów leksykalnych

Generator LLgen. Wojciech Complak Generator LLgen - charakterystyka. Generator LLgen -składnia specyfikacji

Podstawy generatora YACC. Bartosz Bogacki.

Plan wykładu. Kompilatory. Literatura. Translatory. Literatura Translatory. Paweł J. Matuszyk

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Wprowadzenie. Wojciech Complak

Matematyczne Podstawy Informatyki

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

automatem skończonym niedeterministycznym (ang. nondeterministic finite automaton) M N nazywamy system:

Jerzy Nawrocki, Wprowadzenie do informatyki

Zmienne, stałe i operatory

10. Translacja sterowana składnią i YACC

Jerzy Nawrocki, Wprowadzenie do informatyki

Wstęp do programowania

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

Języki programowania zasady ich tworzenia

Wprowadzenie do programowania w języku C

1 Podstawy c++ w pigułce.

Programowanie komputerów

Języki formalne i gramatyki

Wstęp do programowania

Wprowadzenie do kompilatorów

Jerzy Nawrocki, Wprowadzenie do informatyki

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Instrukcja do ćwiczenia P4 Analiza semantyczna i generowanie kodu Język: Ada

Zajęcia P2AM. Analizator składniowy (Flex + Bison, Linux)

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Programowanie strukturalne język C - wprowadzenie

Podstawy Informatyki Języki programowania c.d.

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

Podstawy programowania w języku C

Java EE produkcja oprogramowania

Programowanie. Pascal - język programowania wysokiego poziomu. Klasa 2 Lekcja 9 PASCAL

Wstęp do programowania. Wykład 1

Wprowadzenie do analizy leksykalnej. Bartosz Bogacki.

Podstawy Kompilatorów

Python wprowadzenie. Warszawa, 24 marca PROGRAMOWANIE I SZKOLENIA

Elżbieta Kula - wprowadzenie do Turbo Pascala i algorytmiki

Algorytmy od problemu do wyniku

( wykł. dr Marek Piasecki )

Tablice, funkcje - wprowadzenie

INFORMATYKA, TECHNOLOGIA INFORMACYJNA ORAZ INFORMATYKA W LOGISTYCE

Wstęp do programowania INP003203L rok akademicki 2016/17 semestr zimowy. Laboratorium 1. Karol Tarnowski A-1 p.

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania

Semantyka i Weryfikacja Programów - Laboratorium 6

Wydział Zarządzania AGH. Katedra Informatyki Stosowanej. Podstawy VBA cz. 1. Programowanie komputerowe

Podstawy programowania - 1

Gramatyki atrybutywne

Podstawy programowania (1)

1 Podstawy c++ w pigułce.

Języki i metodyka programowania. Wprowadzenie do języka C

Programowanie Proceduralne

Microsoft IT Academy kurs programowania

Podstawy kompilatorów. Generator LLgen. Wojciech Complak.

Wykład 4. Środowisko programistyczne

Programowanie w języku Python. Grażyna Koba

Podstawy Programowania. Wykład 1

Programowanie obiektowe, wykład nr 6. Klasy i obiekty

ForPascal Interpreter języka Pascal

Programy pomocnicze: diff, make, systemy rcs i cvs, debugger. Zarządzanie wersjami.

Ryszard Myhan. Wykład 1: Języki programowania

Wstęp do Programowania, laboratorium 02

Analiza zależności kontekstowych

Elementy języków programowania

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

Podstawy programowania C. dr. Krystyna Łapin

Język programowania PASCAL

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Język C++ zajęcia nr 1

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

Informatyka, Ćwiczenie Uruchomienie Microsoft Visual C++ Politechnika Rzeszowska, Wojciech Szydełko. I. ZałoŜenie nowego projektu

Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI

Podstawy Programowania

Język ludzki kod maszynowy

Programowanie strukturalne i obiektowe

Podstawy Kompilatorów

Programowanie. Projektowanie funkcje programu tworzenie algorytmu i struktur danych. Programowanie implementacja algorytmu kompilacja programu

Wykład V. Rzut okiem na języki programowania. Studia Podyplomowe INFORMATYKA Podstawy Informatyki

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

1. Brian W. Kernighan, Dennis M. Ritchie, Język ANSI C, WNT, Warszawa 1998.

Transkrypt:

Analiza leksykalna i generator LEX Wojciech Complak Wojciech.Complak@cs.put.poznan.pl wprowadzenie generator LEX wyrażenia regularne i niejednoznaczności retrakcja definicje regularne atrybuty lewy kontekst (stany) prawy kontekst (podgląd) koniec pliku (funkcja yywrap) białe spacje i komentarze słowa kluczowe odrzucenie dopasowania (REJECT) Plan wykładu 1.05 Analiza leksykalna i generator LEX (2/44) Kompilatory i interpretery Model kompilatora kompilator jest programem, który przetwarza kod napisany w jednym języku (tzw. języku źródłowym) na równoważny kod w drugim języku (tzw. języku wynikowym) interpreter jest programem, który nie generuje programu wynikowego tylko od razu wykonuje instrukcje zawarte w programie źródłowym, interpretery są wykorzystywane do wykonywania języków poleceń oraz języków bardzo wysokiego poziomu takich, jak APL czy Prolog każda kompilacja składa się z dwóch etapów: etapu analizy w której program źródłowy rozkładany jest na części składowe i generowana jest jego reprezentacja pośrednia etapu syntezy w której na podstawie reprezentacji pośredniej generowany jest program wynikowy program źródłowy analiza reprezentacja pośrednia synteza program wynikowy Analiza leksykalna i generator LEX (3/44) Analiza leksykalna i generator LEX (4/44) Model kompilatora Analiza leksykalna - wprowadzenie etap analizy obejmuje: analizę leksykalną analizę składniową analizę semantyczną etap syntezy obejmuje: generację kodu pośredniego optymalizację kodu generację kodu wynikowego analiza synteza program źródłowy analiza leksykalna analiza składniowa analiza semantyczna generacja kodu pośredniego optymalizacja kodu generacja kodu wynikowego program wynikowy analiza leksykalna jest pierwszą fazą kompilatora czyta tekst wejściowy i wyprowadza rozpoznane jednostki leksykalne wydzielenie fazy analizy leksykalnej: upraszcza projekt i utrzymanie poprawia wydajność ułatwia przenoszenie analiza synteza program źródłowy analiza leksykalna analiza składniowa analiza semantyczna generacja kodu pośredniego optymalizacja kodu generacja kodu wynikowego program wynikowy Analiza leksykalna i generator LEX (5/44) Analiza leksykalna i generator LEX (6/44) 1

Analiza leksykalna - wprowadzenie Analiza leksykalna przykład (#1/2) rozpoznawanie ciągów znaków o pewnych własnościach (zbudowanych zgodnie z określonymi regułami) wykorzystywana w różnych narzędziach do przetwarzania tekstu takich jak : edytory strukturalne formatery kodu analizatory i kontrolery statyczne kompilatory krzemowe translatory języków naturalnych interpretery i kompilatory języków formalnych (np. języków programowania) Analiza leksykalna i generator LEX (7/44) dany jest fragment programu w języku C, należy podzielić go na jednostki leksykalne podstawowe pojęcia związane z analizą leksykalną: token leksem wzorzec atrybut(y) przykładowy program w języku C: int sqr(int n) { return n * n; Analiza leksykalna i generator LEX (8/44) Analiza leksykalna przykład (#2/2) Generator LEX (#1/3) token wzorzec (LEX) leksem atrybut KWD_INT int int IDENT [_a-za-z][_a-za-z0-9]* sqr "sqr" '(' \( ( KWD_INT int int IDENT [_a-za-z][_a-za-z0-9]* n "n" ')' \) ) '{' \{ { KWD_RET return return IDENT [_a-za-z][_a-za-z0-9]* n "n" OP_STAR \* * IDENT [_a-za-z][_a-za-z0-9]* n "n" ';' ; ; '' \ Analiza leksykalna i generator LEX (9/44) LEX jest generatorem analizatorów leksykalnych na podstawie zadanej specyfikacji generuje program źródłowy implementujący analizator leksykalny analizator leksykalny jest domyślnie generowany w języku C istnieją wersje LEXa, które mogą generować analizatory w innych językach programowania np.: C++, C#, Pascal, Java, Ada, Eiffel synonimy: analizator leksykalny = skaner analizator składniowy = parser Analiza leksykalna i generator LEX (10/44) Generator LEX (#2/3) Generator LEX (#3/3) na wejście generatora LEX podajemy specyfikację analizatora na wyjściu generatora LEX otrzymujemy implementację analizatora w języku C (funkcja yylex()) specyfikacja analizatora leksykalnego LEX funkcja: yylex() plik: lex.yy.c funkcję yylex() można: wykorzystać jako samodzielny analizator zintegrować z większą aplikacją np. z analizatorem składniowym Analiza leksykalna i generator LEX (11/44) postać specyfikacji dla generatora LEX: Definicje Reguły Podprogramy sekcje Definicji i Podprogramów mogą być puste sekcja Reguł musi zawierać co najmniej jedną regułę każda Reguła to: Wzorzec Akcja(e) w specyfikacjach można używać komentarzy (tak jak w ANSI C: /* komentarz */) Analiza leksykalna i generator LEX (12/44) 2

Podstawowe reguły działania (#1/2) Podstawowe reguły działania (#2/2) niedopasowane znaki są przepisywane na wyjście akcja = instrukcja języka C, akcja pusta = ; przykład: usuwanie nadmiarowych słów kluczowych języka C (register, auto) register ; auto ; wejście wyjście int a(void) { register int c; auto int d; int a(void) { int c; int d; Analiza leksykalna i generator LEX (13/44) wzorce zawierające spacje ujmujemy w znaki: " " przykład: skracanie deklaracji języka C long int long signed int int "long int" printf("long"); "signed int" printf("int"); wejście wyjście int a(void) { signed int c; long int d; int a(void) { int c; long d; Analiza leksykalna i generator LEX (14/44) Zmienne statyczne Zmienne automatyczne zliczanie liczby linii do ciągu ### z wykorzystaniem zmiennej statycznej int NR = 0; \n { printf("\n"); NR ++; ### { printf("###\n%d lines\n", NR); Analiza leksykalna i generator LEX (15/44) zliczanie liczby linii do ciągu ### z wykorzystaniem zmiennej automatycznej int NR = 0; \n { printf("\n"); NR ++; ### { printf("###\n%d line(s)\n", NR); Analiza leksykalna i generator LEX (16/44) Funkcje Wyrażenia regularne zliczanie liczby linii do ciągu ### z użyciem funkcji prototyp definicja funkcji int NR = 0; void incnr(int *); \n { printf("\n"); incnr(&nr); ### { printf("###\n%d lines\n",nr); void incnr(int *n) { (*n)++; Analiza leksykalna i generator LEX (17/44) dowolny znak (z wyjątkiem \n). konkatenacja x*y* początek linii ^x koniec linii x$ operator opcjonalności x? nawiasy (x y)z powtórzenia wzorca x{5 alternatywa x y sekwencja ucieczki \ sekwencje specjalne \a\t\n liczba oktalna \nnn liczba szesnastkowa \xhh zakres powtórzeń wzorca x{2,5 domknięcie zwrotne x* klasa znaków [] domknięcie dodatnie x+ Analiza leksykalna i generator LEX (18/44) 3

Niejednoznaczności (#1/2) Niejednoznaczności (#2/2) ile liter a zostanie wypisanych na wyjście? 1* { printf("a"); zasada najdłuższego dopasowania wejście 1111;1 wyjście? Analiza leksykalna i generator LEX (19/44) jakie litery zostaną wypisane na wyjście? 11 { printf("b"); 1* { printf("a"); wejście 11;1111; wyjście? przy równej długości dopasowania wybierany jest wzorzec występujący wcześniej w specyfikacji Analiza leksykalna i generator LEX (20/44) Retrakcja Definicje regularne rozpoznawanie liczb rzeczywistych w Fortranie 1.E? Q dlaczego to działa? wejście 1.EQ.2 wyjście Card RelOp Card [0-9]+ printf("card "); ".EQ." printf("relop "); [0-9]+".E"[0-9]+ printf("real "); Analiza leksykalna i generator LEX (21/44) usuwanie z programu etykiet skoków definicja użycie ident [_a-za-z][_a-za-z0-9]* {ident: ; Analiza leksykalna i generator LEX (22/44) Atrybuty symboli leksykalnych (#1/2) Atrybuty symboli leksykalnych (#2/2) zmienne wbudowane w LEXa: int yyleng char yytext[] / char *yytext (zależnie od implementacji LEXa) zmienne wbudowane najbezpieczniej jest traktować jak zmienne tylko do odczytu przykład: suma sekwencji liczb wejście 1+ 11+ 8= wyjście 1+ 11+ 8= 20 Analiza leksykalna i generator LEX (23/44) int suma = 0; [0-9]+ { int liczba; sscanf(yytext,"%d",&liczba); ECHO; suma+=liczba; = printf("= %d",suma); Analiza leksykalna i generator LEX (24/44) 4

Lewy kontekst (stany) (#1/3) Lewy kontekst (stany) (#2/3) przykład: analizator usuwający łańcuchy ujęte w znaki cudzysłowu: wejście wyjście #include "defs1.h" #include "defs2.h" int i; #include #include int i; "/; %s qstring <qstring>\" BEGIN 0; <qstring>. ; \" BEGIN qstring; BEGIN stan; = zmiana bieżącego stanu./echo 0 qstring./; "/; Analiza leksykalna i generator LEX (25/44) reguły działają tylko w wymienionym stanie jeżeli przed regułą nie ma nazwy stanu to reguła działa we wszystkich stanach! (uwaga na pozostałe zasady) Analiza leksykalna i generator LEX (26/44) Lewy kontekst (stany) (#3/3) Prawy kontekst (podgląd) (#1/3) stan początkowy (<0>): albo <INITIAL> (uwaga na Flexa!): musi być <INITIAL> %s qstring <qstring>\" BEGIN 0; <qstring>. ; <0>\" BEGIN qstring; %s qstring <qstring>\" BEGIN 0; 0 albo INITIAL <qstring>. ; <INITIAL>\" BEGIN qstring; nazwy stanów nie mogą być słowami kluczowymi języka C jeśli reguła ma działać w określonych stanach należy poprzedzić ją nazwami stanów: <INITIAL,c_state>[^ ] { ECHO; Analiza leksykalna i generator LEX (27/44) przykład: rozpoznawanie symbolu zakresu w Moduli-2 Cardinal [0-9]+ Real [0-9]+"."[0-9]*(E[+\-]?[0-9]+)? {Cardinal { printf("card(%s) ",yytext); {Real { printf("real(%s) ",yytext); ".." { printf("range(%s) ",yytext); "." { printf("dot(%s) ",yytext); "[" { printf("["); "]" { printf("]"); Analiza leksykalna i generator LEX (28/44) Prawy kontekst (podgląd) (#2/3) Prawy kontekst (podgląd) (#3/3) problem: wejście [1..5] oczekiwane wyjście [Card(1) Range(..) Card(5) ] rzeczywiste wyjście [Real(1.) Dot(.) Card(5) ] Analiza leksykalna i generator LEX (29/44) poprawne rozwiązanie z wykorzystaniem operatora podglądu Cardinal [0-9]+ Real [0-9]+"."[0-9]*(E[+-]?][0-9]+)? {Cardinal { printf("card(%s) ",yytext); {Real/[^0-9.] { printf("real(%s) ",yytext); ".." { printf("range(%s) ",yytext); "." { printf("dot(%s) ",yytext); "[" { printf("["); "]" { printf("]"); Analiza leksykalna i generator LEX (30/44) 5

Koniec pliku i funkcja yywrap (#1/2) Koniec pliku i funkcja yywrap (#2/2) przykład: suma sekwencji liczb wejście 1 2 3 4 5 wyjście Suma = 15 funkcja yywrap() jest wywoływana przez yylex() po natrafieniu na koniec pliku int yywrap(void) { /* akcje użytkownika */ return 1; 0 powrót do skanowania wejścia!0 zakończenie skanowania Analiza leksykalna i generator LEX (31/44) int suma = 0; [0-9]+ { int liczba; sscanf(yytext,"%d",&liczba); suma += liczba; " " ; int yywrap(void) { printf("suma = %d\n",suma); return 1; Analiza leksykalna i generator LEX (32/44) Białe spacje Komentarze (#1/5) w większości języków programowania białe spacje służą tylko poprawie czytelności programu (wyjątkami są np. Fortran i AWK) analizator leksykalny je pomija (ukrywa przed analizatorem składniowym) [ \t\n] ; problem: pomijanie niezagnieżdżonych komentarzy języka Pascal rozwiązanie z użyciem wzorca typowy błąd \{.+\ ; wejście x{zm:={podst1 {st ; oczekiwane wyjście x:=1 ; rzeczywiste wyjście x ; Analiza leksykalna i generator LEX (33/44) Analiza leksykalna i generator LEX (34/44) Komentarze (#2/5) Komentarze (#3/5) problem: pomijanie niezagnieżdżonych komentarzy języka Pascal rozwiązanie z użyciem wzorca rozwiązanie poprawne \{[^]+\ ; rozwiązanie z wykorzystaniem wzorców jest nieefektywne (niepotrzebnie gromadzi rozpoznawany tekst w buforze) Analiza leksykalna i generator LEX (35/44) problem: pomijanie niezagnieżdżonych komentarzy języka C (standard ANSI) rozwiązanie z użyciem stanów %s comment <0>"/*" BEGIN comment; <comment>. ; <comment>"*/" BEGIN 0; rozwiązanie z użyciem stanów jest efektywniejsze (szybsze, nie gromadzimy tekstu) i łatwo można je rozbudować o możliwość obsługi zagnieżdżonych komentarzy Analiza leksykalna i generator LEX (36/44) 6

Komentarze (#4/5) Komentarze (#5/5) problem: pomijanie zagnieżdżonych komentarzy języka C (rozszerzenie standardu ANSI) int CommentLevel; %s comment <0>"/*" { CommentLevel = 1; BEGIN comment; <comment>"/*" { CommentLevel++; <comment>. { ; <comment>"*/" { if( (--CommentLevel) == 0)BEGIN 0; Analiza leksykalna i generator LEX (37/44) prawdziwy problem: pomijanie zagnieżdżonych komentarzy dwóch różnych typów w języku Pascal (* i *) oraz { i przykładowe wejście: var x : integer; begin x{zm:={p(*ods*)t1{st; end. rozwiązanie:? Analiza leksykalna i generator LEX (38/44) Rozpoznawanie słów kluczowych (#1/3) Rozpoznawanie słów kluczowych (#2/3) usunąć z programu wszystkie identyfikatory z wyjątkiem słów kluczowych begin i end prototyp rozwiązania ident [a-za-z][a-za-z0-9]* {ident ; [bb][ee][gg][ii][nn] ECHO; [ee][nn][dd] ECHO; Analiza leksykalna i generator LEX (39/44) problem: wejście begin var:=x+y; end. oczekiwane wyjście begin :=+; end. rzeczywiste wyjście :=+;. Analiza leksykalna i generator LEX (40/44) Rozpoznawanie słów kluczowych (#3/3) Odrzucenie dopasowanie REJECT (#1/3) usunąć z programu wszystkie identyfikatory z wyjątkiem słów kluczowych begin i end rozwiązanie poprawne ident [a-za-z][a-za-z0-9]* [bb][ee][gg][ii][nn] ECHO; [ee][nn][dd] ECHO; {ident ; Analiza leksykalna i generator LEX (41/44) program zliczający liczbę wystąpień słów he i she prototyp rozwiązania int she = 0, he = 0; she { she++; he { he++;. \n { ; int yywrap(void) { printf("he (%d) she (%d)",he,she); return 1; Analiza leksykalna i generator LEX (42/44) 7

Odrzucenie dopasowanie REJECT (#2/3) Odrzucenie dopasowanie REJECT (3/3) problem: wejście hesheheshe oczekiwane wyjście he (4) she (2) rzeczywiste wyjście he (2) she (2) Analiza leksykalna i generator LEX (43/44) program zliczający liczbę wystąpień słów he i she poprawne rozwiązanie z użyciem REJECT int she = 0, he = 0; she { she++; REJECT; he { he++;. \n { ; int yywrap(void) { printf("he (%d) she (%d)",he,she); return 1; Analiza leksykalna i generator LEX (44/44) 8