PROGRAMOVACÍ JAZYKY A PŘEKLADAČE PŘEKLADY TYPICKÝCH JAZYKOVÝCH KONSTRUKCÍ PROGRAMOVACÍCH JAZYKŮ. 2011 Jan Janoušek BI-PJP Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti
Dva základní principy překladu programovacích jazyků Přímý překlad do cílového jazyka jako rozšíření syntaktické analýzy. (Direct Code Generation) Celý překlad do cílového jazyka je specifikován atributovou gramatikou, viz. jako příklad adresář mila1 v semestrální práci. Překlad za použití vnitřní reprezentace (tzv. mezikódu). (Intermediate Representations (IR)) Atributová gramatika definuje překlad do mezikódu, viz. jako příklad adresář mila2 v semestrální práci (jako mezikód je zde použit abstraktní syntaktický strom - AST). Mezikód je pak obvykle dále zpracováván v několika fázích: Všelijaké typy optimalizací nad mezikódem, přidělování registrů, generování mezikódů nižší úrovně, generování cílového kódu (pozn. viz. předmět MI-GEN. V předmětu BI-PJP generujeme z AST přímo kód v zapsaný v cílovém jazyku + děláme jednoduché optimalizace na AST, viz adresář mila2).
Přímý překlad do cílového jazyka jako rozšíření syntaktické analýzy. Výhody: Jednoprůchodový deterministický překlad. Konceptuálně jednoduchý model překladu. Nevýhody: Nevýhody spojené s principem vše v jednom: K některým činnostem je obecně potřeba více průchodů. Oddělení specifických činností (přidělování registrů, hw nezávislé a hw závislé optimalizace) je často výhodné (modifikace, jednodušší implementace). Příliš složitá specifikace, jedná-li se o složitější typ překladu.
Překlad za použití vnitřní reprezentace (tzv. mezikódu) Výhody: Oddělení jednotlivých činností, oddělení high-level operací od low-level operací. (Např. oddělení generování kódu a přidělování registrů od sémantické analýzy vstupního jazyka.) Možnost mít mezikódy různých úrovní (nezávislé na vstupním a výstupním jazyku, závislé na výstupním jazyku, ). Jednodušší a unifikované hw nezávislé optimalizace na mezikódu nezávislém na vstupním a výstupním jazyku. Transportabilita mezikódu (stačí kolikrát napsat nový frontend nebo backend pro nový překladač). Nevýhody: Více průchodů, a z tohoto pohledu také obecně složitější.
Překlad do AST
Překlad do AST viz také dokument semestrálky mila2, Výsledný AST je typicky uložený v jednom syntetizovaním atributu.
DAG Místo AST se používá také DAG (Directed acyclic Graph). Stejné podstromy jsou spojeny do jednoho. Výhody DAGu oproti AST: Paměťová optimalizace uložení vnitřní formy. Výhodný pro optimalizace eliminace společných podvýrazů. Nevýhody: Složitější manipulace a generování.
DAG - příklad příkaz a = b*-c+b*-c AST: DAG: assign a + assign a + * * * b uminus b uminus b uminus c c c
Přímý překlad
Přímý překlad viz také dokument semestrálky mila1, Výsledný kód je typicky uložený v jednom syntetizovaném atributu (viz další slajdy), nebo je překlad realizován jako atributovaný formální překlad (přes výstupní (akční) symboly a jejich dědičné atributy) (viz dokument mila1).
Příklad překladu výrazu E E R + T E T T T R * F T F F ( E ) F id E.p = newtemp E.c = concat(e R.c, T.c, gen(e.p=e R.p + T.p)) E.p = T.p E.c = T.c T.p = newtemp T.c = concat(t R.c, F.c, gen(t.p = T R.p * F.p)) T.p = F.p T.c = F.c F.p = E.p F.c = E.c F.p = id.p F.c =
Příklad překladu cyklu tupu while S while E do S R S.L1: E.c JZ E.p, S.L2 S R.c S.L1 = curradr S.L2 = curradr + E.c.size + S R.c.size + 2 S.c = concat(e.c, gen(jz E.p, S.L2), S R.c, gen(jmp S.L1)) S.L2: JMP S.L1
while příklad ješte jednou (lépe) S while E do S R JMP S.L2 S.L1: S R.c S.L2: E.c S.L1 = curradr + 1 S.L2 = curradr + S R.c.size + 1 S.c = concat(gen(jmp S.L2), S R.c, E.c, gen(jnz E.p, S.L1)) JNZ E.p, S.L1
Překlad do jazyka zásobníkového počítače Pozn. jazyk zásobníkového počítače je použit v semestrální práci.
Jazyk zásobníkového počítače int gcd(int a,int b) { while (a!= b) { if (a > b) a = b; else b = a; } return a; } # javap -c Gcd Method int gcd(int, int) 0 goto 19 3 iload_1 // Push a 4 iload_2 // Push b 5 if_icmple 15 // if a <= b goto 15 8 iload_1 // Push a 9 iload_2 // Push b 10 isub // a - b 11 istore_1 // Store new a 12 goto 19 15 iload_2 // Push b 16 iload_1 // Push a 17 isub // b - a 18 istore_2 // Store new b 19 iload_1 // Push a 20 iload_2 // Push b 21 if_icmpne 3 // if a!= b goto 3 24 iload_1 // Push a 25 ireturn // Return a
Výhody Jednoduchý překlad výrazů. Jednoduchý interpret. Neexistuje problém s velmi malým počtem registrů (používá se zásobník místo registrů). Kompaktní kód.
Nevýhody Sémantický mezi zásobníkovými operacemi a moderními procesory s registry (vrchol zásobníku je často držen v registrech). Nesrozumitelný kód z pohledu analýzy co komunikuje s čím. Obtížný tvar pro optimalizace.
stack based IRs Recently again popular and frequently used: Java bytecode interpreted and/or compiled by Java Virtual Machine Common Intermediate Language (CIL), formerly called Microsoft Intermediate Language (MSIL) interpreted and/or compiled by.net runtime or MONO runtime