Dagens tema: Nødvendig Java. De ulike modulene Prosjektet. Strukturen Pakker i Java Avbrudd («exceptions») Enum-klasser i Java Hvilket objekt er jeg?

Like dokumenter
Dagens tema: Nødvendig Java. De ulike modulene i prosjektet vårt Prosjektet

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

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

Dagens tema: Prosjektet. Hva er en god feilmelding? Melding med mening. Ubrukelig. Hvor på linjen? Noe bedre. Enda bedre

Prosjektet. Dagens tema: Moduler i prosjektet error log chargenerator scanner. Enum klasser i Java. Programmeringsverktøy Emacs Eclipse

Dagens tema: Kompilatorens struktur. De ulike modulene Prosjektet. Oppbyggingen Pakker i Java Enum-klasser i Java

INF2100. Oppgaver 26. september til 1. oktober 2007

INF2100. Oppgaver uke 40 og

IN2030. Oppgave 1. Løsningsforslag. Uke (Disse filene finnes også i mappen ~inf2100/e/e2/.)

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.

Dagens tema: Kompilatorens struktur. De ulike modulene Prosjektet. Oppbyggingen Pakker i Java Enum-klasser i Java

Dagens tema: Hva skal gjøres? Hva gjør en kompilator? Hva gjør en kompilator?

Dagens tema: Sjekking

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

INF1010 våren 2019 Onsdag 30. januar. Mer om unntak i Java (med litt repetisjon av I/O først)

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

Dagens tema: 12 gode råd for en kompilatorskriver

Jentetreff INF1000 Debugging i Java

Dagens tema: Sjekking (obligatorisk oppgave 3)

Hvordan skrive Flok og Flass kode? I mange tilfelle er det svært enkelt:

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

Kapittel 8: Programutvikling

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

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

Forelesning inf Java 4

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

IN Notat om I/O i Java

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

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

Programmeringsspråket C

INF1000 undervisningen INF 1000 høsten 2011 Uke september

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

2 Parser. 1 Skanner. 4 Kodegenerator. 3 Sjekker. Oversikt Datamaskinhistorie x86 Kodegenerering Setninger Uttrykk.

Kompilering Syntakstreet Syntaksanalyse Programmering Statiske Programmering

Fra Python til Java, del 2

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; }

TOD063 Datastrukturer og algoritmer

Leksjon 7. Filer og unntak

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

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

Programmeringsspråket C

Forkurs INF1010. Dag 1. Andreas Færøvig Olsen Tuva Kristine Thoresen

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

Løsningsforslag Test 2

Programmeringsspråket C

HØGSKOLEN I SØR-TRØNDELAG

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

INF1000-SIKT - Notat om I/O i Java

INF Notat om I/O i Java

Litt om pakker og mest om data inn og ut

I dag skal vi se på. INF 1000 (uke 2) Variabler, tilordninger og uttrykk. Gruppene starter denne uken! Klart for første oblig

Dagens tema: Maskinkode. Litt datamaskinhistorie Hva er maskin- og assemblerkode? x86-prosessoren Programkode og variabler

Videregående programmering 6

Forelesning inf Java 5

Forelesning inf Java 5

Eksamen i emnet INF100 Grunnkurs i programmering (Programmering I) og i emnet INF100-F Objektorientert programmering i Java I Løsningsforslag

UNIVERSITETET I OSLO

Kort om meg. INF1000 Uke 2. Oversikt. Repetisjon - Introduksjon

Forkurs INF1010. Dag 3. Andreas Færøvig Olsen Eivind Storm Aarnæs

Sortering med tråder - Quicksort

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

UNIVERSITETET I OSLO

Dagens tema Kapittel 8: Objekter og klasser

Kapittel 11: Unntakshåndtering. Java som første programmeringsspråk

INF Løsning på seminaropppgaver til uke 8

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

Transkript:

Dagens tema: Nødvendig Java Strukturen Pakker i Java Avbrudd («exceptions») Enum-klasser i Java Hvilket objekt er jeg? De ulike modulene Prosjektet Hva skal del 1 gjøre? Feilmeldinger Testutskrifter Siste råd

Oppdeling av programmer Prosjektet Hvordan skriver man et større program som en kompilator? Struktur Det bør deles opp i passe store deler. Hvordan bør et program deles opp? Ingen faste regler men Hvilken oppdeling virker naturlig? Hvilken oppdeling gir få aksesser mellom modulene? Hvordan flyter data?

Oppdeling av programmer f.pas f.s 1 Skanner :Token :Token :Token 2 Parser <program> <block> <var decl> <statm list> 4 Kodegenerator 3 Sjekker

Moduler Noen programmeringsspråk har mekanismer for store moduler men langt fra alle. Java har package. Begrunnelse Anta at vi skal utvikle et CAD-system. Et firma i India har laget en god GUI-modul. Men, begge har en klasse Bar. Moduler kan løse dette problemet.

Javas pakker Alle filene som skal inngå i en Java-pakke starter med «package navn». Pakkenavn bør bestå av opphavsstedets internettadresse (baklengs) og et lokalt navn. Vårt kompilatorprosjekt heter no.uio.ifi.pascal2100

Javas pakker Eksempel package P1; P1/A.java public class A { public static int x = 1; (Under kompileringen må klassen ligge i et fil-tre som tilsvarer leddene i pakkenavnet; våre filer ligger i no/uio/ifi/pascal2100/scanner/scanner.java og tilsvarende.)

Javas pakker Vi kan hente klasser fra alle pakker så lenge de finnes i CLASSPATH: B.java class B { public static void main (String arg[]) { System.out.println("P1.A.x = " + P1.A.x); P1/A.java package P1; public class A { public static int x = 1; Ifis standard CLASSPATH er: $ printenv CLASSPATH /usr/share/java:/usr/share/java/postgresql-jdbc.jar:.

Javas pakker Beskyttelse Klasser kan beskyttes: er usynlig utenfor pakken. public kan brukes fra andre pakker. For klasseelementer (dvs metoder og variabler) gjelder: private er bare tilgjengelige i klassen. protected er for klassen og subklasser. er bare for bruk innen pakken. public kan benyttes overalt.

Javas pakker For å unngå å skrive mange lange navn som no.uio.ifi.pascal2100.main.main.version, kan vi importere klasser fra pakker: import P1.A; B.java class B { public static void main (String arg[]) { System.out.println("P1.A.x = " + A.x); P1/A.java package P1; public class A { public static int x = 1;

Javas pakker Vi kan også importere alle klassene fra en pakke: import P1.*; B.java class B { public static void main (String arg[]) { System.out.println("P1.A.x = " + A.x); P1/A.java package P1; public class A { public static int x = 1;

Javas pakker En siste mulighet er å importere statiske deklarasjoner i en klasse: B.java import static P1.A.*; class B { public static void main (String arg[]) { System.out.println("P1.A.x = " + x); P1/A.java package P1; public class A { public static int x = 1;

Javas pakker Hva kan en pakke inneholde? En Java-pakke kan bare inneholde klasser. Men det er også nyttig noen ganger å ha data og metoder som er «globale» for prosjektet vårt. Disse legger vi i Main-objektet som public static.

Enum-klasser Enum-klasser Noen ganger har man diskrete data som kun kan ha et begrenset antall fast definerte verdier: Kortfarge Kløver, ruter, hjerter, spar Tippetegn Hjemmeseier, uavgjort, borteseier Ukedag Mandag, tirsdag, onsdag, torsdag, fredag, lørdag, søndag Å representere disse med heltall er en halvgod løsning.

Et eksempel Java tilbyr enum-klasser: Tippetegn.java enum Tippetegn { Hjemmeseier, Uavgjort, Borteseier; //... Dette er syntaktisk sukker for Tippetegn.java class Tippetegn extends java.lang.enum { public static final Tippetegn Hjemmeseier = new Tippetegn(), Uavgjort = new Tippetegn(), Borteseier = new Tippetegn(); //...

Bruk av enum-klasser Slik brukes denne klassen: Tipping.java class Tipping { public static void main (String arg[]) { Tippetegn rekke[] = new Tippetegn[12+1]; rekke[1] = Tippetegn.Hjemmeseier; rekke[2] = Tippetegn.Borteseier; rekke[3] = Tippetegn.Borteseier; for (int i = 1; i <= 3; ++i) System.out.print(rekke[i]+" "); System.out.println(); > java Tipping Hjemmeseier Borteseier Borteseier

Bruk av enum-klasser Hva kan vi gjøre med enum-klasser? Tilordne verdier («rekke[i] = Tippetegn.Uavgjort») Sjekke på likhet og ulikhet («rekke[1] == Tippetegn.Borteseier») Skrive ut objektet («System.out.println(rekke[1])» som er det samme som «System.out.println(rekke[1].toString())»)

Når det går galt Avbrudd Noen ganger trenger vi å avbryte den normale utførelsen fordi en feil eller noe annet unormalt har skjedd. Hvis dette involverer mange metodekall, er avbrudd («exceptions») nyttig. Sikre avbrudd benyttes der vi vil være sikre på at feilen tas hånd om, f eks FileNotFoundException. Kjøreavbrudd krever ingen slik sikring.

Når det går galt void f(...) { : throw new RuntimeException("Melding"); : void g(...) { try { : f(...) : catch (RuntimeException e) { // Hvis feil: : finally { // Alltid: :

Og til sist en generelt nyttig metode En nyttig metode Til sist et lite tips: Når man skriver oo-programmer, er det nyttig om alle objektene kan identifisere seg selv. Nøyaktig hvilken informasjon de skal gi, avhenger av programmet. I dette prosjektet skal vi la alle våre klasser inneholde en metode identify som gir nok informasjon til å identifisere objektene. Som eksempel: Scanner: public String identify() { return "Scanner reading " + sourcefilename;

Våre pakker no.uio.ifi.pascal2100.main Main LogFile CodeFile PascalError no.uio.ifi.pascal2100.scanner no.uio.ifi.pascal2100.parser Token TokenKind PascalSyntax PascalDecl Scanner Program...

Modulen «main» Hovedprogrammet Main.java package no.uio.ifi.pascal2100.main; import no.uio.ifi.pascal2100.parser.*; import no.uio.ifi.pascal2100.scanner.*; import static no.uio.ifi.pascal2100.scanner.tokenkind.*; import java.io.*; public class Main { public static final String version = "2015-08-23"; public static Library library; public static LogFile log = new LogFile(); private static String sourcefilename, basefilename; private static boolean testparser = false, testscanner = false;

Modulen «main» public static void main(string arg[]) { System.out.println("This is the Ifi Pascal2100 compiler (" + version + ")"); int exitstatus = 0; try { readargs(arg); log.init(basefilename + ".log"); Scanner s = new Scanner(sourceFileName); if (testscanner) dotestscanner(s); else if (testparser) dotestparser(s); else dorunrealcompiler(s); catch (PascalError e) { System.out.println(); System.err.println(e.getMessage()); exitstatus = 1; finally { log.finish(); System.exit(exitStatus);

Modulen «main» private static void dotestscanner(scanner s) { while (s.nexttoken.kind!= eoftoken) s.readnexttoken(); private static void dotestparser(scanner s) { Program prog = Program.parse(s); if (s.curtoken.kind!= eoftoken) error("scanner error: Garbage after the program!"); prog.prettyprint(); private static void dorunrealcompiler(scanner s) { System.out.print("Parsing..."); Program prog = Program.parse(s);.

Modulen «scanner» Skanner En kompilator kan lese og tolke en program tegn for tegn, men det er mye lettere om det kan gjøres symbol for symbol. Dette ordner en skanner. En skanner gjør følgende: Leser programkoden fra en fil Fjerner alle kommentarer Deler resten av teksten opp i symboler («tokens»)

Modulen «scanner» /* Et minimalt Pascal-program */ program Mini; begin write( x ); end. har disse symbolene: program name: Mini ; begin name: write ( x ) ; end.

Prosjektet I vår skanner Vår skanner kan levere token som definert i klassen Token: package no.uio.ifi.pascal2100.scanner; import static no.uio.ifi.pascal2100.scanner.tokenkind.*; public class Token { public TokenKind kind; public String id, strval; public int intval, linenum;

Prosjektet TokenKind er definert i en enum-klasse: public enum TokenKind { nametoken("name"), intvaltoken("number"), stringvaltoken("text string"), addtoken("+"), assigntoken(":="), colontoken(":"), commatoken(","),. eoftoken("e-o-f"); private String image; TokenKind(String im) { image = im; public String identify() { return image + " token";

Prosjektet Klassen Scanner public class Scanner { public Token curtoken = null, nexttoken = null; private LineNumberReader sourcefile = null; private String sourcefilename, sourceline = ""; private int sourcepos = 0; public Scanner(String filename) { sourcefilename = filename; try { sourcefile = new LineNumberReader(new FileReader(fileName)); catch (FileNotFoundException e) { Main.error("Cannot read " + filename + "!"); readnexttoken(); readnexttoken(); public String identify() { return "Scanner reading " + sourcefilename;

Prosjektet Symbolene leses inn i curtoken og nexttoken i metoden readnext: public void readnexttoken() { curtoken = nexttoken; nexttoken = null;. Main.log.noteToken(nextToken); private void readnextline() { if (sourcefile!= null) { try { sourceline = sourcefile.readline(); if (sourceline == null) { sourcefile.close(); sourcefile = null; sourceline = ""; else { sourceline += " "; sourcepos = 0; catch (IOException e) { Main.error("Scanner error: unspecified I/O error!"); if (sourcefile!= null) Main.log.noteSourceLine(getFileLineNum(), sourceline);

Hva når vi oppdager en feil? Hva er en god feilmelding? Ubrukelig ERROR: Syntax error detected! Noe bedre ERROR: Syntax error found in line 217. Enda litt bedre ERROR: Syntax error found in line 217: if (x == y+1)

Hva når vi oppdager en feil? Melding med mening Meldingen bør fortelle hva som er galt: ERROR in line 217: Illegal expression. if (x == y+1) Den beste meldingen Meldingen bør angi hvorledes kompilatoren «tenker»: ERROR in line 217: Expected a value but found =. if (x == y+1)

Hva når vi oppdager en feil? Feil Hva gjør man med feil? Før prøvde man å finne så mange feil som mulig. Vi skal stoppe med melding ved første feil.

Hva når vi oppdager en feil? Metoden Main.error public static void error(string message) { log.noteerror(message); throw new PascalError(message); PascalError.java public class PascalError extends RuntimeException { PascalError(String message) { super(message);

Hva når vi oppdager en feil? Noen ganger tabber vi oss ut! public void panic(string where) { error("panic! Programming error in " + where);

Selv den beste vil gjøre noen feil. Testutskrifter Alle vil gjøre feil under arbeidet med kompilatoren. For enklere å oppdage feilene når de skjer, skal vi bygge inn ulike testutskrifter som brukeren enkelt kan slå på: Opsjon Hva dumpes? Del logb Navnebindingen 3 logp Parseringen 2 logs Skanneren 1 logt Typesjekkingen 3 logy «Pretty-printing» 2

Klassen LogFile Modulen log Brukeren kan slå av og på logging. public class LogFile { boolean dologbinding = false, dologparser = false, dologprettyprint = false, dologscanner = false, dologtypechecks = false; public void notesourceline(int linenum, String line) { if (dologparser dologscanner) writelogline(string.format("%4d: %s",linenum,line)); public void notetoken(token tok) { if (dologscanner) writelogline("scanner: " + tok.identify());

Klassen LogFile $ ~inf2100/pascal2100 -testscanner mini.pas $ more mini.log 1: 2: /* Et minimalt Pascal-program */ 3: program Mini; Scanner: program token on line 3 Scanner: name token on line 3: mini Scanner: ; token on line 3 4: begin Scanner: begin token on line 4 5: write( x ); Scanner: name token on line 5: write Scanner: ( token on line 5 Scanner: text string token on line 5: x Scanner: ) token on line 5 Scanner: ; token on line 5 6: end. Scanner: end token on line 6 Scanner:. token on line 6 Scanner: e-o-f token

Klassen LogFile NB! Siden utskriften på forrige side kommer fra to kilder, vil flettingen av den kunne variere. Variasjoner i fletting er helt normalt og må forventes. Når hele programmet er lest, vil skanneren bare returnere eoftoken.

Del-1 f.pas f.s 1 Skanner :Token :Token :Token 2 Parser <program> <block> <var decl> <statm list> 4 Kodegenerator 3 Sjekker

Hva skal gjøres? Mål for del 1 1 Hent ned, pakk ut og kompiler prekoden. 2 Gjør nødvendige endringer slik at skanneren fungerer og at den skriver ut loggmeldinger som vist når vi kjører kompilatoren med opsjonen testscanner.

Siste råd? Siste innspill Skanneren er dum! Den lager symboler uten tanke på sammenhengen. Skanneren er grådig! Den lager så lange symboler som mulig; for eksempel:... ifa... blir til name: ifa En del av jobben er å skjønne basiskoden, resten er å programmere Scanner.readNextToken. Les kompendiet! Det er lov å endre basiskoden. Du kan bruke alt du vil fra Java-biblioteket. Gruppelærerne er der for å hjelpe dere. Begynn i tide!