Metody kompilacji Wykłady 4-5

Podobne dokumenty
Metody Kompilacji Wykład 8 Analiza Syntaktyczna cd. Włodzimierz Bielecki WI ZUT

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

Metody Kompilacji Wykład 1 Wstęp

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

Metody Kompilacji Wykład 7 Analiza Syntaktyczna

Metody Kompilacji Wykład 13

Zadanie analizy leksykalnej

Metody Kompilacji Wykład 3

Podstawy programowania skrót z wykładów:

Języki programowania zasady ich tworzenia

L E X. Generator analizatorów leksykalnych

Języki formalne i automaty Ćwiczenia 6

Matematyczne Podstawy Informatyki

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

Program We Kompilator Wy Źródłowy

Stałe i zmienne znakowe. Stała znakowa: znak

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

Podstawy Kompilatorów

INFORMATYKA Studia Niestacjonarne Elektrotechnika

Generatory analizatorów

Semantyka i Weryfikacja Programów - Laboratorium 6

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

Wstęp do programowania

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

Parsery LL(1) Teoria kompilacji. Dr inż. Janusz Majewski Katedra Informatyki

INSTRUKCJA PUSTA. Nie składa się z żadnych znaków i symboli, niczego nie robi. for i := 1 to 10 do {tu nic nie ma};

Podstawy Kompilatorów

Opis: Instrukcja warunkowa Składnia: IF [NOT] warunek [AND [NOT] warunek] [OR [NOT] warunek].

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

Laboratorium z użyciem analizatora leksykalnego FLEX

Biblioteka standardowa - operacje wejścia/wyjścia

Reprezentacja symboli w komputerze. Znaki alfabetu i łańcuchy znakowe. Programowanie Proceduralne 1

Python wprowadzenie. Warszawa, 24 marca PROGRAMOWANIE I SZKOLENIA

Analiza leksykalna i generator LEX

1 Podstawy c++ w pigułce.

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 1. Karol Tarnowski A-1 p.

Laboratorium 6: Ciągi znaków. mgr inż. Leszek Ciopiński dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

Algorytm. a programowanie -

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

Zmienne, stałe i operatory

Podstawy programowania w języku C i C++

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

Programowanie w językach wysokiego poziomu

Przykład: Σ = {0, 1} Σ - zbiór wszystkich skończonych ciagów binarnych. L 1 = {0, 00, 000,...,1, 11, 111,... } L 2 = {01, 1010, 001, 11}

Paradygmaty i języki programowania. Analiza leksykalna Skaner, RE, DAS, NAS, ε- NAS

Języki formalne i automaty Ćwiczenia 4

ECDL Podstawy programowania Sylabus - wersja 1.0

#include <stdio.h> void main(void) { int x = 10; long y = 20; double s; s = x + y; printf ( %s obliczen %d + %ld = %f, Wynik, x, y, s ); }

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Podstawy Programowania ELEMENTY PROGRAMU i TYPY DANYCH

Podstawy programowania w C++

KONSTRUKCJA KOMPILATORÓW

2 Przygotował: mgr inż. Maciej Lasota

Laboratorium 3: Tablice, tablice znaków i funkcje operujące na ciągach znaków. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

iii. b. Deklaracja zmiennej znakowej poprzez podanie znaku

Elementy języka C. ACprogramislikeafastdanceonanewlywaxeddancefloorbypeople carrying razors.

Wstęp do programowania. Wykład 1

Powtórka algorytmów. Wprowadzenie do języka Java.

Gramatyki atrybutywne

Generator skanerów Flex

Języki formalne i automaty Ćwiczenia 1

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

Nazwa implementacji: Nauka języka Python wyrażenia warunkowe. Autor: Piotr Fiorek. Opis implementacji: Poznanie wyrażeń warunkowych if elif - else.

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Microsoft IT Academy kurs programowania

Jerzy Nawrocki, Wprowadzenie do informatyki

Funkcje w PL/SQL Funkcja to nazwany blok języka PL/SQL. Jest przechowywana w bazie i musi zwracać wynik. Z reguły, funkcji utworzonych w PL/SQL-u

OPERACJE WEJŚCIA / WYJŚCIA. wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout)

Podstawy Programowania C++

Przedstawię teraz tzw. podstawowe symbole wyrażenia regularne (BRE, Basic Regular Expression)

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

1 Podstawy c++ w pigułce.

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Wprowadzenie do analizy leksykalnej. Bartosz Bogacki.

ZADANIA Z AUTOMATU SKOŃCZONEGO SPRAWOZDANIE NR 4

Podstawy generatora YACC. Bartosz Bogacki.

#include <stdio.h> int main( ) { int x = 10; long y = 20; double s; s = x + y; printf ( %s obliczen %d + %ld = %f, Wynik, x, y, s ); }

Autor: dr inż. Katarzyna Rudnik

Struktury, unie, formatowanie, wskaźniki

Podstawy Programowania Podstawowa składnia języka C++

KURS C/C++ WYKŁAD 2. char znak; znak = a ; Program 2 #include<stdio.h> void main() { char znak; while( (znak = getchar() )!= t ) putchar(znak); }

Podstawy programowania C. dr. Krystyna Łapin

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Wskaźniki w C. Anna Gogolińska

Języki programowania. Przetwarzanie plików amorficznych Konwencja języka C. Część siódma. Autorzy Tomasz Xięski Roman Simiński

Typy danych, zmienne i tablice. Tomasz Borzyszkowski

JAO - Wprowadzenie do Gramatyk bezkontekstowych

Podstawy programowania w języku C

10. Translacja sterowana składnią i YACC

Operatory. Operatory bitowe i uzupełnienie informacji o pozostałych operatorach. Programowanie Proceduralne 1

Język programowania zbiór reguł określających, które ciągi symboli tworzą program komputerowy oraz jakie obliczenia opisuje ten program.

Maszyna Turinga. Algorytm. czy program???? Problem Hilberta: Przykłady algorytmów. Cechy algorytmu: Pojęcie algorytmu

Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory

int tab[5]; tab[1]; ciągły obszar pamięci, w którym umieszczone są elementy tego samego typu macierz [ ] - dwuargumentowy operator indeksowania

Skrypty powłoki Skrypty Najcz ciej u ywane polecenia w skryptach:

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

Bloki anonimowe w PL/SQL

KURS C/C++ WYKŁAD 1. Pierwszy program

Transkrypt:

Metody kompilacji Wykłady 4-5

Analiza Leksykalna Wstęp Analizator leksykalny odczytuje znaki z wejścia, rozpoznaje leksemy i produkuje tokeny. Wraz z symbolem terminalnym, który jest używany przez parser, token zawiera dodatkowe informacje w postaci wartości atrybutów. Token jest to terminal wraz z dodatkową informacją. Włodzimierz Bielecki WI ZUT 2

ANALIZA LEKSYKALNA Program źródłowy Analizator leksykalny Parser Tablice symboli Włodzimierz Bielecki WI ZUT 3

Wstęp Analiza Leksykalna Sekwencja znaków wejściowych, która zawiera pojedynczy token nazywa się leksemem. Tak więc, można powiedzieć, że analizator leksykalny izoluje parser od reprezentacji znakowej symbolu, czyli parser dostaje tokeny, nie znaki. Włodzimierz Bielecki WI ZUT 4

ANALIZA LEKSYKALNA Głównym zadaniem analizatora leksykalnego jest wczytywanie znaków z programu źródłowego, rozpoznawanie leksemów i produkowanie tokenów(znaczników) dla każdego leksemu. Włodzimierz Bielecki WI ZUT 5

ANALIZA LEKSYKALNA Inne zadania: Wyeliminowanie komentarzy i znaków białych : spacja, znak nowej linii, znak tabulacji. Kolejnym zadaniem jest współudział w obsłudze błędów generowanych przez kompilator. Włodzimierz Bielecki WI ZUT 6

ANALIZA LEKSYKALNA Na przykład, analizator leksykalny może śledzić liczbę linijek kodu, liczbę znaków każdej linijki i przekazywać te dane do kompilatora. Włodzimierz Bielecki WI ZUT 7

ANALIZA LEKSYKALNA Dlaczego analizator leksykalny jest tworzony osobno 1. Prostota projektowania analizatora leksykalnego(w stosunku do projektowania analizatora syntaktycznego) jest najważniejszym czynnikiem. Włodzimierz Bielecki WI ZUT 8

ANALIZA LEKSYKALNA Dlaczego analizator leksykalny jest tworzony osobno 2. Zwiększona wydajność kompilatora. Opracowane są wyspecjalizowane bardzo wydajne techniki analizy leksykalnej. Ponadto techniki buforowania do wczytywania znaków wejściowych mogą przyspieszyć kompilator znacząco. Włodzimierz Bielecki WI ZUT 9

ANALIZA LEKSYKALNA Dlaczego analizator leksykalny jest tworzony osobno 3. Kompilator ma zwiększoną przenośność czyli może być stosowany na różnych platformach. Specyficzne dla urządzeń wejścia osobliwości mogą być uwzględnione tylko w analizatorze leksykalnym, pozostałe części kompilatora zostają bez zmian. Włodzimierz Bielecki WI ZUT 10

ANALIZA LEKSYKALNA Tokeny(Tokens), Wzorce(Patterns), Leksemy(Lexemes) Token jest parą składającą się z nazwy symbolicznej i opcjonalnej wartości atrybutu. Włodzimierz Bielecki WI ZUT 11

ANALIZA LEKSYKALNA Tokeny, Wzorce, Leksemy Wzorzec jest opisem postaci, którą leksem może przyjąć. W przypadku słów kluczowych, wzorzec jest po prostu ciągiem znaków, które tworzą słowa kluczowe. Włodzimierz Bielecki WI ZUT 12

ANALIZA LEKSYKALNA Tokeny, Wzorce, Leksemy Leksem jest ciągiem znaków w programie źródłowym, który pasuje do jakiegoś wzorca. Jest to niepodzielny element programu, dlatego jest nazywany również atomem. Włodzimierz Bielecki WI ZUT 13

ANALIZA LEKSYKALNA Tokeny, Wzorce, Leksemy Token Leksem Wzorzec if if if id abc, n, count, litera +cyfra NUMBER 3.14, 1000 stała numeryczna ; ; ; Włodzimierz Bielecki WI ZUT 14

ANALIZA LEKSYKALNA Tokeny, Wzorce, Leksemy Dla kodu: printf ("Total = %d\n, score) ; zarówno printf i score są leksemami pasującymi do wzorca dla tokena id, "Total = %d\n jest to leksem pasujący do literału( dosłowny tekst). Włodzimierz Bielecki WI ZUT 15

ANALIZA LEKSYKALNA Tokeny, Wzorce, Leksemy W wielu językach programowania, następujące przypadki obejmują większość tokenów: 1. Jeden token dla każdego słowa kluczowego. Wzorzec dla słowa kluczowego jest taki sam jak słowo kluczowe. Włodzimierz Bielecki WI ZUT 16

ANALIZA LEKSYKALNA Tokeny, Wzorce, Leksemy 2. Tokeny dla operatorów: indywidualnie dla każdego operatora lub jeden token dla grupy operatorów(przykładowo operatorów relacji). Włodzimierz Bielecki WI ZUT 17

ANALIZA LEKSYKALNA Tokeny, Wzorce, Leksemy 3. Jeden token reprezentujący wszystkie identyfikatory. 4. Jeden lub więcej tokenów reprezentujących stałe, takie jak liczby i literały. 5. Tokeny dla każdego z symboli interpunkcyjnych, takich jak lewy i prawy nawiasy, przecinek, średnik. Włodzimierz Bielecki WI ZUT 18

ANALIZA LEKSYKALNA Atrybuty tokenów Token posiada opcjonalne atrybuty. Najważniejszym przykładem jest token id, z którym musimy skojarzyć dużo informacji: typ danych, wymiar tablicy, liczba elementów tablicy, miejsce w programie, w którym zmienna się pojawia po raz pierwszy.. Włodzimierz Bielecki WI ZUT 19

ANALIZA LEKSYKALNA Atrybuty tokenów Atrybuty są przechowywane w tablicy symboli. Tak więc jednym z atrybutów jest również wskaźnik do wejścia tablicy symboli dla identyfikatora. Włodzimierz Bielecki WI ZUT 20

ANALIZA LEKSYKALNA Atrybuty tokenów Przykład: dla instrukcji przypisania w Fortranie E = M * C ** 2 mamy następujący wynik produkowany przez analizator leksykalny: Włodzimierz Bielecki WI ZUT 21

ANALIZA LEKSYKALNA Atrybuty tokenów <id, pointer to symbol-table entry for E > < assign_op > <id, pointer to symbol-table entry for M > <mult_op> <id, pointer to symbol-table entry for C > <exp-op> <number, integer value 2 > Włodzimierz Bielecki WI ZUT 22

ANALIZA LEKSYKALNA Błędy leksykalne (Lexical errors) Wykrywanie błędów fi(a==f(x)) Raportowanie błędów Usuwanie błędów Włodzimierz Bielecki WI ZUT 23

ANALIZA LEKSYKALNA Usuwanie błędów Załóżmy, że analizator leksykalny podczas rozpoznawania leksemu nie może kontynuować swojego działania, ponieważ żaden ze wzorców nie pasuje. Analizator może usunąć kolejne znaki z pozostałego wejścia, aż potrafi dopasować wczytywane znaki do jakiegoś wzorca. Włodzimierz Bielecki WI ZUT 24

Analiza Leksykalna Analizator leksykalny, który będziemy tworzyć, pozwala na rozpoznawanie liczb, identyfikatorów i znaków białych" (spacje, tabulatory i znaki nowej linii) w wyrażeniach. Włodzimierz Bielecki WI ZUT 25

Analiza Leksykalna Schemat translacji expr ->expr + term { print ('+') expr - term { print('-') term term -> term * factor { print('*') term / factor { print ( / ) factor factor -> ( expr ) num { print (num. value) id { print (id. lexeme) Włodzimierz Bielecki WI ZUT 26

Analiza Leksykalna Usuwanie znaków białych Większość języków umożliwia dowolną ilość przestrzeni białej między leksemami. Komentarze mogą być traktowane jako przestrzeń biała. Włodzimierz Bielecki WI ZUT 27

Analiza Leksykalna Usuwanie znaków białych Jeśli przestrzeń biała jest eliminowana przez analizator leksykalny, to parser nie będzie musiał brać pod uwagę znaków białych. Alternatywą jest uwzględnienie znaków białych w gramatyce ale to znacznie zwiększa złożoność parsera. Włodzimierz Bielecki WI ZUT 28

Analiza Leksykalna Pseudokod rozpoznawania i usuwania znaków białych: for ( ; ; peek = next input character ) { if ( peek is a blank or a tab ) do nothing; else if ( peek is a newline ) line = line+1; else break; Włodzimierz Bielecki WI ZUT 29

Analiza Leksykalna Czytanie z wyprzedzeniem Analizator leksykalny może wymagać odczytywania znaków wejściowych z wyprzedzeniem, zanim zdecyduje jaki ma być leksem właściwy. Na przykład, analizator leksykalny dla C lub Javy po rozpoznaniu znaku > musi odczytać następny znak. Włodzimierz Bielecki WI ZUT 30

Analiza Leksykalna Czytanie z wyprzedzeniem Jeśli następnym znakiem jest =, to znak > jest częścią sekwencji znaków >=, reprezentujących leksem (operator) "większe lub równe". Inaczej znak > sam tworzy leksem "większy niż ; w takim przypadku analizator leksykalny odczytał jeden znak za dużo. Włodzimierz Bielecki WI ZUT 31

Analiza Leksykalna Czytanie z wyprzedzeniem Ogólne podejście do czytania znaków wejścia z wyprzedzeniem jest oparte na zastosowaniu bufora wejściowego, z którego analizator leksykalny może odczytać znak i zapisać go z powrotem. Włodzimierz Bielecki WI ZUT 32

Analiza Leksykalna Czytanie z wyprzedzeniem Bufory wejściowe mogą być uzasadnione również względem efektywności analizatora ponieważ pobieranie ciągu znaków jest zwykle bardziej wydajne niż odczyt jednego znaku na raz. Włodzimierz Bielecki WI ZUT 33

Analiza Leksykalna Czytanie z wyprzedzeniem Wskaźnik śledzi część wejścia, która już została przeanalizowana; przejście do poprzedniego znaku jest realizowane przez przesunięcie wskaźnika do tyłu. Włodzimierz Bielecki WI ZUT 34

Analiza Leksykalna Czytanie z wyprzedzeniem Jeden znak odczytany z wyprzedzeniem zazwyczaj wystarcza, więc prostym rozwiązaniem jest użycie zmiennej, powiedzmy o nazwie peek, do przechowywania następnego znaku wejściowego. Włodzimierz Bielecki WI ZUT 35

Analiza Leksykalna Czytanie z wyprzedzeniem Analizator leksykalny czyta naprzód tylko wtedy, gdy musi. Operatora * można użyć aby nie odczytywać następnego znaku. W takich przypadkach wartością zmiennej peek jest znak spacji, który może być pominięty gdy analizator jest wywoływany aby znaleźć następny leksem. Włodzimierz Bielecki WI ZUT 36

Analiza Leksykalna Rozpoznawanie stałych Za każdym razem, gdy w wyrażeniu pojawia się pojedyncza cyfra, rozsądnym wydaje się wczytywanie kolejnych cyfr celem rozpoznania liczby całkowitej ponieważ jest ona sekwencją cyfr. Włodzimierz Bielecki WI ZUT 37

Analiza Leksykalna Rozpoznawanie stałych Stałe całkowite mogą być reprezentowane przez utworzenie symbolu terminalnego, powiedzmy o nazwie num dla każdej stałej, lub wprowadzając składnię stałych całkowitych do gramatyki. Włodzimierz Bielecki WI ZUT 38

Analiza Leksykalna Rozpoznawanie stałych Praca łączenia cyfr w liczbę z reguły należy do zadań analizatora leksykalnego, więc liczby mogą być traktowane jako pojedyncze jednostki(leksemy) w trakcie parsowania i tłumaczenia kodu źródłowego. Włodzimierz Bielecki WI ZUT 39

Analiza Leksykalna Rozpoznawanie stałych Kiedy pojawia się ciąg cyfr w strumieniu wejściowym, analizator leksykalny przekazuje do parsera token, który składa się z terminala num wraz z atrybutem rozpoznanej liczby całkowitej. Włodzimierz Bielecki WI ZUT 40

Analiza Leksykalna Rozpoznawanie stałych Dla napisu wejściowego 31 + 28 + 59 analizator leksykalny produkuje następujący wynik: <num,31> <+> <num,28> <+> <num,59> Włodzimierz Bielecki WI ZUT 41

Analiza Leksykalna Pseudokod do rozpoznawania stałych if ( peek holds a digit ) { v = 0; do { v = v * 10 + integer value of digit peek; peek = next input character; while ( peek holds a digit ) ; return token (num, v); Włodzimierz Bielecki WI ZUT 42

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych Większość języków używa słów kluczowych, na przykład: for, do, if, while,. które są reprezentowane przez ciągi znaków. Włodzimierz Bielecki WI ZUT 43

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych Ciągi znaków są również wykorzystywane do tworzenia nazw zmiennych, tablic, funkcji i t. d. Żeby uprościć parser, gramatyki traktują identyfikatory jako terminal, powiedzmy id, za każdym razem, gdy identyfikator pojawi się na wejściu. Włodzimierz Bielecki WI ZUT 44

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych Na przykład dla wejścia: count = count + increment; parser dostanie od analizatora leksykalnego następujący ciąg tokenów: id = id + id. Dla tokena id atrybutem jest leksem reprezentujący identyfikator. Włodzimierz Bielecki WI ZUT 45

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych Dla wejścia count = count + increment; Analizator leksykalny produkuje: id, "count " = id, "count " + id, "increment " ; Włodzimierz Bielecki WI ZUT 46

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych Słowa kluczowe generalnie spełniają zasady tworzenia identyfikatorów, więc jest potrzebny mechanizm do podjęcia decyzji: leksem reprezentuje słowo kluczowe czy identyfikator. Włodzimierz Bielecki WI ZUT 47

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych Problem jest łatwiejszy do rozwiązania, jeśli słowa kluczowe są zastrzeżone: nie mogą one być wykorzystywane jako identyfikatory. Ciąg znaków tworzy identyfikator jeżeli nie reprezentuje on słowo kluczowe. Włodzimierz Bielecki WI ZUT 48

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych Analizator leksykalny rozwiązuje ten problem za pomocą tablicy do przechowywania ciągów znaków, czyli symboli. Włodzimierz Bielecki WI ZUT 49

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych 1. Tablica symboli może izolować resztę kompilatora z reprezentacji ciągów, fazy kompilatora mogą korzystać z referencji lub wskaźnika do łańcucha w tabeli. Referencje/wskaźniki mogą być bardziej efektywne niż manipulowanie samymi ciągami. Włodzimierz Bielecki WI ZUT 50

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych 2. Tablica symboli może być inicjalizowana słowami zarezerwowanymi. Włodzimierz Bielecki WI ZUT 51

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych Kiedy analizator leksykalny rozpoznaje leksem, który może stanowić identyfikator, najpierw sprawdza, czy leksem jest przechowywany w tablicy symboli. Jeżeli tak, to zwraca token przechowywany w tablicy; w przeciwnym razie tworzy i zwraca token, którego pierwszym elementem jest id. Włodzimierz Bielecki WI ZUT 52

Analiza Leksykalna Rozpoznawanie identyfikatorów i słów kluczowych Tablica symboli może być zaimplementowana jako tablica haszująca z użyciem klasy o nazwie Hashtable. Na przykład: Hashtable words = new Hashtable(); Włodzimierz Bielecki WI ZUT 53

Pseudokod do rozpoznawania identyfikatorów i słów kluczowych if ( peek holds a letter ) { collect letters or digits into a buffer b; s = string formed from the characters in b; w = token returned by words.get(s); if ( w is not null ) return w; else { Enter the key-value pair (s, id, s ) into words return token id, s ; Włodzimierz Bielecki WI ZUT 54

Analiza Leksykalna Pseudokod funkcji scan, która zwraca tokeny Token scan() { skip white space; handle numbers; handle reserved words and identifiers; /* if we get here, treat read-ahead character peek as a token */ Token t = new Token(peek); peek = blank return t; Włodzimierz Bielecki WI ZUT 55

Analizator leksykalny w C int lineno = 1; int tokenval = NONE; int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { tokenval = t '0'; t = getchar(); while (isdigit(t)) { tokenval = tokenval*10 + t '0'; t = getchar(); ungetc (t, stdin); return NUM; else { tokenval = NONE; return t; Włodzimierz Bielecki WI ZUT 56

Analizator leksykalny w C int lineno = 1; int tokenval = NONE; int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { tokenval = t '0'; t = getchar(); while (isdigit(t)) { tokenval = tokenval*10 + t '0'; t = getchar(); ungetc (t, stdin); return NUM; else { tokenval = NONE; return t; Numer aktualnie analizowanego wiersza Włodzimierz Bielecki WI ZUT 57

Analizator leksykalny w C int lineno = 1; int tokenval = NONE; int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { tokenval = t '0'; t = getchar(); while (isdigit(t)) { tokenval = tokenval*10 + t '0'; t = getchar(); ungetc (t, stdin); return NUM; else { tokenval = NONE; return t; Atrybut symbolu leksykalnego Włodzimierz Bielecki WI ZUT 58

Analizator leksykalny w C int lineno = 1; int tokenval = NONE; int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { tokenval = t '0'; t = getchar(); while (isdigit(t)) { tokenval = tokenval*10 + t '0'; t = getchar(); ungetc (t, stdin); return NUM; else { tokenval = NONE; return t; Pobierz jeden znak Włodzimierz Bielecki WI ZUT 59

Analizator leksykalny w C int lineno = 1; int tokenval = NONE; int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { tokenval = t '0'; t = getchar(); while (isdigit(t)) { tokenval = tokenval*10 + t '0'; t = getchar(); ungetc (t, stdin); return NUM; else { tokenval = NONE; return t; Jeżeli t jest białym znakiem, pomiń znak Włodzimierz Bielecki WI ZUT 60

Analizator leksykalny w C int lineno = 1; int tokenval = NONE; int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { tokenval = t '0'; t = getchar(); while (isdigit(t)) { tokenval = tokenval*10 + t '0'; t = getchar(); ungetc (t, stdin); return NUM; else { tokenval = NONE; return t; Jeżeli t jest znakiem nowej linii, zwiększ numer aktualnie analizowanego wiersza Włodzimierz Bielecki WI ZUT 61

Analizator leksykalny w C int lineno = 1; int tokenval = NONE; int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { tokenval = t '0'; t = getchar(); while (isdigit(t)) { tokenval = tokenval*10 + t '0'; t = getchar(); ungetc (t, stdin); return NUM; else { tokenval = NONE; return t; Jeżeli t jest liczbą, zamień napis na wartość typu całkowitego Włodzimierz Bielecki WI ZUT 62

Analizator leksykalny w C int lineno = 1; int tokenval = NONE; int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { tokenval = t '0'; t = getchar(); while (isdigit(t)) { tokenval = tokenval*10 + t '0'; t = getchar(); ungetc (t, stdin); return NUM; else { tokenval = NONE; return t; Wczytany znak jest nieznanym symbolem Włodzimierz Bielecki WI ZUT 63

Tablica symboli Tablica symboli jest wykorzystywana do przechowywania zmiennych oraz słów kluczowych. Jest inicjalizowana poprzez wstawienie do niej słów kluczowych: Włodzimierz Bielecki WI ZUT 64

Tablica symboli int insert(const char* s, int t); /* zwraca indeks w tablicy symboli dla nowego leksemu s i tokenu t */ int lookup(const char* s); /* zwraca indeks wpisu dla leksemu s lub 0 gdy nie znaleziono */ insert("div", DIV); insert("mod", MOD); Włodzimierz Bielecki WI ZUT 65

Analizator leksykalny z tablicą symboli int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { ungetc (t, stdin); scanf ("%d", &tokenval); return NUM; else if (isalpha (t)) { int p, b = 0; while (isalnum (t)) { lexbuf[b] = t; t = getchar (); b++; if (b >= BSIZE) error ("compiler error"); lexbuf[b] = EOS; if (t!= EOF) ungetc (t, stdin); p = lookup (lexbuf); if (p == 0) p = insert (lexbuf, ID); tokenval = p; return symtable[p].token; else if (t == EOF) return DONE; else { tokenval = NONE; return t; Włodzimierz Bielecki WI ZUT 66

Analizator leksykalny z tablicą symboli int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { ungetc (t, stdin); scanf ("%d", &tokenval); return NUM; else if (isalpha (t)) { int p, b = 0; while (isalnum (t)) { lexbuf[b] = t; t = getchar (); b++; if (b >= BSIZE) error ("compiler error"); lexbuf[b] = EOS; if (t!= EOF) ungetc (t, stdin); p = lookup (lexbuf); if (p == 0) p = insert (lexbuf, ID); tokenval = p; return symtable[p].token; else if (t == EOF) return DONE; else { tokenval = NONE; return t; Jeżeli t jest identyfikatorem Włodzimierz Bielecki WI ZUT 67

Analizator leksykalny z tablicą symboli int lexan () { int t; while (1) { t = getchar (); if (t == ' ' t == '\t'); else if (t == '\n') lineno++; else if (isdigit (t)) { ungetc (t, stdin); scanf ("%d", &tokenval); return NUM; else if (isalpha (t)) { int p, b = 0; while (isalnum (t)) { lexbuf[b] = t; t = getchar (); b++; if (b >= BSIZE) error ("compiler error"); lexbuf[b] = EOS; if (t!= EOF) ungetc (t, stdin); p = lookup (lexbuf); if (p == 0) p = insert (lexbuf, ID); tokenval = p; return symtable[p].token; else if (t == EOF) return DONE; else { tokenval = NONE; return t; Jeżeli t jest znakiem końca pliku Włodzimierz Bielecki WI ZUT 68

ANALIZA LEKSYKALNA Ciągi znaków i języki (Strings and Languages) Alfabet jest to dowolny skończony zbiór symboli. Typowe przykłady symboli to są litery, cyfry i znaki interpunkcyjne. Zbiór {0,1 jest alfabetem binarnym. Znaki tablicy kodów ASCII tworzą ważny przykład alfabetu. Włodzimierz Bielecki WI ZUT 69

ANALIZA LEKSYKALNA Ciągi znaków i języki Napis (ciąg znaków, łańcuch) nad pewnym alfabetem jest to skończony ciąg symboli z tego alfabetu. Długość napisu s, zapisywana jako s, jest to liczba wystąpień symboli w napisie s. Włodzimierz Bielecki WI ZUT 70

ANALIZA LEKSYKALNA Ciągi znaków i języki Na przykład, napis banan ma długość 5. Pusty ciąg znaków, oznaczany jako, jest ciągiem o zerowej długości. Bardzo szeroka definicja języka: Język jest to zbiór napisów nad pewnym ustalonym alfabetem. Włodzimierz Bielecki WI ZUT 71

ANALIZA LEKSYKALNA Ciągi znaków i języki Przykład: dla alfabetu L = {A,..., Z, zbiór {A, B, C, BF,,ABZ, jest językiem zdefiniowanym przez alfabet L. Należy zauważyć, że definicja "języka" nie wymaga, aby każdy napis posiadał jakiś sens. Włodzimierz Bielecki WI ZUT 72

ANALIZA LEKSYKALNA Pojęcia związane z napisami Prefiks(przedrostek) napisu s jest to dowolny napis uzyskany przez usunięcie zero lub więcej symboli z końca s. Na przykład, ban, banana, and są prefiksami napisu banana. Włodzimierz Bielecki WI ZUT 73

ANALIZA LEKSYKALNA Pojęcia związane z napisami Sufiks(przyrostek) napisu s jest to dowolny napis uzyskany przez usunięcie zero lub więcej symboli z początku s. Na przykłąd, nana, banana, and są sufiksami napisu banana. Włodzimierz Bielecki WI ZUT 74

ANALIZA LEKSYKALNA Pojęcia związane z napisami Podnapis(podciąg spójny) napisu s jest uzyskiwany przez usuwanie jakichkolwiek przedrostków i przyrostków z s. Na przykład, banana, nan i są podnapisami napisu banana. Włodzimierz Bielecki WI ZUT 75

ANALIZA LEKSYKALNA Pojęcia związane z napisami Przedrostki, przyrostki i podnapisy napisu s są właściwe jeśli nie są napisami pustymi lub nie są równe s. Włodzimierz Bielecki WI ZUT 76

ANALIZA LEKSYKALNA Pojęcia związane z napisami Podciąg napisu s jest to dowolny ciąg utworzony przez usunięcie zero lub więcej nie koniecznie kolejnych znaków z s. Na przykład, baan jest podciągiem napisu banana. Włodzimierz Bielecki WI ZUT 77

ANALIZA LEKSYKALNA Pojęcia związane z napisami Złączenie (concatenation) napisów x i y jest to napis xy utworzony przez dodanie y na koniec do x. Na przykład jeśli x = dog i y = house, to xy = doghouse. Dla napisu pustego są sprawiedliwe równości: s = s = s. Włodzimierz Bielecki WI ZUT 78

ANALIZA LEKSYKALNA Pojęcia związane z napisami Podnoszenie napisu do potęgi definiujemy w następujący sposób: s 0 = s i = s i-1 s dla i > 0 Przykłady: s 1 = s, s 2 = ss, s 3 = sss. Włodzimierz Bielecki WI ZUT 79

ANALIZA LEKSYKALNA Operacje na językach Suma(Union) L M = {s s L or s M Złączenie (Concatenation) LM = {xy x L and y M Potęgowanie (Exponentiation) L 0 = { ; L i = L i-1 L Włodzimierz Bielecki WI ZUT 80

ANALIZA LEKSYKALNA Operacje na językach Domknięcie Kleen a (Kleene closure) L * = i=0,, L i Domknięcie dodatnie (Positive closure) L + = i=1,, L i Włodzimierz Bielecki WI ZUT 81

ANALIZA LEKSYKALNA Wyrażenia regularne (Regular Expressions) Podstawowe wyrażenia regularne: jest wyrażeniem regularnym oznaczającym język { a jest wyrażeniem regularnym oznaczającym język {a Włodzimierz Bielecki WI ZUT 82

ANALIZA LEKSYKALNA Wyrażenia regularne Jeśli r i s są wyrażeniami regularnymi oznaczającymi języki L(r) i M(s) to r s jest wyrażeniem regularnym oznaczającym język L(r) M(s) rs jest wyrażeniem regularnym oznaczającym język L(r)M(s) Włodzimierz Bielecki WI ZUT 83

ANALIZA LEKSYKALNA Wyrażenia regularne r * jest wyrażeniem regularnym oznaczającym język L(r) *. (r) jest wyrażeniem regularnym oznaczającym język L(r). Włodzimierz Bielecki WI ZUT 84

ANALIZA LEKSYKALNA Wyrażenia regularne Czyli wyrażenia regularne są budowane z mniejszych wyrażeń regularnych w sposób rekurencyjny. Włodzimierz Bielecki WI ZUT 85

ANALIZA LEKSYKALNA Wyrażenia regularne Wyrażenia regularne mogą zawierać zbędne pary nawiasów. Możemy usunąć niektóre pary nawiasów, jeśli przyjmiemy następującą konwencję: Włodzimierz Bielecki WI ZUT 86

ANALIZA LEKSYKALNA Wyrażenia regularne a) Operator jednoargumentowy * (operator domknięcia) ma najwyższy priorytet i jest łączny lewostronnie, b) Złączenie ma drugi najwyższy priorytet i jest łączne lewostronnie. Włodzimierz Bielecki WI ZUT 87

ANALIZA LEKSYKALNA Wyrażenia regularne Przykład : = {a, b. 1. Wyrażenie regularne a b oznacza język {a, b. 2. (a b) (a b) oznacza {aa, ab, ba, bb), czyli język, którego elementami są napisy o długości 2. Włodzimierz Bielecki WI ZUT 88

ANALIZA LEKSYKALNA Wyrażenia regularne 3. a* oznacza język, którego elementy są złożeniem zero lub więcej symboli a: {, a, aa, aaa,.... Włodzimierz Bielecki WI ZUT 89

ANALIZA LEKSYKALNA Wyrażenia regularne 4. (a b)* oznacza język, którego elementy są złożeniem zero lub więcej symboli a lub b : {, a, b, aa, ab, ba, bb, aaa,.... 5. a a*b oznacza język {a, b, ab, aab,aaab,... Włodzimierz Bielecki WI ZUT 90

ANALIZA LEKSYKALNA Wyrażenia regularne 4. (a b)* oznacza język, którego elementy są złożeniem zero lub więcej symboli a lub b : {, a, b, aa, ab, ba, bb, aaa,.... 5. a a*b oznacza język {a, b, ab, aab,aaab,... Włodzimierz Bielecki WI ZUT 91

Przykład Rozważmy alfabet = { a Jakie jest wyrażenie regularne, które oznacza język, którego każde słowo jest o długości nieparzystej??? Włodzimierz Bielecki WI ZUT 92

Przykład Rozważmy alfabet = { a a (aa)* jest wyrażeniem regularnym, które oznacza język, którego każde słowo jest o długości nieparzystej Włodzimierz Bielecki WI ZUT 93

Przykład Rozważmy alfabet = { a, b Jakie jest wyrażenie regularne, które oznacza język, którego każde słowo zaczyna się od litery b??? Włodzimierz Bielecki WI ZUT 94

Przykład Rozważmy alfabet = { a, b b (a b)* jest wyrażeniem regularnym, które oznacza język, którego każde słowo zaczyna się od litery b Włodzimierz Bielecki WI ZUT 95

Przykład Rozważmy alfabet = { a, b Jakie jest wyrażenie regularne, które oznacza język, którego każde słowo musi zaczynać się na literę a, a kończy się na literę b???? Włodzimierz Bielecki WI ZUT 96

Przykład Rozważmy alfabet = { a, b b (a b)* a jest wyrażeniem regularnym, które oznacza język, którego każde słowo musi zaczynać się na literę b, a kończy się na literę a Włodzimierz Bielecki WI ZUT 97

Przykład Rozważmy alfabet = { a, b, c Jakie jest wyrażenie regularne, które oznacza język: L = { a, c, ab, cb, abb, cbb, abbb, cbbb, abbbb, cbbbb...? Włodzimierz Bielecki WI ZUT 98

Przykład Rozważmy alfabet = { a, b, c ((a c) b*) oznacza język: L = { a, c, ab, cb, abb, cbb, abbb, cbbb, abbbb, cbbbb... Włodzimierz Bielecki WI ZUT 99

Dziękuję za uwagę Włodzimierz Bielecki WI ZUT 100