Úvod z historie RNDr. Miroslav Benedikovič John Louis von Neumann r. 1946 nová koncepce počítače (společná paměť pro kód programu a zpracovávaná data) vytvořila podmínky pro vznik softvéru na přípravu programů Katedra informatiky v dopravě Dopravní fakulta Jana Pernera Univerzita Pardubice Katedra informatiky Fakulta riadenia a informatiky Žilinská univerzita Kontakt: (421 41) 513 4 187 Grace Murray Hopper r. 1951 vznik myšlenky programu, který umožní přeložit instrukce z vyššího jazyka do strojového kódu. Kompilace / Kompilátor Compile / Compiler bene@fri.uniza.sk 2 Úvod z historie Pojem kompilátoru John Backus Pod jeho vedením byl v r. 1954 až 1957 ve firmě IBM vyvinutý první kompilátor jazyka FORTRAN formula translation Byl to problémově orientovaný jazyk pro řešení matematických úloh Vývoj spotřeboval 18 člověko-let (staff-years) implementace Stavba tohoto kompilátoru nebyla založena na nějakém teoretickém základě. Jeho struktura, komponenty a techniky vznikali ad-hoc Noam Chomsky Výzkum v oblasti struktury přirozených jazyků. Základy vývoje a tvorby moderních jazyků a jejich kompilátorů. První pohled - Černá skříňka Zdrojový program KOMPILÁTOR Chybové zprávy protokoly Cílový program 3 4
Úvodní pojmy Typická organizace kompilátoru Zdrojový (Source) kód (posloupnost znaků) Zdrojový jazyk jazyk, ve kterém sestavíme zdrojový text, ten je vstupem pro kompilátor (Pascal, C, Java,...) Cílový jazyk jazyk, do kterého přeloží kompilátor zdrojový text, procesor ho dokáže interpretovat Hostující jazyk programovací jazyk, ve kterém sestavíme kompilátor Analýza rozeznává nějaký zdrojový jazyk L Syntéza vytváří cílový kód v cílovém jazyku L' Lexikální analyzátor (scanner) Posloupnost tokenů POPREDIE Front end POZADIE Back end Syntaktický analyzátor (parser) Abstraktní syntaktický strom Rozšířený označený syntaktický strom Pomocný kód Optimalizovaný pomocný kód Sémantický analyzátor Generátor pomocného kódu Optimalizátor Cílový (Object) kód (může být assemblerovský nebo strojový kód) Generátor kódu 5 Fázy kompilátoru Scanner lexikální analyzátor Lineární analýza, scanning proud znaků tvořící zdrojový program je čtený zleva doprava, vyhledávané jsou významové posloupnosti znaků tvořící vždy nedělitelný jedno resp. víceznakový symbol - lexému. Každé z lexém je přiřazený token. Této fáze se častěji říká lexikální analýza, anebo scanning Hierarchická analýza, parsing naskenované symboly anebo tokeny jsou sdružované do syntaktických celků podle přesně stanovených gramatických pravidel jazyka. Tuto fázi voláme syntaktickou analýzou Sémantická analýza vykonávají se určité kontroly pro zajištění správného významu příslušných komponentů v celkovém kontextu programu, případně jeho částí Čte postupně jednotlivé znaky ze zdrojového programu Seskupuje znaky do LEXÉM (jsou to posloupnosti znaků, které patří k sobě ; popisují nějakou entitu jazyka) Každá lexéma odpovídá jednomu TOKEN-u (je to prvek jazyka s definovaným významem); scanner vrací následující token (případně další přídavnou informaci) a odesílá ho do parseru Scanner odhaluje lexikální chyby (např. nekorektní znaky) 7 8
Lexéma / Token - jejich vzájemný vztah Scanner čte příslušnou posloupnost znaků tzv. lexému Přiradí lexémě dohodnutý kód token Pro scanner je pořadí lexém nevýznamné!! Příklad v jazyku Pascal Přiřazovací příkaz: Pozice := zaklad posuv * 60 Lexéma : index := tmp 37 10.2 while <= Token COLON ASSIGN INT-LIT REAL-LIT LOOP-WHILE LE Význam dvojtečka identifikátor přiřazení identifikátor celočíselní literál literál reálního čísla cyklus While relace menší anebo rovný Scanner zjistil následující lexémy a tokeny L e x é m y : Pozice := zaklad posun * 60 T o k e n y : (například jednobytové hodnoty) ASSIGN OP-PLUS OP-KRAT INT-LIT 9 10 PARSER - syntaktický analyzátor Syntaktický strom Seskupuje tokeny do gramatických vět - fráz Zkoumá gramatickou strukturu zdrojového programu Hledá syntaktické chyby, například následující věta v Pascalu: pozice := * 5 je lexikálně správná, ale syntakticky je chybná!! Může hledat i některé "statické sémantické" chyby, například nedeklarované proměnné, případně víckrát deklarované proměnné Generuje vnitřní reprezentaci programu vyjadřující ve tvaru abstraktního syntaktického stromu a buduje program ve vnitřním jazyku Datová struktura s následujícími vlastnostmi: vnitřní uzly stromu obsahují OPERÁTORY synové uzlu obsahují OPERANDY příslušné operace počet synů odpovídá počtu operandů operace každá část podstromu je samostatnou "logickou jednotkou X Y if A<0 then Pr1 else A:=B1 X Y A if < Pr1 := 0 A B 1 11 12
Příklad v jazyku Pascal Sémantický analyzátor Přiřazovací příkaz: pozice := zaklad posuv * 60 ASSIGN V uzlech stromu jsou tokeny!! Informace o lexémech jsou v tabulce symbolů OP-PLUS OP-KRAT INT-LIT Jako vstup používá abstraktní strom vytvořený scannerem Zjišťuje kompatibilitu typů jednotlivých hodnot - typová kontrola V případě potřeby doplňuje uzly konverzními funkcemi pro změnu typu hodnoty na kompatibilní typ, například integer na ty Generuje vnitřní reprezentaci programu vyjadřující ve tvaru abstraktního syntaktického stromu 13 14 Rozšířený syntaktický strom Generátor vnitřního kódu Uzly ve stromě jsou doplněny sémantickými informacemi o typu hodnot pozice := zaklad stupen Doplněný je uzel s funkcí intto() pro převod celočíselné hodnoty na reálnou * intto() 60 Překládá data z abstraktního syntaktického stromu do pomocného vnitřního kódu (intermediate code) Je to zjednodušený kód nezávislý na cílovém jazyku, například tříadresový kód podobný assembleru. V mnohých pascalovských kompilátorech je populární tzv. P-kód Je ho možné lehčeji vytvořit, než konkrétní cílový program Výstupem je tzv. vnitřní tvar programu intermediate representation, připravený pro zpracování v závěrečné syntetizační části kompilátoru V této etapě kompilace je možno vykonávat optimalizaci programu 15 16
Popředí / pozadí Optimalizátor PASCAL C FORTRAN BASIC LOGO Bez vnitřní reprezentace: 25 možností procesor 1 procesor 2 procesor 3 procesor 4 procesor 5 PASCAL C FORTRAN BASIC LOGO S vnitřní reprezentací: Vnitřní Vnitřní jazyk jazyk 10 možností procesor 1 procesor 2 procesor 3 procesor 4 procesor 5 Umožňuje vylepšit cílový kód z hlediska paměťového úspora operační paměti časového náhrada pomalých instrukcí rychlejšími, případně vhodný kompromis předcházejících Odstraňuje redundantní anebo nepotřebné příkazy Dvě etapy optimalizace popředí, front end všeobecné metody nezávislé na cílovém jazyku pozadí, back end optimalizace podřízena cílovému prostředí, například strojovému kódu procesoru (vhodné využívání registrů, používání prostředků pro ekonomičtější organizaci dát...) 17 18 Generátor cílového kódu Dekompozice kompilátoru Generuje cílový kód z (optimalizovaného) pomocného kódu. Je úplně závislý na cílovém prostředí, ve kterém má pracovat přeložený program Příklady cílového jazyka podle účelu: Jazyk symbolických adres assemblerovský jazyk Čistý strojový kód množinu instrukcí procesoru bez předpokladu existence operačního systému a knižnic nezávislý na jiném softvéru Rozšířený strojový kód používané jsou rutiny OS a podporné rutiny (V/V operace, alokace paměti, matematické funkce apod.) Virtuální strojový kód složený je úplně z takzvaných virtuálních instrukcí technika tvorby přenositelného počítače Zdrojový program Lexikální analyzátor Syntaktický analyzátor Sémantický analyzátor Generátor vnitřního kódu Optimalizátor kódu Generátor cílového kódu Cílový program Správce hlášení chyb Error Reporting druh chyby a jej alokace způsob pokračování překladu - zastavení překladu - zotavení Správce tabulky symbolů Symbol Table informace o identifikátorech - paměť nutná pro alokaci identifik. - druh identifikátoru - typ odpovídající hodnoty -počet a typ argumentů procedur a funkcí... 19 20