Dagens tema: Sjekking

Like dokumenter
Dagens tema: Sjekking (obligatorisk oppgave 3)

Del 3: Evaluere uttrykk

Dagens tema: Mer av det dere trenger til del 1

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

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

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

Oversikt Deklarasjoner Typesjekk Programmering Datamaskinhistorie x86 Kodegenerering

Dagens tema: Resten av det dere trenger til del 1

Oversikt Kompilering Syntaksanalyse Java Feilsjekking Oppsummering

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

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

Oversikt Kodegenerering Variabler Setninger Uttrykk While-setningen

Dagens tema: Resten av det dere trenger til del 1

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

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

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

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

Diverse eksamensgaver

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

Anatomien til en kompilator - I

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

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

INF5110 Obligatorisk Oppgave 2 del 2. Andreas Svendsen SINTEF. 23. April Oversikt

Hjemmeeksamen 2 i INF3110/4110

Eivind Gard Lund. 24. Mars 2009 Foilene bygger på 2009 utgaven av Andreas Svendsen

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

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

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

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

Anatomien til en kompilator - I

INF2100. Oppgaver 23. og 24. september 2010

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

INF2100. Oppgaver 9. oktober 2012 C 100 X 10

Semantisk Analyse del I

UNIVERSITETET I OSLO

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

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

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

INF2100. Oppgaver uke 40 og

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

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

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

Datatyper og typesjekking

Obligatorisk Innlevering 2

Oversikt. Introduksjon Kildekode Kompilering Hello world Hello world med argumenter. 1 C programmering. 2 Funksjoner. 3 Datatyper. 4 Pekere og arrays

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

UNIVERSITETET I OSLO

Semantisk Analyse del III

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

Datatyper og typesjekking

Dagens tema: Mer av det dere trenger til del 1

Datatyper og typesjekking

Datatyper og typesjekking

Oppsummering. Kort gjennomgang av klasser etc ved å løse halvparten av eksamen Klasser. Datastrukturer. Interface Subklasser Klasseparametre

Oversikt. Praktisk. Litt om meg. Obligatorisk oppgave 1 - Kort om oppgaven og verktøyene. Fredrik Sørensen OMS-gruppen, IfI.

INF Oblig 2 semantikksjekk og kodegenerering

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

Oblig 2 - Simpila. INF Kompilatorteknikk. Våren Typesjekking, sjekking av bruk av navn og blokkstrtuktur i språk.

INF Seminaroppgaver til uke 3

Repitisjonskurs. Arv, Subklasser og Grensesnitt

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

Runtimesystemer - II. Funksjoner som parametere. Virtuelle metoder

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

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.

UNIVERSITETET I OSLO

Skal bindes opp til en deklarasjon av samme navn

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

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

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

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

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

Gjennomgang av eksamen H99

UNIVERSITETET I OSLO

Skal bindes opp til en deklarasjon av samme navn

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)

class Book { String title; } class Dictionary extends Book { int wordcount; } class CartoonAlbum extends Book { int stripcount; }

Dagens tema: Mer av det dere trenger til del 2

INF1010 våren 2008 Uke 4, 22. januar Arv og subklasser

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

En kompilator for Pascal. Kompendium for INF2100

Programmering Høst 2017

Arv. Book book1 = new Book(); book1. title = "Sofies verden" class Book { String title; } class Dictiona ry extends Book {

LO191D/LC191D Videregående programmering

Løsnings forslag i java In115, Våren 1998

INF5110. Oblig 2 presentasjon

Oppgave 1. Oppgave 2. Oppgave 3. Prøveeksamen i INF1000. Ole Christian og Arne. 23. november 2004

Oversikt. INF5110 Obligatorisk Oppgave 1. Andreas Svendsen SINTEF

2 Om statiske variable/konstanter og statiske metoder.

Løsningsforslag til hjemmeeksamen 2 i INF3110/4110

Velkommen til INF2100

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

Prøveeksamen i INF1000. Ole Christian og Arne. 23. november 2004

Forelesning inf Java 4

BOKMÅL Side 1 av 5. KONTERINGSEKSAMEN I FAG TDT4102 Prosedyre og objektorientert programmering. Onsdag 6. august 2008 Kl

Oversikt Deklarasjoner Typesjekk Datamaskinhistorie x86 Kodegenerering

IN1010 våren januar. Objektorientering i Java

UNIVERSITETET I OSLO

Transkript:

Dagens tema Dagens tema: Sjekking Navnebinding (obligatorisk oppgave 3) Biblioteket Logging Riktig bruk av navn (frivillig) Typesjekking (frivillig)

Hele prosjektet Strukturen til kompilatoren vår f.pas f.s 1 Skanner :Token :Token :Token 2 Parser <program> <var decl> 4 Kodegenerator 3 Sjekker

Hva skal gjøres? Navnebinding program ; var : ; procedure (V: ); type = ; Gitt følgende program: Oppgaven er: lle navneforekomster skal bindes til sin deklarasjon. function F (V: ): ; := 2*V; F := end; { F } := + F(V) end; { } := 1; (10); write( =,, eol) end.

Syntakstreet program ; var : ; procedure (V: ); type = ; function F (V: ): ; := 2*V; F := end; { F } <program> := + F(V) end; { } := 1; (10); write( =,, eol) end. <var decl part> <proc decl> <var decl> <param decl list> <proc call> <proc call> <type> <param decl> <type decl part> <func decl> <variable> <type name> <type name> <type decl> <param decl list> <type name> <simple expr> <simple expr> <simple expr> <simple expr> <simple expr> <type> <param decl> <variable> <term> <term> <term> <term> <term> <type name> <type> <simple expr> <number literal> <number literal> <string literal> <variable> <variable> <type name> <variable> <variable> <term> <term opr> <term> <simple expr> <simple expr> <variable> <func call> <term> <term> <number literal> <factor opr> <variable> <variable> <simple expr> <term> <variable>

Syntakstreet La oss forenkle syntakstreet: program ; var : ; procedure (V: ); type = ; function F (V: ): ; := 2*V; F := end; { F } := + F(V) end; { } := 1; (10); write( =,, eol) end. Prog library Type boolean Type char Const eol Type integer Proc write Var Proc Enum false Enum true Param V write Type Func F 1 10 = eol Param V F F 2 V V

Hvilke noder har vi? Grønne noder er deklarasjoner. program ; var : ; procedure (V: ); type = ; function F (V: ): ; := 2*V; F := end; { F } := + F(V) end; { } := 1; (10); write( =,, eol) end. Prog library Type boolean Type char Const eol Type integer Proc write Var Proc Enum false Enum true Param V write Type Func F 1 10 = eol Param V F F 2 V V

Hvilke noder har vi? Blå noder er navneforekomster. program ; var : ; procedure (V: ); type = ; function F (V: ): ; := 2*V; F := end; { F } := + F(V) end; { } := 1; (10); write( =,, eol) end. Prog Library Type boolean Type char Const eol Type integer Proc write Var Proc Enum false Enum true Param V write Type Func F 1 10 = eol Param V F F 2 V V

Navnebindingen En del av dem skal bindes slik: program ; var : ; procedure (V: ); type = ; function F (V: ): ; := 2*V; F := end; { F } := + F(V) end; { } := 1; (10); write( =,, eol) end. Prog Library Type boolean Type char Const eol Type integer Proc write Var Proc Enum false Enum true Param V write Type Func F 1 10 = eol Param V F F 2 V V

Navnebindingen De andre skal bindes slik: program ; var : ; procedure (V: ); type = ; function F (V: ): ; := 2*V; F := end; { F } := + F(V) end; { } := 1; (10); write( =,, eol) end. Prog Library Type boolean Type char Const eol Type integer Proc write Var Proc Enum false Enum true Param V write Type Func F 1 10 = eol Param V F F 2 V V

Hvordan gjør vi det? Hvordan kan foreta navnebindingen? lle deklarasjonene er i en block : konstanter (const pi = 3;) typer (type decimal = 0..9;) enum-konstanter (type farge = (R, G, B);) variabler (var teller: 1..2;) funksjoner (function f: char;...) prosedyrer (procedure p;...) parametre (om block i funksjon eller prosedyre)

Hvordan gjør vi det? Et forslag La klassen Block inneholde en oversikt over alle dens deklarasjoner, for eksempel i form av en HashMap<String,PascalDecl>. En slik struktur ar en ekstra fordel: Det er enkelt å sjekke om noen navn er deklarert flere ganger i samme blokk. Dette skal i så fall gi en feilmelding.

Hvordan gjør vi det? Sjekkingen For å sjekke hele programmet, må vi skrive en rekursiv metode void check(block curscope, Library lib) som traverserer det. (Parametrene kommer vi tilbake til senere.)

Hvordan gjør vi det? Deler av Block kan se slik ut: public class Block extends PascalSyntax { ConstDeclPart constdeclpart = null; : HashMap<String,PascalDecl> decls = new HashMap<String,PascalDecl>(); void adddecl(string id, PascalDecl d) { if (decls.containskey(id)) d.error(id + " declared twice in same block!"); decls.put(id, d); } @Override void check(block curscope, Library lib) { if (constdeclpart!= null) { constdeclpart.check(this, lib); for (ConstDecl cd: constdeclpart.constants) { adddecl(cd.name, cd); } } :

Leting i lokalt skop Leting etter navn 1 Det enkleste først: nta at navnet finnes i den lokale blokken: Da sender vi med en peker til den som parameter til check. Eksempel class ProcCallStatm extends Statement { String procname; rraylist<expression> actparams = new rraylist<expression>(); ProcDecl procref; @Override void check(block curscope, Library lib) { PascalDecl d = curscope.finddecl(procname,this); : procref = (ProcDecl)d; :

Leting i ytre skop 2 Hvis deklarasjonen ikke er lokal, kan vi finne den ved å lete i ytre skop. Derfor bør Block inneholde en peker Block outerscope som peker på blokken utenfor. Den kan initieres av check.

Leting i ytre skop program ; var : ; procedure (V: ); type = ; function F (V: ): ; := 2*V; F := end; { F } := + F(V) end; { } := 1; (10); write( =,, eol) end. Prog Library Type boolean Type char Const eol Type integer Proc write Var Proc Enum false Enum true Param V write Type Func F 1 10 = eol Param V F F 2 V V

Leting i ytre skop Klassen Block kan da ha en metode finddecl: PascalDecl finddecl(string id, PascalSyntax where) { PascalDecl d = decls.get(id); if (d!= null) { Main.log.noteBinding(id, where, d); return d; } if (outerscope!= null) return outerscope.finddecl(id,where); } where.error("name " + id + " is unknown!"); return null; // Required by the Java compiler.

Biblioteket Biblioteket Noen navn som integer og write er predefinert. Hvordan bør vi håndtere dem? Løsning Lag et «kunstig» Block-objekt med disse predefinerte deklarasjonene og legg det ytterst. Da vil de bli funnet om ikke brukeren har deklarert noe med samme navn. Hint Lag en subklasse Library av Block for dette formålet.

Biblioteket program ; var : ; procedure (V: ); type = ; function F (V: ): ; := 2*V; F := end; { F } := + F(V) end; { } := 1; (10); write( =,, eol) end. Prog Library Type boolean Type char Const eol Type integer Proc write Var Proc Enum false Enum true Param V write Type Func F 1 10 = eol Param V F F 2 V V

Sjekk hva loggen sier Kontroll For å sjekke navnebindingen brukes opsjonen -logb. Kallet på Main.log.noteBinding i Block.findDecl gir oss den informasjonen vi trenger. 1 program ; 2 var : ; 3 4 procedure (V: ); 5 type = ; 6 7 function F (V: ): ; 8 9 := 2*V; 0 F := 1 end; { F } 2 3 4 := + F(V) 5 end; { } 6 7 8 := 1; 9 (10); 0 write( =,, eol) 1 end. Binding on line 2: integer was declared in <type decl> in the libra Binding on line 4: integer was declared in <type decl> in the libra Binding on line 5: integer was declared in <type decl> in the libra Binding on line 7: a was declared in <type decl> on line 5 Binding on line 7: a was declared in <type decl> on line 5 Binding on line 9: x was declared in <var decl> on line 2 Binding on line 9: v was declared in <param decl> on line 7 Binding on line 10: f was declared in <func decl> on line 7 Binding on line 10: x was declared in <var decl> on line 2 Binding on line 14: x was declared in <var decl> on line 2 Binding on line 14: x was declared in <var decl> on line 2 Binding on line 14: f was declared in <func decl> on line 7 Binding on line 14: v was declared in <param decl> on line 4 Binding on line 18: x was declared in <var decl> on line 2 Binding on line 19: a was declared in <proc decl> on line 4 Binding on line 20: write was declared in <proc decl> in the librar Binding on line 20: x was declared in <var decl> on line 2 Binding on line 20: eol was declared in <const decl> in the library

Brukes navnet riktig? Navnebruk (frivillig) Etter å ha funnet hvor et navn er deklarert, må en kompilator sjekke at det brukes rett, for eksempel at vi ikke har const C = 5; procedure P; C := 10 + P; end; {P}

Brukes navnet riktig? Hvordan sjekke dette? Det er mange måter å sjekke navnebruken på; jeg skal vise at oo-programmering kan gjøre dette enkelt og oversiktlig. 1 Deklarer en virtuell funksjon i klassen PascalDecl: abstract void checkwhetherssignable(pascalsyntax where); 2 I alle deklarasjoner som kan stå til venstre i en tilordning (f eks VarDecl og FuncDecl), implementeres denne som en tom metode: @Override void checkwhetherssignable(pascalsyntax where) {} 3 I alle andre deklarasjoner lager vi i stedet en @Override void checkwhetherssignable(pascalsyntax where) { where.error("you cannot assign to a constant."); }

Brukes navnet riktig? Ved alle navneforekomster der det skal skje en tilordning (f eks i ssignstatm), kan vi bruke denne metoden: class ssignstatm extends Statement { Variable var; Expression expr; @Override void check(block curscope, Library lib) { var.check(curscope, lib); var.vardecl.checkwhetherssignable(this); expr.check(curscope, lib); :

Hvor mange trenger vi? Hvilke checkwhether-metoder trenger vi? Selv har jeg brukt disse: checkwhetherssignable for tilordning (i ssignstatm og funksjons- og prosedyrekall) checkwhetherfunction for funksjonskall checkwhetherprocedure for prosedyrekall checkwhethervalue for uttrykk

Hvordan sjekke riktig bruk av typer? Typesjekking (frivillig) Det er også viktig å sjekke at programmereren overholder typereglene og ikke skriver slikt som type Index = 1.. z ; var : ; B: Char; C: array [Index] of Boolean; if then B := C + 1; :

Hvordan gjøre det i praksis? Hvordan kan dette implementeres? Det er også her mange mulige måter å ordne seg på; jeg vil vise én som minner om checkwhether: 1 I klassen Type deklareres en virtuell metode abstract void checktype(type tx, PascalSyntax where, String message); Parametrene er: tx er typen som «vår» type skal sammenlignes med where angir hvor i programmet typen forekommer message inneholder meldingen som skal gis om det er typefeil

Hvordan gjøre det i praksis? 2 Hver subklasse til Type må da implementere en fornuftig checktype. I EnumType kan den se slik ut: class EnumType extends Type { rraylist<enumliteral> values = new rraylist<enumliteral>(); @Override void checktype(type tx, PascalSyntax where, String message) { if (tx == this) return; // OK else if (tx instanceof TypeName) checktype(((typename)tx).namedref, where, message); else where.error(message); }

Hvordan gjøre det i praksis? Nå har vi testapparatet vi trenger. I WhileStatm kan vi for eksempel skrive class WhileStatm extends Statement { Expression expr; Statement body; @Override void check(block curscope, Library lib) { expr.check(curscope, lib); Main.log.noteTypeCheck("while", expr.type, this); expr.type.checktype(lib.booleantype, this, "While-test is not Boolean."); body.check(curscope, lib); } (Her ser vi at parameteren lib til check-metoden er nyttig.)