Generování vnitřní reprezentace programu
460 likes | 626 Views
Generování vnitřní reprezentace programu. Miroslav Beneš Dušan Kolář. Možnosti překladu. Interpre tace Okamžité provádění programu Překlad do instrukcí procesoru Závislost na konkrétním typu procesoru Překlad do vnitřní reprezentace
Generování vnitřní reprezentace programu
E N D
Presentation Transcript
Generování vnitřní reprezentace programu Miroslav Beneš Dušan Kolář
Možnosti překladu • Interpretace • Okamžité provádění programu • Překlad do instrukcí procesoru • Závislost na konkrétním typu procesoru • Překlad do vnitřní reprezentace • Následuje interpretace nebo překlad do instrukcí procesoru Vnitřní reprezentace programu
Výhody překladu do vnitřní reprezentace • Strukturalizace překladače • Mnohem jednodušší přenos na více typů procesorů • Možnost optimalizace na úrovni vnitřní reprezentace • strojově nezávislé metody Vnitřní reprezentace programu
Formáty vnitřní reprezentace programu • Grafová reprezentace • Zásobníkový kód • Tříadresový kód Vnitřní reprezentace programu
Grafová reprezentace • Abstraktní syntaktický strom (AST)a:=b*(-c)+b*(-c) assign Uzly - operátory Listy - operandy a + * * b uminus b uminus c c Vnitřní reprezentace programu
Grafová reprezentace • DAG (Directed Acyclic Graph)a:=b*(-c)+b*(-c) assign Společné podvýrazy jako sdílené uzly Používá se pro optimalizaci a + * b uminus c Vnitřní reprezentace programu
Příklad var n,f: Integer;begin read n; f:=1; while n>1 do begin f:=f*n; n:=n-1 end; write f,”\n”end. Vnitřní reprezentace programu
Grafová reprezentace seq read := while write n f 1 > seq f \n n 1 := := f * n - f n n 1 Vnitřní reprezentace programu
Zásobníkový kód • Postfixová notace a b c uminus * b c uminus * + assign • výsledek průchodu AST nebo DAG typu post-order • uzel následuje bezprostředně za svými následníky • žádný formální rozdíl mezi operandy a operátory Vnitřní reprezentace programu
Zásobníkový kód • Virtuální zásobníkový procesor load b (b) vrchol zás. vpravoload c (b) (c)inv (b) (-c)mul(b*-c)load b (b*-c)(b)load c (b*-c)(b)(c)inv (b*-c)(b)(-c)mul (b*-c)(b*-c)add(b*-c+b*-c)store a Vnitřní reprezentace programu
Zásobníkový kód • Virtuální zásobníkový procesor • virtuální počítač s pamětí a zásobníkem • P-kód (Wirth) • přenositelný mezikód pro Pascal • specializované procesory • Java Virtual Machine • MSIL – Microsoft Intermediate Language(.NET – C#, C++, VB, …) Vnitřní reprezentace programu
Příklad - JVM public class Priklad { public static void main(String[] args) { int x = 1; System.out.println(x + 2); } } Vnitřní reprezentace programu
Příklad - JVM 0:iconst_1 1:istore_1 2:getstatic#2;//java/lang/System.out 5:iload_1 6:iconst_2 7:iadd 8:invokevirtual#3;//java/io/PrintStream.println 11:return Vnitřní reprezentace programu
Příklad - MSIL using System; public class Priklad { public static void Main(string[] args) { int x = 1; Console.WriteLine(x + 2); } } Vnitřní reprezentace programu
Příklad - MSIL .method public static void Main(string[] args) { .entrypoint .maxstack 2 .locals init (int32 V_0) ldc.i4.1 stloc.0 ldloc.0 ldc.i4.2 add call void System.Console::WriteLine(int32) ret } Vnitřní reprezentace programu
Tříadresový kód • x := y opz • x - (dočasná) proměnná • y,z - (dočasné) proměnné, konstanty • Operandy nemohou být výrazy • rozklad na primitivní výrazy s dočasnými proměnnými • Explicitníodkazy na operandy • možnost přesouvání příkazů při optimalizaci Vnitřní reprezentace programu
Příklad1 a:=b*(-c)+b*(-c) t1:=-c t1:=-c t2:=b*t1 t2:=b*t1 t3:=-c t5:=t2+t2 t4:=b*t3 a :=t5 t5:=t2+t4 a :=t5 Strom DAG • dočasné proměnné = vnitřníuzly stromu (DAG) Vnitřní reprezentace programu
Příklad 2 var n,f:integer; begin 1: read nread n; 2: f:=1 f:=1; 3: if n<=1 goto 7 while n>1 do begin 4: f:=f*nf:=f*n; n:=n-15: n:=n-1 end; 6: goto 3 write f,"\n" 7: write fend. 8: write "\n" Vnitřní reprezentace programu
Příkazy tříadresového kódu • x := y op z op – binární operátor • x := op y op - unární operátor(-, not, typová konverze, …) • x := y • goto L nepodmíněný skok • if x relop y goto L podmíněný skok Vnitřní reprezentace programu
Příkazy tříadresového kódu • param x1… param xnvolání podprogramucall p,n p(x1,…,xn) • return y návrat z podprogramu Vnitřní reprezentace programu
Příkazy tříadresového kódu • x := y[j]x[j] := y indexování • x := &y reference (získání adresy) • x := *y*x := y dereference ukazatele Vnitřní reprezentace programu
Čtveřice op arg1 arg2 výsledek (0) uminus c t1(1) * b t1 t2(2) uminus c t3(3) * b t3 t4(4) + t2 t4 t5(5) := t5 a a:=b*(-c)+b*(-c) Vnitřní reprezentace programu
Příklad – překlad výrazů • Atributy • id.name – jméno identifikátoru • E.place – jméno proměnné obsahujícíhodnotu E • Pomocné funkce • newtemp – vytvoří novou proměnnou • lookup – vyhledá proměnnou v tabulce • emit – generuje instrukci • error – hlášení chyby Vnitřní reprezentace programu
Příklad – překlad výrazů • S -> id := E { p = lookup(id.name); if( p != null ) emit(p,‘:=’,E.place); else error(); } • E -> E1 + E2 { E.place = newtemp(); emit(E.place,‘:=’, E1.place,’+’,E2.place);} • E -> E1 * E2 { E.place := newtemp(); emit(E.place,‘:=’, E1.place,’*’,E2.place);} Vnitřní reprezentace programu
Příklad – překlad výrazů • E -> - E1{ E.place = newtemp(); emit(E.place,‘:=’, ‘uminus’,E1.place);} • E -> (E1) { E.place = E1.place; } • E -> id { p := lookup(id.name); if( p != null ) E.place := p; else error(); } Vnitřní reprezentace programu
Přístup k prvkům pole • array [low..high] of T • prvek a[j] leží na adrese: • base+(j-low)*w = j*w+(base-low*w) =konstanta! low low+1 w=sizeof(T) high base Vnitřní reprezentace programu
Přístup k prvkům pole base low2 high2 • a[j1,j2] • base+((j1-low1)*n2+j2-low2)*w =>((j1*n2)+j2)*w+(base-((low1*n2)+low2)*w) =konstanta! low1 n2 := high2-low2+1 high1 Vnitřní reprezentace programu
Přístup k prvkům pole • Obecně: a[j1, … , jk] • addresa: • (…(j1n2+j2)n3+j3)…)nk+jk)*w + base-(…(low1n2+low2)n3+low3)…)nk+lowk)*w mapovací funkce • nj = highj-lowj+1 Vnitřní reprezentace programu
Překlad výrazů s indexy • S -> L := E • E -> E1 + E2| (E1) | L • L -> Elst ] | id • Elst -> Elst1 , E | id [ E Vnitřní reprezentace programu
L.offset index (null=bez indexu) L.place proměnná E.place proměnná s hodnotou id.place Elst.array popis pole Elst.ndim počet rozměrů Elst.place proměnná obsahující index Překlad výrazů s indexy Vnitřní reprezentace programu
Překlad výrazů s indexy • const(Elst.array) • konstantní část mapovací funkce • width(Elst.array) • velikost prvku pole • limit(Elst.array,m) • počet prvků v m-té dimenzi Vnitřní reprezentace programu
Překlad výrazů s indexy • S -> L := E{ if( L.offset==null ) /* bez indexu */ emit(L.place,‘:=’,E.place); else emit(L.place,‘[’,L.offset,‘]’, ‘:=’,E.place); } • E -> E1 + E2{ E.place = newtemp(); emit(E.place,‘:=’,E1.place, ‘+’,E2.place); } Vnitřní reprezentace programu
Překlad výrazů s indexy • E -> (E1){ E.place = E1.place } • E -> L{ if( L.offset==null ) /* bez indexu */ E.place = L.place; else { E.place = newtemp(); emit(E.place,‘:=’,L.place, ‘[’,L.offset,‘]’) }} Vnitřní reprezentace programu
Překlad výrazů s indexy • L -> Elst ]{ L.place = newtemp(); L.offset = newtemp(); emit(L.place,‘:=’,const(Elst.array)); emit(L.offset,‘:=’,Elst.place,‘*’, width(Elst.array)); } • L -> id{ L.place = id.place; L.offset = null; } Vnitřní reprezentace programu
Překlad výrazů s indexy • Elst -> Elst1 , E{ t = newtemp(); m = Elst1.ndim+1; emit(t,‘:=’,Elst1.place,‘*’, limit(Elst1.array,m)); emit(t,‘:=’,t,‘+’,E.place); Elst.array = Elst1.array; Elst.place = t; Elst.ndim = m;} Vnitřní reprezentace programu
Překlad výrazů s indexy • Elst -> id [ E{ Elst.array = id.place; Elst.place = E.place; Elst.ndim = 1;} Vnitřní reprezentace programu
Příklad • A: array [1..10,1..20] of integer; • sizeof(integer) = 4 • n1 = 10n2 = 20w = 4 • x := A[y,z] Vnitřní reprezentace programu
Příklad x := A[y, z] t1 := y*20t2 := t1+zt3 := c /* konstanta c = &A-84 */t4 := 4*t2(1*20+1)*4=84t5 := t3[t4]x := t5 Vnitřní reprezentace programu
Překlad logických výrazů • E -> E or E | E and E | (E) | not E | id relop id | true | false Vnitřní reprezentace programu
Překlad logických výrazů • Reprezentace logických hodnot celými čísly: true=1, false=0 • a or b and not cx<y1: t1 := not c 1: if x<y goto 42: t2 := b and t1 2: t1 := 03: t3 := a or t2 3: goto 54: … 4: t1 := 1 5: … Vnitřní reprezentace programu
Překlad logických výrazů • Zkrácené vyhodnocení • reprezentace logických hodnot tokem řízení (pozicí v programu) a<b or c<d and e<fif a<b goto Ltrue goto L1L1: if c<d goto L2 goto LfalseL2: if e<f goto Ltrue goto Lfalse Vnitřní reprezentace programu
Překlad řídicích příkazů • Instrukce zásobníkového kódu: • LBL L – definice návěští L pro skok • JMP L – nepodmíněný skok na návěští L • FJP L - podmíněný skok na návěští L, pokud je na vrcholu zásobníku False výstupní symboly překladové gramatiky - {LBL} • Pomocné funkce: • getLbl() – vygeneruje nové číslo návěští zanoření příkazů – nelze použít konstanty! Vnitřní reprezentace programu
Překlad příkazu IF • S -> if ( E ) S • <E> • FJP L1 • <S> • LBL L1 • S -> if ( E ) {FJP} S {LBL} FJP.l = LBL.l = getLbl(); E FJP L1 S LBL L1 Vnitřní reprezentace programu
Překlad příkazu IF • S -> if ( E ) S1else S2 S -> X {LBL} LBL.l = X.l S -> X {JMP} {LBL1}else S {LBL2}JMP.l = LBL2.l = getLbl();LBL1.l = X.l X -> if (E) {FJP} S FJP.l = getLbl() E FJP L1 S1 JMP L2 L1: S1 L2: Vnitřní reprezentace programu
Překlad příkazu WHILE • S -> while ( E ) S • LBL L1 • <E> • FJP L2 • <S> • JMP L1 • LBL L2 L1: E FJP L2 S JMP L1 L2: Vnitřní reprezentace programu
Překlad příkazu WHILE • S -> {LBL1} while ( E ) {FJP2} S {JMP1} {LBL2} LBL1.l = JMP1.l = getLbl(); LBL2.l = FJP.l = getLbl(); • S -> break/continue ; • S.blab – dědičný atribut, návěští pro break • S.clab – dědičný atribut, návěští pro continue • while musí zajistit předání návěští • speciální hodnota návěští – poznáme, že nejsme uvnitř cyklu, break/continue může hlásit chybu Vnitřní reprezentace programu