Dagens tema: Mer av det dere trenger til del 1



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

Dagens tema: 12 gode råd for en kompilatorskriver

Dagens tema: Resten av det dere trenger til del 1

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

Dagens tema: Resten av det dere trenger til del 1

Dagens tema: 12 gode råd for en kompilatorskriver. Prosjektet. Koblingen mellom grammatikken og klasser. Utifra dette RusC-programmet:

Dagens tema: 12 gode råd for en kompilatorskriver. Prosjektet. Modifikasjon av grammatikken. Utifra dette RusC programmet:

Råd nr 1: Start nå! Det tar typisk timer å programmere Del 1 om man ikke har gjort slikt før. Dagens tema:

Dagens tema: Mer av det dere trenger til del 1

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

Oversikt Kompilering Syntaksanalyse Java Feilsjekking Oppsummering

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

Dagens tema: Resten av det dere trenger til del 1

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

Del 3: Evaluere uttrykk

Oversikt Kodegenerering Variabler Setninger Uttrykk While-setningen

Dagens tema: Sjekking

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

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

INF2100. Oppgaver uke 40 og

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

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

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

INF2100. Oppgave 1. Oppgave 2 4. Løsningsforslag til oppgaver uke 40 og Se figur 1 på neste side.

INF2100. Oppgaver 23. og 24. september 2010

Oblig 4 (av 4) INF1000, høsten 2012 Værdata, leveres innen 9. nov. kl

INF2100. Oppgaver 9. oktober 2012 C 100 X 10

Diverse eksamensgaver

Dagens tema: Kompilatorens struktur. De ulike modulene Prosjektet. Oppbyggingen Pakker i Java Avbrudd («exceptions») Enum-klasser i Java

INF1000 Metoder. Marit Nybakken 16. februar 2004

Dagens tema: Kompilatorens struktur. De ulike modulene Prosjektet. Oppbyggingen Pakker i Java Avbrudd («exceptions») Enum-klasser i Java

Introduksjon til objektorientert. programmering. Hva skjedde ~1967? Lokale (og globale) helter. Grunnkurs i objektorientert.

UNIVERSITETET I OSLO

INF2100. Oppgaver 6. og 11. oktober 2011 C 100 X 10

TOD063 Datastrukturer og algoritmer

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

Kapittel 7: Mer om arv

Dagens tema: Resten av det dere trenger til del 1

Oversikt Deklarasjoner Typesjekk Programmering Datamaskinhistorie x86 Kodegenerering

Tre måter å lese fra terminal. Java 4. Eksempel. Formatert utskrift til skjerm

INF Seminaroppgaver til uke 3

UNIVERSITETET I OSLO

Dagens tema: Sjekking (obligatorisk oppgave 3)

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Programmeringsspråk for nybegynnere. Krav til språket. Krav til språket. Krav til språket

Utførelse av programmer, metoder og synlighet av variabler i JSP

Løsningsforslag ukeoppg. 9: okt (INF Høst 2011)

Løsningsforslag ukeoppg. 6: 28. sep - 4. okt (INF Høst 2011)

Konstruktører. Bruk av konstruktører når vi opererer med "enkle" klasser er ganske ukomplisert. Når vi skriver. skjer følgende:

TDT4100 Objektorientert programmering

Algoritmer og datastrukturer Kapittel 9 - Delkapittel 9.2

INF1010 Arv. Marit Nybakken 2. februar 2004

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

Jentetreff INF1000 Debugging i Java

UNIVERSITETET I OSLO

2 Om statiske variable/konstanter og statiske metoder.

UNIVERSITETET I OSLO

INF2100. Oppgave 1, 2 og 3. Løsningsforslag til oppgaver 23. og 24. september Her er det mange mulige løsninger her er én: import java.io.

Løse reelle problemer

Universitetet i Bergen Det matematisk-naturvitenskapelige fakultet Institutt for informatikk

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

Velkommen til INF2100

IN1010 våren januar. Objektorientering i Java

Kapittel 9: Sortering og søking Kort versjon

OPPGAVE 5b og 8b Java Kode

UNIVERSITETET I OSLO

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring AITeL

UNIVERSITETET I OSLO

Kapittel 1. Datamaskiner og programmeringsspråk. 1.1 Programmering

Programmeringsspråket C

TDT4102 Prosedyreog objektorientert programmering Vår 2016

INF1000: Forelesning 7

INF 1010, vår 2005 Løsningsforslag uke 11

INF1010 våren januar. Objektorientering i Java

HØGSKOLEN I SØR-TRØNDELAG

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

INF Uke 10. Ukesoppgaver oktober 2012

Forelesning inf Java 4

INF 1000 høsten 2011 Uke september

OBJEKTER SOM EN PROGRAMMERINGS-TEKNIKK

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Lese fra fil. INF1000 : Forelesning 5. Eksempel. De vanligste lesemetodene. Metoder:

Repitisjonskurs. Arv, Subklasser og Grensesnitt

Fra Python til Java. En introduksjon til programmeringsspråkenes verden. Dag Langmyhr

Forelesningsquiz. Forelesning inf Java 5. Sett dere to (eller tre) sammen og besvar de fire spørsmålene på utdelt ark. Tid: 15 min.

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

Enkle generiske klasser i Java

Viktig. Rettet i koden. Oppgaven. Obligatorisk oppgave 2 - Kort om oppgaven og litt informasjon. Fredrik Sørensen OMS-gruppen, IfI

Programmering i C++ Løsningsforslag Eksamen høsten 2005

Semantisk Analyse del I

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

Forklaring til programmet AbstraktKontoTest.java med tilhørende filer Konto.java, KredittKonto.java, SpareKonto.java

INF1000: Forelesning 6. Klasser og objekter del 1

Fra problem til program

Hva er kompilering? Dagens tema. En kompilator En kompilator leser Minila koden og lager Flok koden.

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.

INF1000: Forelesning 7. Konstruktører Static

Forkurs INF1010. Dag 2. Andreas Færøvig Olsen Gard Inge Rosvold Institutt for Informatikk, 14.

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

Transkript:

Dagens tema Dagens tema: Mer av det dere trenger til del 1 Hvilke klasser trenger vi? Uttrykk Typer Testutskrifter 12 gode råd

Dagens tema Prosjektet Utifra dette AlboC-programmet: int pot2 (int x) { int p2; p2 = 1; while (2*p2 <= x) { p2 = 2*p2; return p2; int x; int main () { int v; v = getint(); x = pot2(v); putint(x); putchar(10);

Dagens tema... skal vi bygge opp dette treet (som her er klippet): Program GlobalDeclList FuncDecl GlobalVarDecl FuncDecl ParamDeclList FuncBody ParamDeclList FuncBody ParamDecl LocalDeclList StatmList LocalDeclList StatmList DeclType LocalVarDecl AssignStatm WhileStatm ReturnStatm LocalVarDecl AssignStatm AssignStatm CallStatm CallStatm DeclType

Hvor mange klasser trenger vi? Koblingen mellom grammatikken og klasser Normalt skal det være én klasse for hvert metasymbol (definisjon) i grammatikken: while-statm while ( expression ) { statm list class WhileStatm extends Statement { Expression test; StatmList body;

Hvor mange klasser trenger vi? Ekstra klasser Noen ganger kan vi innføre ekstra klasser fordi 1 noen metasymboler hører naturlig sammen og/eller 2 vi må lagre noe informasjon. Eksempel: DeclList program declaration func decl name ( param decl, ) func body abstract class DeclList extends SyntaxUnit { Declaration firstdecl = null; DeclList outerscope;

Hvor mange klasser trenger vi? Noen ganger kan vi velge å implementere et metasymbol med flere klasser fordi 1 ulike varianter trenger forskjellig data og/eller 2 de kan trenge ulike virtuelle metoder. Eksempel: VarDecl er implementert som en abstrakt klasse med tre underklasser: GlobalVarDecl, LocalVarDecl og ParamDecl.

Hvor mange klasser trenger vi? Noen ganger kan man droppe å lagre et metasymbol: kan lagres som x = 4; return x; StatmList Statement Statement StatmList AssignStatm ReturnStatm eller AssignStatm ReturnStatm (Varianten til høyre er brukt i prosjektet vårt. Statement er da bare en abstrakt klasse.)

Hvor mange klasser trenger vi? Hint Hvis du stadig programmerer «Hvis det er den varianten, gjør jeg det, og hvis...», kan subklasser med en virtuell metode være løsningen. Dette gjelder spesielt ved test på instanceof.

Hvordan lagre uttrykk Uttrykk Et uttrykk har én eller to termer: expression term rel opr term

Hvordan lagre uttrykk class Expression extends SyntaxUnit { Expression nextexpr = null; Term firstterm, secondterm = null; Operator relopr = null; Type type = null; static Expression parse() { Log.enterParser("<expression>"); Expression e = new Expression(); e.firstterm = Term.parse(); if (Token.isRelOperator(Scanner.curToken)) { e.relopr = RelOpr.parse(); e.secondterm = Term.parse(); Log.leaveParser("</expression>"); return e;

Hvordan lagre uttrykk Termer En term har én eller flere faktorer: term term opr factor Implementasjonen av dette må dere finne ut av selv.

Hvordan lagre uttrykk [SyntaxUnit] Expression [Operand] Address FunctionCall InnerExpr Number Variable [Operator] RelOpr Term Disse klassene (og de du lager selv) brukes til å lagre uttrykk.

Klassen Type Typer Modulen Types inneholder klasser og variabler for å representere typer. Basisklassen er Type: package no.uio.ifi.alboc.types; Type.java public abstract class Type { public abstract int size(); public abstract boolean issametype(type t); public abstract boolean maybeindexed(); public abstract Type getelemtype();

Klassen ValueType Enkle type som kan overføres som parametre og være returverdi for funksjoner (dvs int og pekere) er instanser av ValueType. ValueType.java package no.uio.ifi.alboc.types; public abstract class ValueType extends Type { @Override public boolean maybeindexed() { return false; // Most value types may not. @Override public Type getelemtype() { return null; // Most value types have none.

Modulklassen Types inttype opprettes som statisk variabel i modulen Types: package no.uio.ifi.alboc.types; Types.java public class Types { public static Type inttype; public static void init() { inttype = new ValueType() { @Override public String tostring() { return "int"; @Override public int size() { return 4; ; @Override public boolean issametype(type t) { return this == t;

Må alle klasser ha et navn? Anonyme subklasser Vanligvis deklarerer vi klasser og subklasser slik: abstract class Bil { abstract double antpassasjerer(); Bil.java Sportsbil.java class Sportsbil extends Bil { @Override double antpassasjerer() { return 1; Bilregister.java class Bilregister { public static void main(string arg[]) { Bil a = new Sportsbil();

Må alle klasser ha et navn? Hvis vi ikke trenger Sportsbil til noe annet, kan vi oppnå tilsvarende med en anonym subklasse: abstract class Bil { abstract double antpassasjerer(); Bil.java Bilregister2.java class Bilregister2 { public static void main(string arg[]) { Bil a = new Bil() { @Override double antpassasjerer() { return 1; ; $ ls *.class Bil.class Bilregister2$1.class Bilregister2.class

Må alle klasser ha et navn? Array-typer package no.uio.ifi.alboc.types; public class ArrayType extends Type { private int nelems; private Type elemtype; public ArrayType(Type t, int n) { elemtype = t; nelems = n; @Override public String tostring() { return elemtype + "[]"; @Override public int size() { return nelems * elemtype.size(); @Override public boolean issametype(type t) { return elemtype.issametype(t.getelemtype()); @Override public boolean maybeindexed() { return true; @Override public Type getelemtype() { return elemtype;

Må alle klasser ha et navn? Pekertyper package no.uio.ifi.alboc.types; public class PointerType extends ValueType { private Type elemtype; public PointerType(Type t) { elemtype = t; @Override public String tostring() { return elemtype + "*"; @Override public int size() { return 4; @Override public boolean issametype(type t) { return elemtype.issametype(t.getelemtype()); @Override public boolean maybeindexed() { return true; @Override public Type getelemtype() { return elemtype;

Oversikt Testutskrifter Det er lett å gjøre feil når man programmerer noe såpass komplisert som en kompilator. Det lureste er å godta dette og heller finne teknikker for å oppdage feilen. -logp avslører om man gjør riktige valg i jernbanediagrammene. La hver parse gi lyd fra seg. -logi sjekker om analysetreet ble riktig ved å skrive det ut etterpå.

logp Vårt testprogram int pot2 (int x) { int p2; p2 = 1; while (2*p2 <= x) { p2 = 2*p2; return p2; int x; int main () { int v; v = getint(); x = pot2(v); putint(x); putchar(10);

logp 1: int pot2 (int x) <program> <type> </type> <func decl> <type> </type> <param decl> 2: { </param decl> 3: int p2; p2 = 1; <func body> <type> </type> <var decl> </var decl> <statm list> <statement> <assign-statm> <assignment> <lhs-variable> <variable> </variable> </lhs-variable> <expression> <term> <factor> <primary> <operand> <number> 4: while (2*p2 <= x) { p2 = 2*p2; </number> </operand> </primary> </factor> </term> </expression> </assignment> </assign statm> </statement> <statement> <while-statm> <expression> <term> <factor> <primary> <operand> <number> </number> </operand>

logp Implementasjon Alle parse-metoder må kalle Log.enterParser("<while-statm>"); (eller tilsvarende) ved oppstart og Log.leaveParser("</while-statm>"); ved avslutning. Innrykk må håndteres automatisk.

logi Korrekt parsering av treet sjekkes enkelt ved å regenerere det (såkalt «pretty-printing»): Produsert av -logi Original int pot2 (int x) { int p2; p2 = 1; while (2*p2 <= x) { p2 = 2*p2; return p2; int x; int main () { int v; v = getint(); x = pot2(v); putint(x); putchar(10); Tree: int pot2 (int x) Tree: { Tree: int p2; Tree: Tree: p2 = 1; Tree: while (2 * p2 <= x) { Tree: p2 = 2 * p2; Tree: Tree: return p2; Tree: Tree: Tree: int x; Tree: Tree: int main () Tree: { Tree: int v; Tree: Tree: v = getint(); Tree: x = pot2(v); Tree: putint(x); Tree: putchar(10); Tree:

logi Et eksempel class WhileStatm extends Statement { Expression test; StatmList body; static WhileStatm parse() { Log.enterParser("<while-statm>"); WhileStatm ws = new WhileStatm(); Scanner.skip(whileToken); Scanner.skip(leftParToken); ws.test = Expression.parse(); Scanner.skip(rightParToken); Scanner.skip(leftCurlToken); ws.body = StatmList.parse(); Scanner.skip(rightCurlToken); Log.leaveParser("</while-statm>"); return ws;

logi Alle klasser som utvider SyntaxUnit, må redefinere den virtuelle metoden printtree: @Override void printtree() { Log.wTree("while ("); test.printtree(); Log.wTreeLn(") {"); Log.indentTree(); body.printtree(); Log.outdentTree(); Log.wTreeLn("");

logi I Log-modulen finnes noen nyttige metoder: public static void wtree(string s) { if (curtreeline.length() == 0) { for (int i = 1; i <= treelevel; ++i) curtreeline += " "; curtreeline += s; public static void wtreeln() { writelogline("tree: " + curtreeline); curtreeline = ""; public static void wtreeln(string s) { wtree(s); wtreeln(); public static void indenttree() { //-- Must be changed in part 1: public static void outdenttree() { //-- Must be changed in part 1:

Forstå hva du skal gjøre! Råd nr 1: Forstå problemet! Forstå hva du skal gjøre før du begynner å programmere. NB! Skriv noen korte kodesnutter i AlboC. Tegn syntakstrærne deres. Studér eksemplet med språket E i øvelsesoppgavene. På dette stadium kan man samarbeide så mye man ønsker!

Start enkelt! Råd nr 2: Start med noe enkelt! Ingen bør forvente at de kan skrive all koden og så bare virker den. Start med et enkelt programmeringsspråk program var decl var decl int name ; og få det til å virke først. Utvid etter hvert. Sjekk hver utvidelse før du går videre.

Bruk aktiv feilsøking! Råd nr 3: Ikke sitt og stirr på koden! Når programmet ikke virker: 1 Se på siste versjon av programkoden. 2 Siden du arbeider i små steg er feilen sannsynligvis i de siste linjene du endret. 3 Hvis du ikke har funnet feilen i løpet av fem minutter, gå over til aktiv feilsøking.

Husk testutskriftene! Råd nr 4: Les testutskriftene! P-utskriftene forteller hvilke parse-metoder som kalles. Anta at vi har programmet int pot2 (int x) { int p2; p2 = 1; : Programmet gir en feilmelding i linje 1: Expected a leftcurltoken but found a leftpartoken! Hva er galt?

Husk testutskriftene! Svaret kan vi finne i P-utskriften: 1: int pot2 (int x) <program> <type> </type> <func decl> 2: { 3: int p2; p2 = 1; <func body> Utskriften skulle ha startet 1: int pot2 (int x) <program> <type> </type> <func decl> <type> </type> <param decl> 2: { 3: int p2; p2 = 1; </param decl> <func body>

Husk testutskriftene! I-utskriften viser en utskrift av det genererte treet. Anta at vi har det samme testprogrammet int pot2 (int x) { int p2; p2 = 1; : Hvis I-utskriften er int pot2 (int x) { p2 = 1; : så vet vi at lokale deklarasjoner i funksjoner ikke settes opp riktig (eller at det er feil i I-utskriften ).

Lag egne testutskrifter Råd nr 5: Lag egne testutskrifter Her er litt (muligens feilaktig) kode fra StatmList.parse: class StatmList extends SyntaxUnit { Statement firststatement = null; static StatmList parse() { Log.enterParser("<statm list>"); StatmList sl = new StatmList(); Statement laststatm = null; while (Scanner.curToken!= rightcurltoken) { Statement s = Statement.parse(); if (laststatm!= null) sl.firststatm = laststatm = s; else laststatm.nextstatm = laststatm = s; Log.leaveParser("</statement>"); return sl;

Lag egne testutskrifter Anta at vi får melding om null-peker i linjen med laststatm.nextstatm = laststatm = sx;. Slikt skal ikke skje. Mitt råd er å legge inn noe à la while (...) { System.out.println("StatmList.parse: " + "laststatm er " + (laststatm==null? "null" : "ikke null"));

Lag egne testutskrifter Slik skal koden være: class StatmList extends SyntaxUnit { Statement firststatement = null; static StatmList parse() { Log.enterParser("<statm list>"); StatmList sl = new StatmList(); Statement laststatm = null; while (Scanner.curToken!= rightcurltoken) { Statement s = Statement.parse(); if (laststatm == null) sl.firststatm = laststatm = s; else laststatm.nextstatm = laststatm = s; Log.leaveParser("</statement>"); return sl;

Behold testutskriftene! Råd nr 6: 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å: Det mest avanserte er å bruke opsjoner på kommandolinjen: java Alboc -debugsl.a testprog.alboc Det fungerer også godt å benytte statusvariable: static boolean debugsl_a = true; : if (debugss_a) { System.out.println("...");

Stol ikke på det du har skrevet! Råd nr 7: 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.

Stol ikke på det du har skrevet! class WhileStatm extends Statement { Expression test; StatmList body; static WhileStatm parse() { Log.enterParser("<while-statm>"); WhileStatm ws = new WhileStatm(); assert Scanner.curToken==whileToken: "While-setning starter ikke med while!"; Scanner.skip(whileToken); Scanner.skip(leftParToken); test = Expression.parse(); Scanner.skip(rightParToken); Scanner.skip(leftCurlToken); body = StatmList.parse(); Scanner.skip(rightCurlToken); Log.leaveParser("</while-statm>"); return ws;

Stol ikke på det du har skrevet! NB! Husk å kjøre med java -ea -jar Alboc.jar... for å slå på mekanismen.

Synkronisér med symbolgeneratoren! Råd nr 8: Sjekk spesielt på Scanner.readNext()! Det er lett å kalle readnext() for ofte eller for sjelden. Her er reglene som parse-metodene må følge: 1 Når man kaller parse, skal første symbol være lest inn. 2 Når man returnerer fra en parse, skal første symbol etter konstruksjonen være lest. Vær spesielt oppmerksom der du har forgreninger og løkker i jernbanediagrammet.

Ta sikkerhetskopier! Råd nr 9: 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 1 Ta en kopi av Java-filen hver gang du starter med å legge inn ny kode. 2 Ta uansett en kopi hver dag (om noe som helst er endret).

Hele folket i arbeid! Råd nr 10: Fordel arbeidet! Dere er to om jobben. Selv om begge må kjenne til hovedstrukturen, kan man fordele programmeringen. Forslag 1 Én tar deklarasjoner. 2 Én tar setninger og uttrykk. Men... Snakk ofte sammen. Planlegg hvordan dere bruker filene så ikke den ene ødelegger det den andre har gjort.

Søk profesjonell hjelp! Råd nr 11: Bruk hjelpemidlene Spør gruppelærerne! De er tilgjengelige under gruppetimene og svarer på e-post til andre tider. Orakel De siste ukene før oblig-fristene vil gruppelærerne bare jobbe med å svare på spørsmål. Les kompendiet Stoffet er forklart med flere detaljer enn det er mulig på forelesningene.

Start nå! Råd nr 12: Start nå! Det tar typisk 20 100 timer å programmere Del-1. Det er vanskelig å anslå dette nøyaktig på forhånd. Påtrengende spørsmål Det er 25 arbeidsdager til 31. oktober. Hvor mange timer per dag blir det?