Metody Realizacji Języków Programowania

Podobne dokumenty
Metody Kompilacji Wykład 1 Wstęp

Analiza leksykalna i generator LEX

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

Generatory analizatorów

L E X. Generator analizatorów leksykalnych

Podstawy Kompilatorów

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

KONSTRUKCJA KOMPILATORÓW

Zadanie analizy leksykalnej

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

SYLABUS DOTYCZY CYKLU KSZTAŁCENIA Bieżący sylabus w semestrze zimowym roku 2016/17

Program We Kompilator Wy Źródłowy

Matematyczne Podstawy Informatyki

Laboratorium z użyciem analizatora leksykalnego FLEX

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

Języki programowania zasady ich tworzenia

Translacja wprowadzenie

Języki formalne i techniki translacji

Podstawy programowania - 1

Metody Realizacji Języków Programowania

Podstawy Kompilatorów

Flex - generator analizatorów leksykalnych

Wstęp do Programowania, laboratorium 02

Programowanie komputerów

Podstawy programowania (1)

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

Java EE produkcja oprogramowania

Programowanie w języku Python. Grażyna Koba

Generator skanerów Flex

Programowanie hybrydowe C (C++) - assembler. MS Visual Studio Inline Assembler

Metody Kompilacji Wykład 13

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

Microsoft IT Academy kurs programowania

Metody Realizacji Języków Programowania

Programowanie w C++ Wykład 1. Katarzyna Grzelak. 26 luty K.Grzelak (Wykład 1) Programowanie w C++ 1 / 28

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

Programowanie Proceduralne

Zmienne, stałe i operatory

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

10. Translacja sterowana składnią i YACC

Wstęp do programowania

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

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Wstęp do programowania. Wykład 1

Podstawy Kompilatorów

Programowanie niskopoziomowe

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

Zadanie 2: Arytmetyka symboli

Wstęp do programowania

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

1 Podstawy c++ w pigułce.

Skrypty i funkcje Zapisywane są w m-plikach Wywoływane są przez nazwę m-pliku, w którym są zapisane (bez rozszerzenia) M-pliki mogą zawierać

Programowanie obiektowe

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};

Metody Kompilacji Wykład 3

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

Podstawy Kompilatorów

Programowanie obiektowe

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

Algorytm. a programowanie -

Gramatyki atrybutywne

Podstawy Informatyki Języki programowania c.d.

Podstawy generatora YACC. Bartosz Bogacki.

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

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

Podstawy programowania funkcjonalnego

Semantyka i Weryfikacja Programów - Laboratorium 6

PARADYGMATY I JĘZYKI PROGRAMOWANIA. lex/flex i yacc/bison w- 4 (2014)

Wykład. Materiały bazują częściowo na slajdach Marata Dukhana

Wprowadzenie do języka Java

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

Język C zajęcia nr 7. Uwagi dotyczące stylu programowania

Przyczyny dwustopniowego tłumaczenia

Tablice, funkcje - wprowadzenie

Technologie cyfrowe semestr letni 2018/2019

4 Literatura. c Dr inż. Ignacy Pardyka (Inf.UJK) ASK MP.01 Rok akad. 2011/ / 24

Błędy leksykalne są na ogół nietrudne do znalezienia.

Język ludzki kod maszynowy

PARADYGMATY PROGRAMOWANIA Wykład 4

Podstawy programowania C. dr. Krystyna Łapin

MATERIAŁY DO ZAJĘĆ I. Podstawowe pojęcia. Algorytm. Spis treści Przepis

Podstawy programowania w języku C

Komentarze w PHP (niewykonywane fragmenty tekstowe, będące informacją dla programisty)

Wstęp do Informatyki dla bioinformatyków

Podstawy programowania w języku C++

Ćwiczenia nr 11. Translatory. Wprowadzenie teoretyczne

Programowanie w C++ Wykład 1. Katarzyna Grzelak. 25 luty K.Grzelak (Wykład 1) Programowanie w C++ 1 / 38

Generator analizatorów leksykalnych - Lex. Bartosz Bogacki.

Semantyka i Weryfikacja Programów - Laboratorium 3

Programowanie obiektowe

Tworzenie aplikacji w języku Java

Programowanie w Ruby

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

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Programowanie w języku C++ Grażyna Koba

Algorytmy od problemu do wyniku

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Spis treści. 1 Java T M

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

Wskaźniki w C. Anna Gogolińska

Transkrypt:

Metody Realizacji Języków Programowania Marcin Benke MIM UW 4 października 2010 Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 1 / 40

Co to jest kompilator? Program który tłumaczy programy w języku wyższego poziomu na kod maszynowy procesora (np 80x86, Sparc) lub maszyny wirtualnej (np. JVM). Istnieje wiele podobnych klas problemów/programów, gdzie analizujemy dane wejściowe (zwykle tekst) tłumaczymy na inny język. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 2 / 40

Co robi kompilator? Wczytuje program, zwykle jako tekst. Sprawdza poprawność i dokonuje analizy programu. Myśli chwilę. Generuje kod wynikowy (synteza). Części kompilatora realizujace analizę i syntezę określa się czasem nazwami front-end i back-end Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 3 / 40

Analiza analiza leksykalna podział na leksemy ( słowa ); analiza składniowa rozbiór struktury programu i jej reprezentacja w postaci drzewa; analiza semantyczna powiazanie użycia identyfikatorów z odpowiednimi deklaracjami; kontrola typów. Każda z faz analizy powinna dawać czytelne komunikaty o napotkanych błędach Trudne, ale bardzo ważne. Faza analizy jest niezależna od języka docelowego. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 4 / 40

Przykład Rozważmy prosty program w języku z rodziny C: int sumto(int n) { int i, sum; i = 0; sum = 0; while (i<n) { i = i+1; sum = sum+i; } return sum; } Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 5 / 40

Analiza leksykalna Dzielimy tekst na leksemy: int id sumto ( int id n ) { int id i, id sum ; id i = num 0 ; id sum = num 0 ; while ( id i < id n ) { id i = id i + num 1 ; id sum = id sum + id i ; } return id sum ; } Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 6 / 40

Analiza składniowa Następnym krokiem jest kontrola poprawności składniowej programu. Składnię języka opisujemy zwykle przy pomocy gramatyki, np: Stmt ::= while ( Exp ) Stmt Var=Exp ; return Exp { Stmts }... Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 7 / 40

Analiza składniowa Strumień leksemów zamieniamy na drzewo struktury: SWhile EBinOp SBlock id i < id n SAssign SAssign id i EBinOp id sum EBinOp id i + n 1 id sum + n 1 Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 8 / 40

Analiza semantyczna Analiza deklaracji Zapis informacji w tablicy symboli Kontrola poprawności użycia symboli i powiazanie z odpowiednimi deklaracjami (poprzez tablicę symboli). Kontrola (lub rekonstrukcja) typów. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 9 / 40

Synteza Transformacja drzewa struktury do postaci dogodnej do dalszych przekształceń (kod pośredni) Planowanie struktur czasu wykonania (rekordy aktywacji, etc.) Ulepszanie kodu ( optymalizacja ) Wybór instrukcji Alokacja rejestrów Generacja kodu Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 10 / 40

Maszyna stosowa Argumenty i wyniki operacji na stosie (+) Łatwo wygenerować kod z drzewa stuktury, np genintexp (EBinOp e1 op e2) = do genintexp e1 genintexp e2 intop op intop "+" = emit "iadd" ( ) Trudno optymalizować ( ) Realne procesory nie sa maszynami stosowymi Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 11 / 40

sumto dla maszyny stosowej (JVM).method public sumto()i iconst_0 istore_2 iconst_0 istore_3 L1: iload_2 iload_1 if_icmpge L2 iload_2 iconst_1 iadd istore_2 iload_3 iload_2 iadd istore_3 goto L1 L2: iload_3 ireturn.end method Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 12 / 40

sumto w asemblerze 80x86 (gas) sumto:.l5:.l4:.globl sumto movl 4(%esp), %ecx ; ecx = n xorl %eax, %eax ; eax = 0 testl %ecx, %ecx ; ecx <=0? jle.l4 ; skok do L4 xorl %edx, %edx ; edx = 0 addl $1,%edx ; edx += 1 addl %edx, %eax ; eax += eax cmpl %edx, %ecx ; edx!= n? jne.l5 ; skok do L5 ret ; powrót Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 13 / 40

Plan wykładu Analiza leksykalna (dziś) Analiza syntaktyczna (4 wykłady) Analiza semantyczna (2 wykłady) Kolokwium Środowisko czasu wykonania Generacja kodu Optymalizacja (2 wykłady) Obsługa wyjatków Zarzadzanie pamięcia Kompilacja języków funkcyjnych Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 14 / 40

Materiały http://moodle.mimuw.edu.pl http://www.mimuw.edu.pl/~ben/zajecia/mrj http://wazniak.mimuw.edu.pl A.V. Aho, M.S. Lam, R. Sethi, J.D. Ullman, Compilers: Principles, Techniques, and Tools, 2/E (w języku polskim dostępne jest tłumaczenie poprzedniego wydania: Kompilatory. Reguły, metody i narzędzia, Wydawnictwa Naukowo-Techniczne, Warszawa 2002). Materiały do wykładu pojawiaja się sukcesywnie na moodle.mimuw.edu.pl Ostateczna wersja notatek po wykładzie. Kontakt ze mna: ben@mimuw.edu.pl Konsultacje czwartki 1400-1530 pokój 5750, prosze się umawiać. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 15 / 40

Sprawy organizacyjne Wykład+ćwiczenia Kolokwium pod koniec listopada na wykładzie (kolokwium poprawkowe w styczniu,prawdopodobnie w sobotę). Laboratorium: piszemy kompilator dla prostego języka Na ocenę dst front-end + back-end dla VM. Na wyższa ocenę rozszerzenia języka, optymalizacje lub generacja kodu dla konkretnego procesora. Wiele możliwości, szczegóły później. Obecność (i aktywność!) na zajęciach jest wskazana. Prowadzacy maja prawo (a nawet obowiazek) skreślić osoby, które opuszcza bez usprawiedliwienia zbyt wiele zajęć. Proszę zadawać pytania! Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 16 / 40

Sondaż Czy jest ktoś, kto nie chodził na JPP? Jaki jest preferowany język programowania: C/C++ Java Haskell *ML Python Lisp/Scheme/Clojure inny Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 17 / 40

Analiza leksykalna Rodzaje leksemów Struktura leksykalna języka Analizatory leksykalne Generatory analizatorów leksykalnych Flex, Alex, Jlex,... Ta częśc kompilatora nazywana jest analizatorem leksykalnym, lub w skrócie lekserem Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 18 / 40

Podstawowe rodzaje leksemów Słowa kluczowe, np. for, do Identyfikatory, np. Foo, foo Operatory, np. ++, >>= Literały, np 3.14, \n, u"gżegżółka" znaki przestankowe, np. {, ; Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 19 / 40

Analiza leksykalna Dzielimy tekst na leksemy: int id sumto ( int id n ) { int id i, id sum ; id i = num 0 ; id sum = num 0 ; while ( id i < id n ) { id i = id i + num 1 ; id sum = id sum + id i ; } return id sum ; } Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 20 / 40

Leksemy Niektóre leksemy maja wartość semantyczna, np. id i, num 1 Można opisać przy pomocy wyrażeń regularnych, np. identyfikator = [a-za-z][a-za-z0-9]* Można rozpoznać przy pomocy DFA. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 21 / 40

Reguła najdłuższego dopasowania Zwykle wyrażenia regularne opisujace leksemy pozwalaja na kilka różnych podziałów tekstu na leksemy, np. --a - - id a lub -- id a j23 id j num 23 lub id j23 Zawsze wybieramy najdłuższe możliwe dopasowanie. Drugi przykład pokazuje wyraźnie dlaczego. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 22 / 40

Odstępy Znaki takie jak spacja, TAB, koniec linii zwykle sa pomijane, moga jednak służyć do rozdzielania leksemów, np. a++3 vs a + +3 Leksem może przechowywać swoja pozycję (wiersz, kolumna) w pliku źródłowym, np. dla celów raportowania błędów. W niektórych językach pozycje niektórych leksemów moga wpływać na rozbiór i znaczenie programu (np. Python, Haskell) Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 23 / 40

Układ (Python) Przykład (Python) for a, v in attrs: f(a,v) self.output( %s="%s" %(a,v)) self.output( > ) W tym przykładzie wcięcie determinuje zasięg pętli. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 24 / 40

Układ (Haskell) Znajdź szczegół różniacy poniższe programy: len xs = case xs of [] -> 0 _:ys -> n+1 where n = len ys len xs = case xs of [] -> 0 _:ys -> n+1 where n = len ys Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 25 / 40

Układ (Haskell) Pierwszy program odpowiada ciagowi leksemów takiemu jak: len xs = case xs of { [] -> 0 ; _:ys -> n+1 where {n = len ys} } Drugi zaś len xs = case xs of {[] -> 0 ; _:ys -> n+1 } where {n = len ys} (i jest niepoprawny) Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 26 / 40

Komentarze Przeważnie sa pomijane (traktowane jako odstęp). Czasem moga zawierać wskazówki dla kompilatora (pragmy), np {-# OPTIONS -fglasgow-exts #-} Dwa rodzaje: do końca linii i nawiasowe. Te drugie moga być zagnieżdżane: /* Socket* foo(addr& a) { /* TcpSocket *s; */ Socket s = new UdpSocket(); s->connect(a); return s; } */ Język zagnieżdżonych komentarzy może nie być regularny, zwykle jednak jest rozpoznawany przez lekser przy użyciu dodatkowego licznika. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 27 / 40

Lekser mozna napisać ręcznie...... wystarczy zakodować wszystkie przypadki: lextoken "" = (EOT,"") lextoken s@(c:cs) = case c of c isspace c -> lextoken cs isdigit c -> case lexint s of (IntTok i,. :sfrac) -> lexfloat s x -> x islower c -> let(vid, rest) = span isidentchar s in case lookup vid keywords of Just keyword -> (keyword,rest) Nothing -> (VarId vid, rest) otherwise -> (ErrTok $ msg, rest) where msg = "Unexpected "++[c]++" in "++word (word,rest) = span (not.isspace) s... Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 28 / 40

Generatory analizatorów leksykalnych Pisanie analizatora leksykalnego jest zwykle żmudne. Dlatego przeważnie jest on generowany automatycznie przez narzędzia takie jak Flex (C,C++), JLex (Java), Alex (Haskell), Ocamllex, C#Lex,... Narzędzia takie generuja program realizujacy automat rozpoznajacy leksemy na podstawie opisu złożonego z wyrażeń regularnych i przypisanych im akcji. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 29 / 40

Ogólna postać definicji leksera definicje %% reguły (wzorce+akcje) %% funkcje pomocnicze (w C) W sekcji definicji moga się pojawić definicje klas znaków, np. CYFRA [0-9] LITERA [A-Za-z] a także deklaracje opcji Flexa oraz używanych dalej zmiennych i funkcji (te ostatnie musza być wcięte lub ujęte między znaczniki %{ i %}. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 30 / 40

Wzorce x znak x. dowolny znak (oprócz \n) [xyz] dowolny znak spośród x,y,z [abj-o] klasa znaków: a,b, od j do o [ˆA-Z] dopełnienie klasy znaków r* zero lub więcej r r+ jedno lub więcej r r? zero lub jedno r r{2,5} r od 2 do 5 razy {4} r dokładnie 4 razy rs konkatenacja r i s r s r lub s r/s r w kontekście s ˆr r na poczatku linii r$ r na końcu linii Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 31 / 40

Wywoływanie leksera: yylex() lc.l int lines = 0, chars = 0 ; %option noyywrap %% \n ++lines ; ++ chars ;. ++chars ; %% void main() { yylex() ; printf("lines: %d, chars: %d\n", lines, chars) ; } Opcja noyywrap powoduje, że lekser nie wywołuje yywrap() przy napotkaniu EOF, ale zakłada, ze nie ma więcej plików do analizy. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 32 / 40

Zawartość leksemu: zmienna yytext %option main int suma=0 ; %% [0-9]+ suma += atoi(yytext) ; suma printf("%d\n", suma) ; \n. /* nic */ >./dodaj 11 22 33 suma 66 Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 33 / 40

Klasy znaków i wspólne akcje %option main CYFRA [0-9] double suma=0 ; %% {CYFRA}+(\.{CYFRA}+)? suma += atof(yytext) ; ^\n suma printf("%g\n", suma) ; \n. /* nic */ Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 34 / 40

Zawartość semantyczna leksemu: yylval %{ #include "exp.tab.h" %} %option noyywrap %% [[:digit:]]+ { yylval = atoi( yytext ) ; return (int)num; }. { return (int)(yytext[0]); } \n { return (int) \n ; } %% Nazwa yylval nie ma znacznenia dla Flexa, jest tylko użyteczna konwencja, ale inne narzędzia (np. Bison) moga na niej polegać. Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 35 / 40

Komentarze... %start COMMENT %% <INITIAL>[0-9]+ {return numtoken(atoi((yytext));}... <INITIAL>"/*" {depth=1;yybegin(comment);} <COMMENT>"/*" {depth++;} <COMMENT>"*/" {depth--; if(!depth) yybegin(initial); } <COMMENT>. {} Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 36 / 40

Flex użycie Makefile explex.c: exp2.l flex -o $@ $< Jeśli pominać -o, Flex stworzy plik lex.yy.c (dla kompatybilności ze starszym narzędziem Lex). Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 37 / 40

Alex Generator lekserów dla Haskella; ta sama idea, trochę inna składnia. { module CalcLex(alexScanTokens) where import CalcToken(Token(..)) } %wrapper "basic" $digit = 0-9 $alpha = [a-za-z] tokens :- $white+ ; -- whitespace "--".* ; -- comment let { \s -> Let } in { \s -> In } $digit+ {\s -> Int (read s)} [\=\+\-\*\/\(\)] {\s -> Sym (head s)} $alpha [$alpha $digit \_ \ ]* { \s -> Var s } Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 38 / 40

Alex użycie ben@sowa$ alex CalcLex.x ben@sowa$ ghci CalcLex.hs GHCi, version 6.12.1... Ok, modules loaded: CalcLex, CalcTokens. *CalcLex> alexscantokens "let x = 1 in x +x" Loading package array-0.3.0.0... linking... done. [Let,Var "x",sym =,Int 1,In,Var "x",sym +,Var "x"] Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 39 / 40

Dla ciekawych: yywrap... <<EOF>> { if ( --include_stack_ptr < 0 ) { yyterminate() ; // Really end } else { lineno = lineno_stack[include_ptr] ; strcpy( the_file_name, file_name_stack[include_ptr] ) ; yy_switch_to_buffer(include_stack[include_ptr]); return (int) ; ; }/* if */ } /* <<EOF>> */ %% int yywrap() { return 1; /* there may be more input */ } Marcin Benke (MIM UW) Metody Realizacji Języków Programowania 4 października 2010 40 / 40