Dagens tema: 12 gode råd når man rammerer en kompilator Råd nr 1: Start nå! Det tar typisk 10 50 timer å rammere Del 1 om man ikke har gjort slikt før. Hvor mange timer per dag blir det? Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 1 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 2 av 20 Råd nr 2: Forstå problemet! Forstå hva du skal gjøre før du begynner å rammere. Skriv noen korte kodesnutter i Minila. Tegn syntakstrærne deres. Studér eksemplet med kalkulatoren i forrige og denne ukes øvelsesoppgaver. NB! På dette stadium kan man samarbeide så mye man ønsker! Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 3 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 4 av 20 var n; outtext "Skriv et tall: "; n := inint; outtext "Det dobbelte er "; outint(1) 2*n; outline; InIntPart ConstPart VarPart Expression Expression VarDecl OutText Assign OutText OutInt OutLine Decl DeclSeqv Seqv Program
Råd nr 3: Start med noe enkelt! Ingen bør forvente at de kan skrive all koden og så bare virker den. Start med et enkelt rammeringsspråk Program : og få det til å virke først. Utvid etter hvert. Sjekk hver utvidelse før du går videre. Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 5 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 6 av 20 listresp.testaout("ut","program"); if(! symbgen.curis("")) mainresp.error("forventet "); if(! symbgen.curis("")) mainresp.error("forventet "); if(! symbgen.curis("")) mainresp.error("programmet startet ikke med "); class Program { listresp.testaout("inn", "Program"); Koden for dette blir noe à la Råd nr 4: Ikke sitt og stirr på koden! Når rammet ikke virker: ❶ Se på siste versjon av ramkoden og der du forventer å finne feilen. ❷ Hvis du ikke har funnet feilen i løpet av fem minutter, gå over til aktiv feilsøking. Råd nr 5: Les testutskriftene! Del 1 skal produsere to testutskrifter: A forteller hvilke analyze metoder som kalles. Anta at vi har rammet var i; i := 3; Det gir en feilmelding ***Feil: Forventet Hva er da galt? Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 7 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 8 av 20
Svaret kan vi finne i utskriften fra A: 1: A: INN Program 3: ***Feil: Forventet Utskriften skulle ha vært 1: A: INN Program A: INN DeclSeqv A: INN VarDecl 3: A: UT VarDecl 4: i := 3; A: UT DeclSeqv A: INN Seqv A: INN Assign A: INN AssignVar A: UT AssignVar A: INN Expression A: INN ConstPart 5: A: UT ConstPart A: UT Expression A: UT Assign A: UT Seqv A: UT Program P gir en utskrift av det genererte treet. Anta at vi har det samme testrammet var i; i := 3; Hvis P utskriften er 1: 3: 4: i := 3; 5: P testutskrift: Skriver innholdet av treet. var i ; så vet vi at setninglisten ikke settes opp riktig.... eller at det er feil i P utskriften. Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 9 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 10 av 20 Råd nr 6: Lag egne testutskrifter Her er litt kode fra Seqv.analyze: listresp.testaout("inn", "Seqv"); new = null; while (moreences()) { if (symbgen.curisname()) { new = new Assign(); else if (symbgen.curis("call")) { new = new Call(); else if (symbgen.curis("if")) { new = new If(); else if (symbgen.curis("intext")) { new = new InText(); else if (symbgen.curis("outchar")) { new = new OutChar(); else if (symbgen.curis("outint")) { new = new OutInt(); else if (symbgen.curis("outline")) { new = new OutLine(); else if (symbgen.curis("outtext")) { new = new OutText(); else if (symbgen.curis("while")) { new = new While(); new.analyze(localdeclseqv); add(new); Anta at vi får melding om null peker linjen med new.analyze. Slikt skal ikke skje. Mitt råd er å legge inn noe à la while (moreences()) { System.out.println("Seqv.analyze: " + "symbgen.curis er " + symbgen.curis()); if (! symbgen.curis(";")) mainresp.error("forventet ; etter setning"); listresp.testaout("ut", "Seqv"); Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 11 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 12 av 20
Råd nr 7: Behold testutskriftene! Når feilen er funnet, bør man la testutskriften forbli i koden. Man kan få bruk for den igjen. Derimot bør man kunne slå den av eller på: Råd nr 8: Mistro din egen kode! Det er altfor lett å stole på at ens egen kode andre steder er korrekt. Løsningen er å legge inn assertions som bare sjekker at alt er som det skal være (som vist her i If.analyze): ❶ Det mest avanserte er å bruke opsjoner på kommandolinjen: java MinMinila debugss.a test.min listresp.testaout("inn", "If"); assert symbgen.curis("if"): "If setning starter ikke med if."; ❷ Det fungerer også godt å benytte statusvariable:. static boolean debugss_a = true;. if (debugss_a) { System.out.println("Seqv.analyze: " + "symbgen.curis er " + symbgen.curis()); NB! Husk å kjøre med java ea Minila for å slå på mekanismen. Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 13 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 14 av 20 Råd nr 9: Sjekk spesielt på readsymbol! Det er lett å kalle readsymbol en gang for mye eller for lite. Her er et forsøk på å skrive If.analyze: listresp.testaout("inn", "If"); cond = new Condition(); cond.analyze(localdeclseqv); if (! symbgen.curis("then")) mainresp.error("forventet then etter betingelse"); SS = new Seqv(); SS.analyze(localDeclSeqv); if (symbgen.curis("else")) { elsess = new Seqv(); elsess.analyze(localdeclseqv); Husk kontrakten med SymbolGenerator Her er reglene som analyze metodene må følge: ❶ Når man kaller analyze, skal første symbol være lest inn! ❷ Når man returnerer fra en analyze, skal første symbol etter konstruksjonen være lest. Vær spesielt oppmerksom på if tester og løkker. if (! symbgen.curis("endif")) mainresp.error("forventet endif til slutt i If setn"); listresp.testaout("ut", "If"); Hvor skal det kall på readsymbol? Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 15 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 16 av 20
Slik skal metoden være: listresp.testaout("inn", "If"); cond = new Condition(); cond.analyze(localdeclseqv); if (! symbgen.curis("then")) mainresp.error("forventet then etter betingelse"); SS = new Seqv(); SS.analyze(localDeclSeqv); if (symbgen.curis("else")) { elsess = new Seqv(); elsess.analyze(localdeclseqv); Råd nr 10: Ta kopier daglig eller oftere! Programmering er mye prøving og feiling. Noen ganger må man bare glemme alt man gjorde den siste timen. Det finnes systemer for versjonskontroll som man bør lære seg før eller siden. I mellomtiden kan man ha nytte av ❶ Ta en kopi av Java filen hver gang du starter med å legge inn ny kode. if (! symbgen.curis("endif")) mainresp.error("forventet endif til slutt i If setn"); listresp.testaout("ut", "If"); ❷ Ta uansett en kopi hver dag (om noe som helst er endret). Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 17 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 18 av 20 Råd nr 11: Fordel arbeidet! Dere er to om jobben. Selv om begge må kjenne til hovedstrukturen, kan man fordele rammeringen. Forslag ❶ Én tar det som har med deklarasjoner. Råd nr 12: Bruk hjelpemidlene Spør gruppelærerne! De er tilgjengelige under gruppetimene og svarer på e post til andre tider. ❷ Én tar det som har med setninger. Men... Snakk ofte sammen. Planlegg hvordan dere bruker filene så ikke den ene ødelegger det den andre har gjort. NB! Siste uken før oblig fristene vil de sitte (til vanlige tider) på terminalstuen i Abel for å svare på spørsmål. Les kompendiet Stoffet er forklart med flere detaljer der enn det er mulig på forelesningene. Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 19 av 20 Dag Langmyhr,Ifi,UiO: Forelesning 18. oktober 2005 Ark 20 av 20