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

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

Oversikt Kompilering Syntaksanalyse Java Feilsjekking Oppsummering

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

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

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

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

Dagens tema: Formålet. Kodegenerering NB! Introduksjon Modulen Code. Enkle variable Noen enkle setninger Uttrykk

Dagens tema: Formålet. Kodegenerering NB! Introduksjon Modulen Code. Enkle variable Noen enkle setninger Uttrykk

Dagens tema: Resten av det dere trenger til del 1

Dagens tema: Resten av det dere trenger til del 1

Dagens tema: Mer av det dere trenger til del 1

Oversikt Oversettelse Logging Implementasjon Oppsummering

INF2100. Oppgaver uke 40 og

Oversikt Kodegenerering Variabler Setninger Uttrykk While-setningen

INF2100. Oppgaver 9. oktober 2012 C 100 X 10

Dagens tema: 12 gode råd for en kompilatorskriver

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Velkommen til INF2100. Bakgrunnen for INF2100. Hva gjør en kompilator? Prosjektet. Jeg er Dag Langmyhr

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

Velkommen til INF2100

Velkommen til INF2100

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

INF2100. Oppgaver 23. og 24. september 2010

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

Velkommen til INF2100

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

Dagens tema: Sjekking

Dagens tema: Generelt om variable. Kodegenerering. Deklarasjon av array er. Versjonskontroll. Oppslag i array er

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

Velkommen til INF2100

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

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.

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

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

Programmeringsspråket C

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister Videre

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

IN våren 2019 Onsdag 16. januar

IN våren 2018 Tirsdag 16. januar

Del 3: Evaluere uttrykk

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

Jentetreff INF1000 Debugging i Java

INF våren 2017

INF1000: noen avsluttende ord

Velkommen til INF2100

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

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

Anatomien til en kompilator - I

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.

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Programmeringsspråket C

Semantisk Analyse del I

INF1000: Forelesning 7

Bakgrunnen for INF2100. Velkommen til INF2100. Prosjektet. Hva gjør en kompilator?

Dagens tema Kapittel 8: Objekter og klasser

Feilmeldinger, brukerinput og kontrollflyt

UNIVERSITETET I OSLO

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

Diverse eksamensgaver

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

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

UNIVERSITETET I OSLO

Dagens tema: Kodegenerering. Redigeringsverktøy. Versjonskontroll. Array-er Funksjoner og kall Hovedprogrammet Noen siste gode råd.

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

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

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

UNIVERSITETET I OSLO

Repetisjon. 1 binærtall. INF3110 Programmeringsspråk. Sist så vi ulike notasjoner for syntaks: Jernbanediagrammer. BNF-grammatikker.

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

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

UNIVERSITETET I OSLO

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

INF3110 Programmeringsspråk

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

INF1000: Forelesning 7. Konstruktører Static

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

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

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

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

Oversikt Deklarasjoner Typesjekk Programmering Datamaskinhistorie x86 Kodegenerering

UNIVERSITETET I OSLO

Velkommen til INF Kompilatorteknikk

GUI («Graphical User Interface») del 2

Programmeringsspråket C

Hovedstoffet i kap 4: 16. Februar Ifi, UiO

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

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

Klasser, objekter, pekere og UML. INF gruppe 13

Rekursjon. (Big Java kapittel 13) Fra Urban dictionary: recursion see recursion. IN1010 uke 8 våren Dag Langmyhr

INF1000 oppgaver til uke 38 (17 sep 23 sep)

Hva er syntaks? En overskrift i en norsk avis: Dagens tema Grundig repetisjon og utdyping:

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

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

156C. Algoritmer og maskinspråk. IT1101 Informatikk basisfag. Maskinspråk: det maskinen forstår. Assembler / assemblerspråk

Transkript:

Dagens tema Dagens tema Kildekode Hva er kompilering? Hva er kompilering? Hvordan foreta syntaksanalyse av et program? Hvordan programmere dette i Java? Hvordan oppdage feil? Anta at vi lager dette lille programmet doble.rusc (kalt kildekoden): int n; int main () { putchar(? ); n = getint()*2; putint(n); putchar(10); Maskinkode Maskinkode Dette programmet kan ikke kjøres direkte på noen datamaskin, men det finnes en Rask-kode (kalt maskinkoden) som gjør det samme: #! /local/bin/rask 1600000000000006 211000000000000 1600000000009990 0 0 0 331000000000004 303000000000005 211000000000063 1600000000009993 1600000000009992 203010000000000 201000000000002 601030000000001 301000000000003 111000000000003 1600000000009994 211000000000010 1600000000009993 103000000000005 131000000000004 1700000000000000 Det er ikke lett å lese slik kode det går bedre i assemblerkode: Code 0: 1600000000000000 CALL 0 0 0 # <Dummy main program> Code 1: 211000000000000 SET 11 0 0 # (0) Code 2: 1600000000009990 CALL 0 0 9990 # exit Code 3: RES 1 # int n Code 4: RES 1 # <return address> in main Code 5: RES 1 # <refuge for R3> in main Code 6: 331000000000004 STORE 31 0 4 # <save return address> Code 7: 303000000000005 STORE 3 0 5 # <save R3> Code 8: 211000000000063 SET 11 0 63 # R11 = 63 Code 9: 1600000000009993 CALL 0 0 9993 # putchar(...) Code 10: 1600000000009992 CALL 0 0 9992 # getint(...) Code 11: 203010000000000 SET 3 1 0 # <save operand> Code 12: 201000000000002 SET 1 0 2 # R1 = 2 Code 13: 601030000000001 MUL 1 3 1 # * Code 14: 301000000000003 STORE 1 0 3 # n = Code 15: 111000000000003 LOAD 11 0 3 # R11 = n Code 16: 1600000000009994 CALL 0 0 9994 # putint(...) Code 17: 211000000000010 SET 11 0 10 # R11 = 10 Code 18: 1600000000009993 CALL 0 0 9993 # putchar(...) Code 19: 103000000000005 LOAD 3 0 5 # <restore R3> Code 20: 131000000000004 LOAD 31 0 4 # <restore return address> Code 21: 1700000000000000 RET 0 0 0 # return (from main) ---> 0: 1600000000000006 6 # <address of main >

Kompilatoren Kompilatoren Del-0 Del-1 Del-2 En kompilator En kompilator leser RusC-koden og lager Rask-koden. f.rusc Char- Generator Rusc f.rask Scanner Syntax Code En slik kompilator skal dere lage. Error Log f.log Programtreet Et RusC-program De færreste programmeringsspråk kan oversettes linje for linje, men det ville vært mulig med RusC. Det enkleste er likevel å lagre programmet på intern form først. Det naturlige da er å lage et tre ved å bruke klasser, objekter og pekere. Her er OO-programmering ypperlig egnet. Et program består av en samling deklarasjoner og en samling setninger: program var decl func decl

Programmet doble.rusc representeres da av Siden vi skal representere treet som lister, ser det slik ut: ProgramUnit ProgramUnit DeclListUnit DeclListUnit IntDeclUnit FuncDeclUnit IntDeclUnit FuncDeclUnit var decl, func decl, int name [ number ] ; int name ( int name ) func body En IntDeclUnit må inneholde data om variabelens navn og om den er en array hvor mange elementer den har. En FuncDeclUnit må inneholde opplysninger om parametrene og innmaten.

func body { var decl statm list En FuncBodyUnit inneholder lokale int-deklarasjoner og setninger. Et eksempel int n; int main () { putchar(? ); n = getint()*2; putint(n); putchar(10); ProgramUnit Analyse av naturlige språk Syntaksanalyse DeclListUnit På skolen hadde vi grammatikkanalyse hvor vi fant subjekt og predikat: IntDeclUnit FuncDeclUnit Mannen ga Lise en ball. FuncBodyUnit StatmListUnit FuncStatmUnit AssignUnit FuncStatmUnit FuncStatmUnit

Analyse av naturlige språk Analyse av programmeringsspråk Syntaksanalyse På skolen hadde vi grammatikkanalyse hvor vi fant subjekt og predikat: (Det er ikke alltid like enkelt: Mannen ga Lise en ball. Heldigvis: Analyse av programmeringsspråk er enklere enn naturlige språk: Programmeringsspråk har en klarere definisjon. Programmeringsspråk er laget for å kunne analyseres rimelig enkelt. Fanger krabber så lenge de orker. ) Syntaksanalyse er på samme måte å finne hvilke språkelementer vi har og bygge syntakstreet. RusC-kompilatoren RusC-kompilatoren har i hvert fall disse klassene: [SyntaxUnit] DeclListUnit [DeclarationUnit] FuncDeclUnit [ExprElementUnit] ExpressionUnit ProgramUnit [StatementUnit] AssignmentUnit EmptyStatmUnit FuncCallStatementUnit IfUnit ReturnUnit WhileUnit StatmListUnit Syntaksdiagram Grammatikk Grammatikken (i form av jernbanediagrammene) er et ypperlig utgangspunkt for å analysere et program og bygge opp syntakstreet: while-statm while ( expression ) { statm-list (Klasser i parentes er abstrakte.)

Syntaksdiagram Analyse av et RusC-program Programmering i Java Utifra dette vet vi: Først kommer symbolet while. Så kommer en (. Så kommer en expression. Etter den kommer en ). Deretter kommer en {. I klammene kommer statm-list. Helt til sist kommer en. Utifra jernbanediagrammet kan vi lage en skisse for en metode som analyserer en while-setning i et RusC-program: public static WhileUnit parse() { Sjekk at vi har lest while Sjekk at vi har lest ( Analysér ExpressionUnit Sjekk at vi har lest ) Sjekk at vi har lest { Analysér StatmListUnit Sjekk at vi har lest Analyse av et RusC-program Analyse av et RusC-program Stort sett gjør vi to ting: Symboler (i rundinger) sjekkes. Meta-symboler (i firkanter) overlates til sine egne metoder for analysering. Stort sett gjør vi to ting: Symboler (i rundinger) sjekkes. Meta-symboler (i firkanter) overlates til sine egne metoder for analysering.... og dermed har problemet nærmest løst seg selv!

Fungerer dette for alle språk? Er det så enkelt? Veien er alltid gitt! Veien er alltid klar Mange programmeringsspråk (som RusC og Pascal men ikke Java, C og C++) er designet slik at denne teknikken kalt «recursive descent» alltid fungerer. Et analyseprogram for et LL(1)-språk er aldri i tvil om hvilken vei gjennom programmet som er den rette. Ved analyse av LL(2)-språk må man av og til se ett symbol fremover. Ved analyse av LL(3)-språk (som RusC) må man av og til se to symboler fremover. statement empty statm ; assignment ; function call ; if-statm while-statm return-statm ; Syntaksanalysatoren og skanneren Samarbeid med Scanner Hvordan skrive dette i Java? Plassering av metodene Hvordan sikrer vi at symbolstrømmen fra Scanner er i fase med vår parsering? Det beste er å vedta noen regler som alle 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. Husk at målet med analysen er tofoldig: Vi skal sjekke at programmet er riktig. Vi skal bygge opp syntakstreet.

Hvordan skrive dette i Java? static -spesifikasjonen Det er naturlig å koble analysemetoden til den klassen som skal inngå i syntakstreet. Hvert meta-symbol i diagrammet implementeres av en Java-klasse. Hver av disse klassene får en metode public static xxx parse () {... som kan analysere «seg selv». Dette er OO-programmering. Vanlige variable i klasser Vanlige variable oppstår når et objekt opprettes. Det kan derfor være vilkårlig mange av dem. static-variable Disse ligger i «selve klassen» så det vil alltid være nøyaktig én slik. static -spesifikasjonen static -spesifikasjonen Et eksempel class Item { private static int total = 0; public int id; public Item() { id = ++total; class RunItem { public static void main(string arg[]) { Item a = new Item(), b = new Item(); System.out.println("a.id = "+a.id); System.out.println("b.id = "+b.id); Vanlige metoder i klasser Vanlige metoder ligger logisk sett i det enkelte objektet. Når de refererer til variable, menes variable i samme objekt eller static-variable i klassen. static-metoder Disse ligger logisk sett i «selve klassen». De kan derfor kalles før noen objekter er opprettet men de kan bare referere til static-variable i samme klasse.

static -spesifikasjonen static -spesifikasjonen class BinTreeNode { private static BinTreeNode root = null; private BinTreeNode l_sub, r_sub; public int value; BinTreeNode(int v) { value = v; l_sub = r_sub = null; public static void insert(bintreenode p) { if (root == null) root = p; else root.insertnode(p); private void insertnode(bintreenode p) { if (value <= p.value) { if (l_sub == null) l_sub = p; else l_sub.insertnode(p); else { if (r_sub == null) r_sub = p; else r_sub.insertnode(p); class RunBinTree { public static void main(string arg[]) { BinTreeNode.insert(new BinTreeNode(17)); BinTreeNode.insert(new BinTreeNode(-4)); BinTreeNode.insert(new BinTreeNode(3)); Hvordan finner man programmeringsfeil? Parsering av While-setning Feilsjekking Sjekken på syntaksfeil er svært enkel: Hvordan finne feil? Hvis neste symbol ikke gir noen lovlig vei i diagrammet, er det en feil. while-statm while ( expression ) { statm-list

Parsering av While-setning class WhileUnit extends StatementUnit { ExpressionUnit test; StatmListUnit body; public static WhileUnit parse(decllistunit decls) { WhileUnit w = new WhileUnit(); Scanner.readNext(); Scanner.skip(Token.leftParToken); w.test = ExpressionUnit.parse(decls); Scanner.skip(Token.rightParToken); Scanner.skip(Token.leftCurlToken); w.body = StatmListUnit.parse(decls); Scanner.skip(Token.rightCurlToken); return w; Dagens tema Oppsummering Vi har vært gjennom Hva kompilering er Hvordan foreta en syntaksanalyse av et program Hvordan programmere dette objektorientert Hvordan oppdage feil og gi gode feilmeldinger.