UNIVERSITETET I OSLO

Like dokumenter
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)

UNIVERSITETET I OSLO

MED SVARFORSLAG UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

MED SVARFORSLAG UNIVERSITETET I OSLO. Det matematisk-naturvitenskapelige fakultet

UNIVERSITETET I OSLO

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

Oppgaver til INF 5110, kapittel 5

INF Noen oppgaver til kap. 8

UNIVERSITETET I OSLO

INF5110, onsdag 19. februar, Dagens tema: Parsering ovenfra-ned (top-down)

Diverse eksamensgaver

INF april, 2015 Stein Krogdahl Ifi, UiO. Svar på oppgaver til kap. 8. Ble lagt ut 24. april

INF april, 2014 Stein Krogdahl Ifi, UiO. Svar på oppgaver til kap. 8

INF Noen oppgaver til kap. 8

Semantisk Analyse del I

Anatomien til en kompilator - I

Kap. 4: Ovenfra-ned (top-down) parsering

UNIVERSITETET I OSLO

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

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

UNIVERSITETET I OSLO

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

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

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

Bottom up parsering (nedenfra-og-opp) Kap. 5 del 1 Intro til parsering nedenfra-og-opp samt LR(0) og SLR(1) grammatikker INF5110 v2006

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.

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).

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

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

INF5110 Kap. 5: Parsering nedenfra-og-opp (Bottom-up parsing) 21/ Stein Krogdahl Ifi, UiO. Angående Oblig 1:

Anatomien til en kompilator - I

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Hjemmeeksamen 2 i INF3110/4110

Kap.4 del I Top Down Parsering INF5110 v2005. Arne Maus Ifi, UiO

Kap. 5, del 1: Parsering nedenfra-opp (Bottom up parsing) INF5110. Stein Krogdahl Ifi, UiO

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

UNIVERSITETET I OSLO

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

Kap. 4 del I Top Down Parsering INF5110 v2006. Stein Krogdahl Ifi, UiO

Hovedstoffet i kap 4: 16. Februar Ifi, UiO

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

UNIVERSITETET I OSLO

Dagens tema: 12 gode råd for en kompilatorskriver

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

UNIVERSITETET I OSLO

Dagens tema: 12 gode råd for en kompilatorskriver. Sjekking av navn. Lagring av navn. Hvordan finne et navn?

Oppgaver til INF 5110, kapittel 4, med svarforslag Gjennomgått torsdag 14. febr Disse foilene er justert 15/2, kl. 11

INF5110 V2012 Kapittel 4: Parsering ovenfra-ned

UNIVERSITETET I OSLO

Kap. 5, del 1: Parsering nedenfra-opp (Bottom-up parsering) INF / Stein Krogdahl Ifi, UiO

UNIVERSITETET I OSLO

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

UNIVERSITETET I OSLO

Generiske mekanismer i statisk typede programmeringsspråk

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

UNIVERSITETET I OSLO

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

UNIVERSITETET I OSLO

INF Oblig 2 semantikksjekk og kodegenerering

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet doble.rusc (kalt kildekoden): Hva er kompilering?

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

Oppgave 2. INF5110 oppgave 2 på eksamen v04 med teori. FirstMengder. Arne Maus Ifi. Eks. 4.9 Beregning av First-mengde. terminal

UNIVERSITETET I OSLO

Obligatorisk Oppgave 1

Dagens tema: Sjekking

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

Oppgaver til INF 5110, kapittel 4, med svarforslag Gjennomgås tirsdag 21. febr. 2012

Syntaksanalyse. Skanner (repetisjon) Parsering top-down bottom-up LL(1)-parsering Recursive descent Forutsetninger. IN 211 Programmeringsspråk

Runtimesystemer - II. Funksjoner som parametere. Virtuelle metoder

INF3110 Programmeringsspråk

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet

INF5110, 15/ Dagens temaer: Avslutning kap. 4 Begynne på kap. 5 Se på oppgave. Stein Krogdahl, Ifi UiO

Obligatorisk oppgave 1 INF Kompilatorteknikk Våren 2012 Frist mandag 19. mars

Statisk semantisk analyse - Kap. 6

Syntax/semantics - I INF 3110/ /29/2005 1

UNIVERSITETET I OSLO

MED SVARFORSLAG UNIVERSITETET I OSLO

INF Repetisjon: Hvordan bygge treet og analysere? 8. september Typisk situasjon. De problematiske syntaks-diagrammene

INF5110. Oblig 2 presentasjon

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

Obligatorisk Oppgave 1

Syntaksanalyse. Dagens tema: Språkdiagrammene Jernbanediagrammene er et ypperlig utgangspunkt for å analysere et program: INF2100 INF2100 INF2100

UNIVERSITETET I OSLO

INF1010 Arv. Marit Nybakken 2. februar 2004

UNIVERSITETET I OSLO

Statisk semantisk analyse - Kap. 6

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Dagens tema: INF2100. Syntaksanalyse. Hva annet gjør en kompilator? Sjekking av navnebruk. Testutskrifter

Transkript:

Eksamen i : UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet med svar INF5110 - Kompilatorteknikk Eksamensdag : Onsdag 3. juni 2014 Tid for eksamen : 14.30-18.30 Oppgavesettet er på : Vedlegg : Tillatte hjelpemidler : 7 sider (pluss 1 side vedlegg) 1 side (side 8). Hvis denne siden brukes til besvarelse av spørsmål 3, da rives den ut og leveres i hvit besvarelse lle trykte og skrevne Les gjennom hele oppgavesettet før du begynner å løse oppgavene. Dersom du savner opplysninger i oppgavene, 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. Oppgave 1 (35%) Vi ser på følgende grammatikk G1: # # = a Her er eneste ikke-terminal, og er dermed også start-symbol. I tillegg til #, = og a er også $ terminalsymbol, med vanlig betydning. 1a Finn First og Follow til i G1 Svar 1a: First() = { #, a. Follow() = { =, $. 1b Tegn LR(0)-DFen til G1 (med vanlig tillegg av én produksjon). Nummerer tilstandene fra 0 og oppover.

Svar 1b G1: # # = a 0 1... #. # = 2. a a a. # a 3 4 #. #. =. #. # =. a 5 # # #. #. = = # =. a. #. # = 6. a # =. 1c Gå gjennom alle tilstandene i LR(0)-DFen til G1 og angi for hver av dem om de har noen SLR(1)- konflikter, og i så fall hvilke. Forklar. Svar 1c Tilstander: 0 Skift for a og #. Er SLR(1)-tilstand 1 Bare red. med (= «accept») for $ ( Follow = {$). Er SLR(1). 2 Bare red. med a for = og $. Er SLR(1). 3 Skift for a og #. Er SLR(1). 4 Skift for = og red. med # for = og $. ltså konflikt for =. Er ikke SLR(1) 5 Skift for a og #. Er SLR(1). 6 Reduksjon med # = for = og $. Er SLR(1). (Ikke spurt om, men: På grunn av tilstand 4 er grammatikken altså ikke SLR(1) ) 1d Vis at G1 er flertydig. Svar 1d Denne grammatikken er flertydig på samme måte som «dangeling else» i if-setninger, om vi ser # som «if then» og = som «else». Vi kan da tenke på at to «if»er og én «else» der gav problemer («hvilken if har else»), og dermed kan vi forsøke med følgende setning: # # a = a. Denne kan avledes fra på to måter:

# # a = a # # a = a Dermed kunne vi også vite at under 1c kunne grammatikken ikke bli SLR(1), siden alle SLR(1)- grammatikker (og andre LR-grammatikker) er entydige. 1e Du skal her sette opp en SLR(1)-parseringstabell for G1. Om grammatikken ikke er SLR(1) (og du derved får flere mulige aksjoner i en eller flere «tabell-ruter»), skal du gjøre et fornuftig valg av aksjon blant de aktuelle i denne «ruten». ngi i hvilke tilstander du da må gjøre slike eksplisitte valg, og begrunn hvorfor du gjør de valgene du gjør. Svar 1e # a = $ ------------------------------------------------------------------------------------------------------------ 0 s3 s2 1 1 accept 2 r( a ) r( a ) 3 s3 s2 4 4 NB: r( # ) / s5 r( # ) 5 s3 s2 6 6 r( # = ) r( # = ) ------------------------------------------------------------------------------------------------------------- Her er det altså to muligheter i rute [4, =], nemlig reduksjon med r( a ) og skift. En generell regel sier her at det ved skift/reduser-konflikter lønner seg å heller gjøre skift enn reduksjon. Dette fører her til at vi binder = til nærmeste #, slik vi også gjorde for if-then-else-setninger. (Det var ikke spurt om det, men det motsatte valget ville føre til en parser som ikke virker). 1f Vi skal se på LL(1)-analyse (f.eks. med «recursive descent») av setninger i G1. Gjør «tradisjonelle» forandringer (angitt i boka) på G1 slik at den nye grammatikken, G2, kan egne seg bedre for slik analyse. ngi G2. Svar 1f G1 er altså: # # = a Boka sier at to ting hvertfall må vekk om vi skal ha håp om å kunne gjøre LL(1)-analyse, nemlig venstre-rekursjon og at to alternativer starter på samme måte. Venstre-rekursjon finnes ikke, men de to første alternativene begynner på samme måte. Dette kan ordnes med «venstre-faktorisering», og man får da følgende grammatikk G2 (der L er ment å stå for «likhets-del» tilsvarende «elsedel»):

# L a L = ε (Ikke spurt om: Nå kunne man jo gjette ut fra at G1 var flertydig (og dermed ikke LL(1)), at heller ikke G2 er LL(1). Men G2 kunne danne grunnlaget for en recursive descent parser, om man bare fortsatte å lese i situasjoner tilsvarende den i rute [4, =] i oppgave 1e.) 1g vgjør om L(G1) er et regulært språk. Forklar! Svar 1g Språket L(G1) er ikke regulært. Dette kan man se av at en setning av formen: # #... # a = a = a = a med vilkårlig mange # -tegn og «= a»-grupper, er med i L(G1) hvis og bare hvis det er minst like mange # -tegn som «= a»-grupper. Men dette kan ikke være et regulært språk fordi en automat med et endelig antall tilstander ikke kan «telle opp» og ta med seg videre antall # -tegn, slik at dette kan sjekkes mot antall «= a»-grupper i resten av setningen. Oppgave 2 (20%) Vi antar at vi har et objekt-orientert språk, hvor alle metoder i klasser er virtuelle slik at de kan redefineres i subklasser. En standard måte å implementere tilstandsmaskiner i et slikt språk er å representere tilstander ved objekter av tilstandsklasser som er blad -klasser i et klassehierarki. Mulige hendelser i de forskjellige tilstander representeres som virtuelle metoder, og disse redefineres eventuelt i de forskjellige tilstands-subklasser. Koden under definerer en klasse Watch som en tilstandsmaskin med tilstandene Display, Hours og Minutes. Klokken endrer tilstand ved at det trykkes på en mode-knapp, som (indirekte, se under) fører til et kall på metoden mode. I tilstanden Display vises bare tiden, mens man i de andre tilstander kan øke enten timer eller minutter med 1 ved å trykke på incr-knappen som fører til et kall på metoden incr. Tilstandsklassene er definert som indre klasser i Watch for at variablene time og currentstate skal være tilgjengelige i metodene i de tilstandsklassene. Klassen Time definerer hvordan tid representeres, og vi forutsetter at den har metodene incrhours og incrminutes. class Watch { Time time = new Time(); State currentstate; void mode(){ currentstate.mode(); void incr(){ currentstate.incr(); Watch(){ currentstate = new Display(); class State { void mode(){... void incr(){... class Hours extends State { void mode(){currentstate = new Minutes(); void incr(){ /* 1 */ time.incrhours(1); class Minutes extends State { void mode(){currentstate = new Display(); void incr(){ time.incrminutes(1); class Display extends State { void mode(){currentstate = new Hours();

void settime(time newtime){time = newtime; class Time {... Vi antar at det i tillegg finnes et objekt av en klasse WatchInterface, som i en metode sense registrerer trykk på knapper som svarer til metodene mode og incr, og som kaller mode eller incr på det Watch-objektet som er tilknyttet WatchInterface-objektet. Her vises det utsnitt av sense hvor incr kalles: class WatchInterface { Watch thewatch = new Watch(); void sense(){...; if <mode button pressed> then thewatch.mode() else if <incr button pressed> then thewatch.incr();... 2a Tegn runtime-stakken som den ser ut som et resultat av dette kallet, rett før incr skal utføre time.incrhours(1), altså at utførelsen er ved /* 1 */ i koden ovenfor. Starten på stakken er en activation record som svarer til et kall på sense. nta at thewatch-objektet er i tilstanden Hours. Ta bare med activation records og ikke objekter, og for activation records tar du bare med control links. Svar 2a 2b Lag virtuell-tabellene for objekter av klassene State, Hours, Minutes og Display. For hvert element i tabellene skal du bruke notasjonen <klasse>::<metode> for å angi hvilken metode som gjelder. Ta høyde for at det finnes subklasser av Display som ikke er tatt med i koden over.

Svar 2b State 0 State::mode 1 State::incr Hours 0 Hours::mode 1 Hours::incr Minutes 0 Minutes::mode 1 Minutes::incr Display 0 Display::mode 1 State::incr 2 Display::setTime 2c Metoden settime kalles fra en metode i en klasse i Watch som ikke er tatt med i koden ovenfor. settime kalles som et resultat av at klokken får et radiosignal med ny (korrekt) tid, og den inneholder følgende kode:... // receive new time via radiolink (Display)currentState.setTime(receivedTime);... Man vil bare kalle settime mens klokken er i tilstanden Display, derfor forsøker man seg med denne type-castingen, som vil gi en runtime feil hvis currentstate ikke er et objekt av klassen Display. Dette er ikke den optimale måten å gjøre det på, men slik ble det gjort. Ovenfor er det eksempel på en down-cast (fra State til Display), men vi antar at man kan gjøre både down-cast og up-cast. Ovenfor har vi sett at objekter har en peker til en virtuell-tabell. Hva trenger du å vite om objekter, i tillegg til virtuell-tabellen, for å implementere en slik casting. Beskriv dette og lag en skisse av den koden som skal utføres for å gjøre denne testen. Svar 2c Man må vite klassen til objektet, og klassen må representeres på en slik måte at du har informasjon om dens superklasse, for eksempel: class Class { String Name; Class super; 2d Hvordan vil kompilatoren bruke denne castingen i sjekking av statisk semantikk? Svar 2c Typen til currentstate er State, og settime er i symboltabellen (eller i syntakstreet) ikke definert i State. Castingen gjør at man skal slå opp settime i symboltabellen tilsvarende klassen Display. 2e Ett kall på awatch.mode() fører til et kall på currentstate.mode(). Hva oversettes dette kallet til?

Svar 2c Kall på currentstate.vt[index(mode)] 2f Man ser at klassen State egentlig bare har de samme metoder som den omsluttende klasse (her Watch) og at man bare bruker virtuell-tabellene for State-objektene. Man går derfor over til et annet objekt-orientert språk, der følgende tre ting gjelder: 1. virtuelle metoder kan redefineres i indre klasser som er definert som STTE-klasser (se syntaks for STTE-klasser i koden under) 2. virtuell-tabellen pekes ut av en predefinert variabel _STTE 3. ved å assigne en STTE-klasse til _STTE endrer man virtuell-tabellen til den som gjelder for STTE-klassen. class Watch { Time time; void mode(...) void incr(...) Watch (){ _STTE = Display; class Hours STTE { void mode(){ _STTE = Minutes; void incr(){ time.incrhours(1); class Minutes STTE { void mode(){ _STTE = Display; void incr(){ time.incrminutes(1); class Display STTE { void mode(){ _STTE = Hours; void settime(time newtime){time= newtime; Hva oversettes awatch.mode() da til? Svar 2c awatch._stte[index(mode)] Oppgave 3 (20%) I denne oppgaven bruker vi språket som ble innført i 2f. Det følgende er et fragment av grammatikken for språket. Vi har bare tatt med de detaljer i språket som er aktuelle for oppgaven: classdecls classdecls ; classdecl classdecls classdecl classdecl class name { methoddecls classdecls classdecl class name STTE{ methoddecls methoddecls methoddecls ; methoddecl methoddecls methoddecl methoddecl type name () body

type int type bool type void Ord i kursiv er ikke-terminaler, ord og tegn i fet skrift er terminal-symboler, mens name representerer et navn som scanneren leverer. Det kan antas at name har attributtet name. I dette språket er en metode uten parametere og med typen void en såkalt event-metode. Den semantiske regelen er at en event-metode i en indre STTE-klasse må matche en event-metode i den omsluttende klasse. Den semantiske regelen som uttrykker akkurat dette er allerede lagt inn i attributtgrammatikken (ved attributtet error i methoddecl. MERK: Her var det en trykkfeil i oppgaven, det stod «match» i stedet for «error»), og denne reglen baserer seg på følgende attributter: classdecl eventmethods: set of names of event-methods for this class enclosingeventmethods: set of names of event-methods from enclosing class that should match the event methods for this class in case it is a STTE class methoddecls enclosingeventmethods: set of names of event-methods from enclosing class that should match the event methods among methods represented by this methoddecls shallmatcheventmethod: true if the methods represented by this methoddecls are methods of a STTE class, false otherwise methoddecl enclosingeventmethods: set of names of event-methods from enclosing class that shall contain the name of the method represented by this methoddecl shallmatcheventmethod: true if method of a STTE class, false otherwise error: true if method of a STTE class matches an event method of the enclosing class, false otherwise Trykkfeil, denne manglet: eventmethods: The (set of) the name of the method declaration. Det brukes følgende funksjoner, samt union av mengder (+): set(name): Lager en mengde med name som element s.lookup(name): true if name is in the set, otherwise false Gjør ferdig de semantiske regler for disse attributter. Du kan besvare dette spørsmålet ved å bruke vedlegget side 8 eller ved å lage en tilsvarende tabell selv.

Svar 3 (se også egen figur lagt ved som eget dokument) Grammar Rule classdecls 1 classdecls 2 ; classdecl classdecls classdecl Semantic Rule classdecls 2.enclosingEventMethods = classdecls 1.enclosingEventMethods classdecl.enclosingeventmethods = classdecls 1.enclosingEventMethods classdecl.enclosingeventmethods = classdecls.enclosingeventmethods classdecl class name { methoddecls classdecls classdecl.eventmethods = methoddecls.eventmethods classdecls.enclosingeventmethods = classdecl.eventmethods methoddecls.shallmatcheventmethod = false classdecl class name STTE { methoddecls methoddecls 1 methoddecls 2 ; methoddecl methoddecls.shallmatcheventmethod = true methoddecls.enclosingeventmethods = classdecl.enclosingeventmethods methoddecls 2.enclosingEventMethods = methoddecls 1.enclosingEventMethods methoddecl.enclosingeventmethods = methoddecls 1.enclosingEventMethods methoddecls 1.eventMethods = methoddecls 2.eventMethods + methoddecl.eventmethods methoddecls 2.shallMatchEventMethod = methoddecls 1.shallMatchEventMethod methoddecl.shallmatcheventmethod = methoddecls 1.shallMatchEventMethod methoddecls methoddecl methoddecls.eventmethods = methoddecl.eventmethods methoddecl.enclosingeventmethods = methoddecls.enclosingeventmethods methoddecl.shallmatcheventmethod = methoddecls.shallmatcheventmethod methoddecl type name () body if type.type= void then methoddecl.eventmethods = setof(name) (Trykkfeil, må ha: else methoddecl.eventmethods = Ø ) error = if type.type = void and methoddecl.shallmatcheventmethod then if methoddecl.enclosingeventmethods.lookup(name) then true else false

Oppgave 4 (25%) Vi skal her se på kodegenerering for «lange» if-then-else setninger av formen: if <condition> then <statement> elseif <condition> then <statement> elseif <condition> then <statement> elseif <condition> then <statement> else <statement> endif Her er elseif et nytt nøkkelord, og meningen med setningen skulle fremgå av syntaksen. Det kan være null eller flere elseif-grener, og null eller én else-gren til slutt. 4a Skissér et flyt-diagram (med bokser som angir koden til setninger og betingelser) som viser hvordan denne setningen kan oversettes, og angi spesielt hvordan «labler» og hopp skal plasseres. Svar 4a Betingelse 1 Test på true/false Setning 1 Betingelse 2 Test på true/false Setning 2...... Betingelse n Test på true/false Setning n False True False True False True Ubet. hopp Ubet. hopp Kommentar: Det er her ikke helt klart ut fra oppgaven akkurat hvordan denne tegningen skal se ut. Å bruke piler som her er OK, men om det i stedet er brukt noen betingede og ubetingede hopp-instruksjoner, og noen velplasserte labler som det hoppes til, så er det også OK. Tegninger lik den til venstre, men uten de tre true-pilene er også OK (siden programmet da ville falle gjennom, til setningen under, som er det riktige). Tegningen er laget ut fra et det er en elsegren til slutt (Setning n+1). Om det ikke er det blir det noen opplagte forandringer. Vi krevet ikke at man skulle omtale det. Setning n+1 Ubet. hopp

4b Vi antar at setninger beskrevet i forrige punkt er representert i det abstrakte syntakstreet med følgende nodeklasser (i Java): class Statement extends { // Vi bryr oss ikke med klassehierarkiet over dette nivået abstract void codegen( ); static String getnewlabel( ) { er ferdig programmert // genererer nye label-navn class IfStatement extends Statement { ElseIf first; /* Peker til første i en liste av ElseIf-objekter (se klassen ElseIf under). Merk at også «condition/statement»-paret som følger direkte etter første if er med i denne listen, slik at den alltid inneholder minst ett element. */ Statement elsestat; // NULL om det ikke er else-gren void codegen { // Denne skal du skrive! Og vi anbefaler at all kodegenerering for if-setningen gjøres her. class ElseIf extends { Condition cond; Statement stat; ElseIf next; // NULL om den er den siste i elseif-lista // nbefaling: Ingen codegen( ) her. ll T-kode generes da fra codegen() i IfStatement. class Condition extends { String codegen() { /* Denne skal du kalle, men ikke skrive. Den vil generere kode som beregner verdien av betingelsen (true eller false), og vil leverere en String som er navnet på den variabelen der svaret vil ligge. Se detaljer under. */ Vi antar at treet for det aktuelle programmet er satt opp før vi starter kodegenereringen. Merk altså at det her bare er den codegen-metoden som behandler «Condition» som leverer en String. Denne String en vil altså være navnet på den (kanskje temporære) variablen der svaret (true eller false) vil ligge etter at denne «Condition» er beregnet under utførelsen. For å få lagt ut en T-instruksjon kan du kalle metoden «void emit(string instr){» (som er direkte synlig). Denne er ferdig skrevet, og instruksjonene fra påfølgende kall vil da bli lagt pent etter hverandre på en fil. De T-instruksjonene du trenger burde være kurante (og det er ikke nøye om de har akkurat samme syntaks som i boka).

Oppgaven: Les kommentarene i klassene over nøye, og skriv så innmaten av void codegen( )» i IfStatement (slik som antydet over). Vi anbefaler altså at du skriver denne metoden slik at den gjør all kodegenerering for hele if-setningen, men det er også OK om du legger noe av arbeidet inn i en «codegen»-metode i ElseIf-klassen. Svar 4.b Først figuren fra 4.a: Betingelse 1 Test på true/false Setning 1 Betingelse 2 Test på true/false Setning 2...... Betingelse n Test på true/false Setning n False True False True False True Ubet. hopp Ubet. hopp Setning n+1 Ubet. hopp Labfter void codegen( ) { String labnext ; // Lablen på kommende betingelse String labfter = getnewlabel( ); // Lablen bak hele vår setning String tempname; ElseIF current = first; while (current!= null) { labnext = getnewlabel( ); tempname = current.cond.codegen( ); emit( if_false + tempname + goto + labnext ); current.stat.codegen ( ); emit ( goto + labfter); emit ( label + labnext); // Dette gir også en riktig label foran en eventuell else-setning current = current.next; If (elsestat!= null) { elsestat.codegen( ); emit ( label + labfter);

4c Du skal her skrive codegen( )-metoden i klassen IfStatement (se 4b) en gang til, men under litt andre betingelser. Denne gangen antar vi at codegen-metoden i klassen Condition har to stringparametere (som er label-navn), og at metoden ikke leverer noen String. Når den kalles skal den (som parametre) få med «labler» som angir stedene man skal hoppe til dersom betingelsen blir hhv. true og false. Koden den genererer vil alltid hoppe til en av disse lablene (og altså aldri «falle gjennom» til instruksjonen etter). Klassen Condition er slik: class Condition extends { void codegen(string truelab, falselab) { // Denne skal du kalle, men ikke skrive. Les teksten over om hva den gjør. Oppgaven: Skriv en ny utgave av codegen()-metoden i klassen IfStatement under de betingelser som er beskrevet over. Det er viktig her at alle hopp blir så direkte som mulig. Svar 4c Svaret her blir nokså likt det på 4b. Under er det som er nytt i forhold til 4b angitt i blått, og det som skal vekk er skrevet i grønt med strek over: void codegen( ) { String labstat; // Label på førstkommende setning String labnext; // Label på førstkommende betingelse String labfter = getnewlabel( ); String tempname; ElseIF current = first; while (current!= null) { labstat = getnewlabel( ); labnext = getnewlabel( ); tempname = current.cond.codegen(labstat, labnext ); emit( if_false + tempname + goto + labnext ); emit ( label + labstat); current.stat.codegen ( ); emit ( goto + labfter); emit ( label + labnext); // Dette gir også en riktig label foran en eventuell else-setning current = current.next; If (elsestat!= null) { elsestat.codegen( ); emit ( label + labfter);

Vi tar også med en renskrevet versjon: void codegen( ) { String labstat; // Label på førstkommende setning String labnext; // Label på førstkommende betingelse String labfter = getnewlabel( ); ElseIF current = first; while (current!= null) { labstat = getnewlabel( ); labnext = getnewlabel( ); current.cond.codegen(labstat, labnext ); emit ( label + labstat); current.stat.codegen ( ); emit ( goto + labfter); emit ( label + labnext); // Dette gir også en riktig label foran en eventuell else-setning current = current.next; If (elsestat!= null) { elsestat.codegen( ); emit ( label + labfter);