MED SVARFORSLAG UNIVERSITETET I OSLO. Det matematisk-naturvitenskapelige fakultet

Like dokumenter
UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Med Svarforslag UNIVERSITETET I OSLO. Det matematisk-naturvitenskapelige fakultet. 3 sider (side 6, 7 og 8, rives ut, fylles ut og leveres)

2012 2a. C rc; void main() { rc = new C (); rc.m2(); } } INF 3110/ INF /28/13 1

UNIVERSITETET I OSLO

Diverse eksamensgaver

Anatomien til en kompilator - I

UNIVERSITETET I OSLO

MED SVARFORSLAG UNIVERSITETET I OSLO

Anatomien til en kompilator - I

Semantisk Analyse del I

Runtime-omgivelser Kap 7 - I

Oppgaver til kodegenerering etc. INF-5110, 16. mai, 2014

UNIVERSITETET I OSLO

Runtimesystemer Kap 7 - I

Kodegenerering del 3: Tilleggsnotat fra AHU Samt litt om class-filer og byte-kode INF5110 V2007. Stein Krogdahl, Ifi UiO

UNIVERSITETET I OSLO

Oppgaver til kodegenerering etc. INF-5110, 12. mai, 2015

UNIVERSITETET I OSLO

Beskrivelse av programmeringsspråket Compila15 INF Kompilatorteknikk Våren 2015

Runtimesystemer - II. Funksjoner som parametere. Virtuelle metoder

Litt om Javas class-filer og byte-kode

UNIVERSITETET I OSLO

Runtimesystemer Kap 7 - I

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

NOTAT (pensum!) Javas klasse-filer, byte-kode og utførelse. INF 5110, 10/5-2011, Stein Krogdahl

Kap. 5, Del 3: INF5110, fra 1/3-2011

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Repetisjon: Statiske språk uten rekursive metoder (C1 og C2) Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

NOTAT (pensum!) Javas klasse-filer, byte-kode og utførelse

Kap 6.3: Symboltabellen Foiler ved Birger Møller-Pedersen Forelest av Stein Krogdahl 17. mars Dagens tema:

UNIVERSITETET I OSLO

Oppgaver til INF 5110, kapittel 5

UNIVERSITETET I OSLO

Oppgaver til INF 5110, kapittel 5 Fullt svar på oppgave 5.4, og en del andre oppgaver med svar

Beskrivelse av programmeringsspråket Simpila INF Kompilatorteknikk Våren 2012

UNIVERSITETET I OSLO

INF / Kap. 5, Del 2 Stein Krogdahl, Ifi, UiO

Javas klasse-filer, byte-kode og utførelse (og litt om C# sin CIL-kode)

Kap 6.4: Typesjekking Foiler ved Birger Møller-Pedersen Forelest av Stein Krogdahl 19. og 23. mars Dagens tema: Typer og typesjekking

Oppgaver til INF 5110, kapittel 5, med svarforslag Gjennomgått torsdag 26. febr Dette er versjon fra 28/7

Generiske mekanismer i statisk typede programmeringsspråk

UNIVERSITETET I OSLO

Eksamen iin115, 14. mai 1998 Side 2 Oppgave 1 15 % Du skal skrive en prosedyre lagalle som i en global character array S(1:n) genererer alle sekvenser

Datatyper og typesjekking

UNIVERSITETET I OSLO

Datatyper og typesjekking

Datatyper og typesjekking

UNIVERSITETET I OSLO

INF april, 2013 Kap. 8 Noen oppgaver som er meget relevante for Oblig 2

Kap. 5, Del 2: INF / (og 2/3 og 3/3)

Kap. 5, Del 2: SLR(1), LR(1)- og LALR(1)-grammatikker INF5110 V2009

UNIVERSITETET I OSLO

Kap. 5, del 2 LR(1)- og LALR(1)-grammatikker INF5110 V2008

Om oppgaveteksten på noe punkt er uklar eller upresis, kan du gjøre egne presiseringer. Formulér i så fall disse tydelig i oppgavebesvarelsen din.

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Hjemmeeksamen 2 i INF3110/4110

Datatyper og typesjekking

UNIVERSITETET I OSLO

Dagens tema Syntaks (kapittel Komp. 47, kap. 1 og 2)

Kap. 5, Del 2: SLR(1), LR(1)- og LALR(1)-grammatikker INF /2-2011

INF 5110, 3. februar Dette foilheftet: Kapittel 3

Litt om kompilering og interpretering. Dagens tema Syntaks (kapittel Komp. 47, kap. 1 og 2) Syntaks og semantikk

Plan: Parameter-overføring Alias Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) IN 211 Programmeringsspråk

Dagens Tema: Grammatikker

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Skal bindes opp til en deklarasjon av samme navn

UNIVERSITETET I OSLO

INF /2, 2015 Kap. 5, Del 2 Stein Krogdahl, Ifi, UiO

2 Om statiske variable/konstanter og statiske metoder.

Eksamen i IN 110, 18. mai 1993 Side 2 Del 1 (15%) Vi skal se på prioritetskøer av heltall, der vi hele tiden er interessert i å få ut den minste verdi

UNIVERSITETET I OSLO

INF-5110 Oppgaver kodegenerering etc. INF-5110, vår 2011

INF5110 V2013 Stoff som i boka står i kap 4, men som er generelt stoff om grammatikker

UNIVERSITETET I OSLO

INF januar Forelesninger fremover:

UNIVERSITETET I OSLO

Statisk semantisk analyse - Kap. 6

Statisk semantisk analyse - Kap. 6

Pensumoversikt - kodegenerering. Kap. 8 del 1 kodegenerering INF5110 v2006. Hvordan er instruksjonene i en virkelig CPU? Arne Maus, Ifi UiO

INF225 høsten 2003 Prosjekt del 4: kodegenerering

Obligatorisk Innlevering 2

Hvor er vi nå - kap. 3 (+4,5)? Forenklet skisse av hva en parser gjør PARSER. Kontekstfrie grammatikker og syntaksanalyse (parsering)

Kap. 5 del 2: LR(1)- og LALR(1)-grammatikker INF5110 V2005. Stein Krogdahl, Ifi, UiO

EKSAMEN. Dato: 9. mai 2016 Eksamenstid: 09:00 13:00

Kap.4, del 2: Top Down Parsering Kap. 5, del 1: Bottom Up Parsing INF5110, 7/ Legger ut en oppgave til kap. 4 (se beskjed).

Kap. 8 del 1 kodegenerering INF5110 Vår2007

Kontekstfrie grammatikker og syntaksanalyse (parsering)

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Kodegenerering, del 2: Resten av Kap. 8 pluss tilleggsnotat (fra kap. 9 i ASU ) INF5110 V2007

Hjemmeeksamen 1 i INF3110/4110

Transkript:

MED SVARFORSLAG UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet Eksamen i : INF5110 - Kompilatorteknikk Eksamensdag : Onsdag 2. juni 2010 Tid for eksamen : 14.30-17.30 Oppgavesettet er på : 5 sider (pluss vedlegg) Vedlegg : 1 side (side 6 rives ut, fylles ut og leveres) Tillatte hjelpemidler : Alle trykte og skrevne Les gjennom hele oppgavesettet før du begynner å løse den første oppgaven. Dersom du savner opplysninger i oppgaven, kan du selv legge dine egne forutsetninger til grunn og gjøre rimelige antagelser, så lenge de ikke bryter med oppgavens "ånd". Gjør i så tilfelle rede for disse forutsetningene og antagelsene. Deler av oppgavene 2 og 3 besvares ved bruk av vedlegg. Oppgave 1 (25%) Vi skal se på grammatikker for uttrykk som kan inneholde såkalte unære minuser, altså at man kan skrive uttrykk som x * y + z. Man kan imidlertid tolke dette uttrykket på forskjellige måte, f.eks. på en av de to følgende: (a) (b) ( (x * y)) + z (( x) * y) + z 1a Vi ser på følgende grammatikk G1: E U U + V U T -T V V + T T T T * F F F ( E ) name Her er E, U, V, T, og F ikke-terminaler, E er startsymbol, og resten er terminal-symboler. Avgjør hvilken av de to tolkningen (a) eller (b) denne grammatikken vil gi av x * y + z, og tegn et parserings-tre (altså ikke bare et abstrakt syntaks-tre) som viser at grammatikken kan produsere denne setningen med den tolkningen du har valgt. 1

Svar 1a Denne grammatikken vil gi tolkningen (a). Det kommer av at den unære minusen bare kan komme på den første Ten i en T+T+ +T avledet fra en E, fordi bare den går gjennom en U. Inne i en T kan vi ikke få noen minus, slik at multiplikasjon har større presedens enn både unær minus og pluss. Treet vil se slik ut: E - U T + V T T * F F F y z Kommentar: Grammatikken x var kanskje litt rar, siden den ville tolke f.eks. : x + y + z + u slik: (( x) +((y + z) + u))) Det rimelige hadde vel vært at slike lange uttrykk ble tolket slik: (((( x) + y) + z) + u). Dette berørte imidlertid ikke oppgaven slik den var formulert. 1b Legg på produksjonen E E. Tegn så starttilstanden av LR(0)-DFA en til G1, samt de tilstandene du får om du går ett hakk ut fra denne. Svar 1b E. E E. U E. U + V U. T U. T T. T + F T. F F. ( E ) F. name name F name. ( F E U T E U. E U. + V U T. T T. + F U. T T. T + F T. F F. ( E ) F. name E E. F (. E ) E. U E. U + V U. T U. T T. T + F T. F F. ( E ) F. name Det vil også være noen T tilstands-overganger F. mellom de tilstandene som ligger ett hakk ut, men man fikk full uttelling uten dem. 2

1c Grammatikken G1 er opplagt ikke LL(1). Din oppgave her er å skrive om grammatikken slik at det ikke lenger finnes opplagte tegn på at grammatikken ikke er LL(1). Du behøver ikke sjekke om den resulterende grammatikken faktisk er LL(1). Svar 1c E U E De to første er venstrefaktorisering av E U U + V E + V U T -T V T V Her er fjernet venstre-rekusjon fra V V + T T på standard vis V + T V T F T Her er fjernet venstre-rekusjon fra T T * F F på standard vis T * F T F ( E ) name 1d Finn en grammatikk G2 som gir den motsatte tolkningen ((a) eller (b)) av den du anga i oppgave 1a. Merk at G2 skal tolke alle tradisjonelle uttrykk som ikke har noen unær minus (men har + og *) på vanlig måte. Forsøk å lage G2 slik at den ikke tillater flere unære minuser etter hverandre, altså slik at - - x er ulovlig, mens - (- x) er lovlig. Svar 1d Dette gjør vi ved å flytte den unære minusen ned på helt ned på F-nivå (faktor). For at vi ikke skal tillate to minuser etter hverandre legger vi inn et nytt nivå, med F. E E E + T T T * F F F F - F F ( E ) name Om man slår sammen de to siste produksjonene til: F ( E ) name - F så vil man altså tillate flere minuser etter hverandre. Oppgave 2 (20%) I denne oppgaven har vi et helt vanlig objekt-orientert språk, hvor en virtuell metode i en klasse kan redefineres i en subklasse av denne klassen. En virtuell metode deklareres med en virtual modifier, mens en redefinisjon deklareres med modifieren redef. Når vi kaller en virtuell metode for et gitt objekt vil klassen til objektet bestemme på vanlig måte hvilken metode som kalles. I motsetning til i Java finnes det altså metoder som ikke er virtuelle. Det følgende er klasser definert i dette språk: 3

class A { virtual void m(){...} void p(){...} virtual void q(){...} } class B extends A{ redef void q(){...} void r(){...} } class C extends B{ redef void m(){...} } class D extends C{ redef void m(){...} redef void q(){...} } 2a Lag virtuell-tabellene for klassene A, B, C og D. For hvert element i tabellene skal du bruke notasjonen A::m for å angi hvilken metode som gjelder. Indeksen i disse tabeller starter på 1. Svar 2.a 2b I denne del av oppgaven skal vi se på hvordan man kan implementere en alternativ redefinisjons-regel: For et objekt av en klasse K, som har en virtuell metode vm, vil et kall på denne metoden virke som følger: hvis K ikke har noen superklasse, så skal det bli et kall på K::vm hvis K har en eller en sekvens av superklasser, så skal vi få en sekvens av kall bestående av: først et kall på vm i den superklassklassen der den introduseres 4

som virtuell, så kall på vm i de superklasser hvor vm redefineres (i en sekvens som følger subklasse-hierarkiet), eventuelt avsluttet med av et kall på vm i K (hvis redefinert i K). For eksemplet i 2a vil et kall på q() for et objekt av klassen D føre til følgende kall-sekvens: A::q(); B::q(); D::q(), altså ingen C::q(), da q ikke er redefinert i klassen C. Vi antar at virtuelle metoder kan ha hverken parametere eller returverdi. Til å implementere dette innføres det for hver klasse en virtuell-tabell, hvor det for hver virtuell metode er en rad med lengde lik 1 + <antall superklasser inntil den klasse som introduserer den virtuelle>, og hvor et element i denne raden angir en eventuelt redefinert metode. Indeksen for hver rad starter på 0. Elementet med indeks 0 i hver rad angir den (eventuelle) redefinisjon for klassen selv, elementet med indeks 1 angir den (eventuelle) redefinisjon for superklassen, osv. Hver rad vil dermed angi sekvensen av de metoder som skal kalles. Tegn de nye virtuell-tabeller for klassene C og D. Tabellene for A og B er gitt under. For redefinisjoner brukes samme notasjon som før, mens det for elementer som representerer ingen redefinisjon brukes en -. Svar 2b 5

2c Vi skal her se på hvordan tabellene fra 2b kan brukes. Når et kall til en virtuell metode blir gjort går kontrollen til en runtime-rutine som får en peker til riktig rad i riktig virtuell-tabell, og lengden av denne raden. Vi antar at denne rutinen også har tilgang til størrelsen på aktiveringsblokkene for metodene i raden. Denne rutinen skal så legge aktiveringsblokker på stakken slik at den til slutt kan gi kontrollen til metoden på toppen av stakken (fp frame pointer), og at utførelsen, inklusive termineringen, skal gå videre av seg selv som ved vanlig eksekvering. Vi skal se på hvordan rutinen da må sette opp stakken, og spesielt hvordan retur-adressene og dynamisk linkene (control link) samt fp skal settes. Du skal vise dette for det tilfellet at vi kaller metoden m for et objekt av klassen D (anta at kallet på m foregår i en main metode). Angi for hver aktiveringsblokk (activation record) hvilken metode den tilsvarer (på formen klasse::metodenavn) og hvor dynamisk link skal peke (ved en pil). Retur-adressen (return address) kan du angi ved en kort forklarende tekst. Statisk link (access link) trenger du ikke angi. Hver aktiveringsblokk skal ha form som angitt under, og stakken skal vokse nedover: Svar 2c For indeks 0: hvis merket med -, da gjør ingenting, ellers lag en aktiveringsblokk for metoden i det tilsvarende tabell-elementet, sett control link til aktiveringsblokk for kalleren (her main), og retur-addressen til stmt etter kallet. For indeks 1..<antal superklasser>: hvis merket med -, da gjør ingenting, ellers lag en aktiveringsblokk for metoden i det tilsvarende tabell-elementet, sett control linken til å peke på forrige genererte aktiveringsblokk (eller main) og retur-addressen til dennes første stmt. Sett fp til å peke på siste genererte aktiveringsblokk 6

7

Oppgave 3 (30%) 3a Det følgende er en del av grammatikken for et språk med funksjoner. func type func id signature stmt-list type int type bool stmt-list stmt-list stmt stmt-list stmt stmt assign-stmt stmt if-stmt stmt return-stmt return-stmt return exp exp id exp id + id exp true exp false Ord i kursiv er ikke-terminaler, ord og tegn i fet skrift er terminal-symboler. id representerer et navn. En funksjon har en type som enten er Integer eller Boolean. Reglen i dette språket er (ikke overraskende) at return-setningen (return exp) skal returnere en verdi med samme type som typen til funksjonen. Fyll ut de tomme felter (markert med *) i attributtgrammatikken for de relevante deler av grammatikken på side 7 slik at attributtet ok for return-stmt er true hvis typen til returuttryket exp er det samme som typen til funksjonen, ellers false. Du kan anta at lookup-kind(id.name)leverer den type, som er lagt inn i symboltabellen ved deklarasjonen av variablen med navnet id.name. 8

Svar 3a Grammar Rule func type func id signature stmt-list type int type bool stmt-list 1 stmt-list 2 stmt stmt-list stmt stmt return-stmt Semantic Rule stmt-list.type = type.type type.type = Integer type.type = Boolean stmt-list 2.type = stmt-list 1.type stmt.type = stmt-list 1.type stmt.type = stmt-list.type return-stmt.type = stmt.type return-stmt return exp return-stmt.ok = (return-stmt.type = exp.type) exp id exp.type = lookup(id.name) exp id 1 + id 2 exp.type = if lookup(id 1.name)= Integer and lookup(id 2.name)= Integer then Integer else ErrorType exp true exp false exp.type = Boolean exp.type = Boolean I de to neste delspørsmål ser vi på parameteroverføring i dette språk. Funksjoner kan ha én parameter, og den er enten by value eller by-value-result (keyword result). Dette er reflektert i følgende definisjon av signature: signature type id result type id Følgende program deklarerer en integer array a og en funksjon inc. Programmet initialiserer i og a, kaller funksjonen inc(a[i]) og skriver ut verdien av a[0], a[1]. Språket følger vanlige statiske skopregler. { int i; int[2] a; int func inc(result int j) { j = j + i; i = i + 1; return i }; 9

} a[0]=1; a[1]=2 i=0; inc(a[i]); write(a[0], a[1]) (slutt svar oppgave 3a) I de to neste delspørsmål ser vi på parameteroverføring i dette språk. Funksjoner kan ha én parameter, og den er enten by value eller by-value-result (keyword result). Dette er reflektert i følgende definisjon av signature: signature type id result type id Følgende program deklarerer en integer array a og en funksjon inc. Programmet initialiserer i og a, kaller funksjonen inc(a[i]) og skriver ut verdien av a[0], a[1]. Språket følger vanlige statiske skopregler. { } int i; int[2] a; int func inc(result int j) { j = j + i; i = i + 1; return i }; a[0]=1; a[1]=2 i=0; inc(a[i]); write(a[0], a[1]) 3b Anta at semantikken for by-value-result er slik at adressen (location) til den aktuelle parameter beregnes ved funksjonskallet. Hva skrives ut? Svar 3b: 1, 2 3c Anta at semantikken for by-value-result er slik at adressen (location) til den aktuelle beregnes ved avslutning av funksjonskallet. Hva skrives ut? Svar 3c: 1, 1 Oppgave 4 (25%) 4a Kari har en BNF-grammatikk hun mener ikke er LR(1), men hun mener likevel at grammatikken beskriver et regulært språk. Anne mener det ikke går an. Hvem har rett? Forklar. 10

Svar 4a Kari har rett. Det går helt fint an at et språk som ikke er LR(1) kan beskrive et språk som er regulært. Det var ikke spørsmål om noe eksempel, men et slikt er følgende grammatikk: A -> a A a a der språket kan skrives som det regulære uttrykket: a (a a)*. Men grammatikken er ikke LR(k) for noen k fordi en parser ikke kan vite når man er på midten (det er da den skal gå over fra skift-operasjoner til reduser-operasjoner) uten å måtte lete et antall symboler framover, og det antallet er ikke oppad begrenset. 4b Per har en BNF-grammatikk han mener er flertydig, men at den likevel er LL(1). Ole mener det ikke går an. Hvem har rett. Forklar. Svar 4b Ole har rett. En grammatikk som er flertydig kan ikke være LL(1) (eller LR(0), SLR(1), LALR(1) eller LR(1) ). 4c Nora påstår at når en Java-klasse oversettes til byte-kode (i form av en class-fil) så må kompilatoren ha tak i class-fila til en eventuell superklasse for der står det hvor mye plass (i byte) som trengs til variablene i denne superklassen (og dens superklasser igjen). Frida mener hun må ha misforstått. Hvem mener du har rett? Forklar. (Denne var kanskje ikke helt vel formulert, og ville vært tydeligere om andre linje var slik: kompilatoren ha tak i class-fila til en eventuell superklasse fordi den trenger å vite hvor mye plass ) Svar 4c Frida har rett. Det foregår ingen utregning av relativadresser under bytkode-produksjon i det hele tatt. I klassefilen og byte-koden ligger bare lister av variabel-navn og deres typer, og ingen relativadresser etc. Det er loaderen som beregner fysiske relativadresser og liknende. 4d Arne har sett på kodegenerings-algoritemen på slutten av det utdelte heftet (fra kap. 9 i ASU). Han mener da at for de to treadresse-instruksjonene: t1 = a b; t2 = b c; så vil algoritmen produsere instruksjonene under. Han har antatt at det er to registre, og at begge er tomme ved starten MOV a, R0 MOV b, R1 SUB R1, R0 SUB c, R1 Ellen er uenig. Hvem har rett? Forklar. Svar 4d Nei, algoritmen vil ikke generere dette. Den vil faktisk (slik som i eksempelet på side 539 i det utleverte notat) alltid hente den siste operanden (hhv b og c) direkte fra hjemmeposisjon i lageret dersom den ikke allerede er i et register. 11

Det var vel ikke krav om å skrive hva den ville generere, men det ville altså bli: MOV a, R0 SUB b, R0 MOV b, R1 SUB c, R1. 4e Anta at vi ser på et språk der kompilatoren har frihet til å oversette uttrykk slik at de forskjellige delene av uttrykket blir beregnet i den rekkefølgen kompilatoren finner best. Videre er det i den maskinen vi oversetter til viktig å holde så mange mellom-verdier som mulig i registre under beregningen av uttrykk. Petter sier da at om man har et stort uttrykk som (f.eks.) er summen av to sub-uttrykk så lønner det seg oftest å generere kode slik at det største sub-uttrykket blir beregnet først, mens Unni mener at det er motsatt. Hvem har rett og hvordan bør man definere størrelsen av et sub-uttrykk i dette tilfellet? Svar 4e Petter har rett. Det lønner seg å beregne det største sub-uttrykket først, for når man skal beregne det andre er da ett register opptatt til å holde verdien av det første sub-uttrykket, og man har derved ett register mindre til disposisjon. Men fordi uttrykket er mindre kan man likevel kanskje klare å holde seg i bare registre. Størrelsen av et (sub-)uttrykk skal her regnes som hvor mange mellomresultater man maksimalt må holde på en gang under beregningen av dette uttrykket. Men, det å si hvordan dette kan beregnes ved bare å se på selve trestrukturen er imidlertid ikke så lett (og vi må jo da anta at det samme prinsippet brukes på alle nivåer). Det enkleste er vel å simulere kodegenerering av hver av sub-uttrykkene som en forberedelse, og så starte med å generere kode for det som trengte mest maksimal plass. Lykke til! Stein Krogdahl og Birger Møller-Pedersen 12