Kompilering Syntakstreet Syntaksanalyse Programmering Statiske Programmering



Like dokumenter
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?

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

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

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

Dagens tema: Sjekking

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: Mer av det dere trenger til del 1

Dagens tema: Sjekking (obligatorisk oppgave 3)

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

Del 3: Evaluere uttrykk

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

Oversikt Kodegenerering Variabler Setninger Uttrykk While-setningen

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

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

Dagens tema: Mer av det dere trenger til del 2

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

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

Dagens tema: Mer av det dere trenger til del 1

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Dagens tema: Resten av det dere trenger til del 1

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

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

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

Dagens tema: Resten av det dere trenger til del 1

INF2100. Oppgaver uke 40 og

Velkommen til INF2100

Dagens tema: 12 gode råd for en kompilatorskriver

INF2100. Oppgaver 9. oktober 2012 C 100 X 10

Oversikt Deklarasjoner Typesjekk Programmering Datamaskinhistorie x86 Kodegenerering

INF2100. Oppgaver 23. og 24. september 2010

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

Oversikt. INF5110 Obligatorisk Oppgave 1. Andreas Svendsen SINTEF

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

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

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

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

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

En oppsummering (og litt som står igjen)

TOD063 Datastrukturer og algoritmer

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

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

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

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

Velkommen til INF2100

Oppbygningen av en datamaskin Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

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

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

Obligatorisk Oppgave 1

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

Velkommen til INF2100

Obligatorisk Oppgave 1

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

INF2100. Oppgaver 26. september til 1. oktober 2007

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

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

Diverse eksamensgaver

Obligatorisk oppgave 1 INF Kompilatorteknikk Våren 2012 Frist mandag 19. mars

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

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

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

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.

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

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

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

Hovedstoffet i kap 4: 16. Februar Ifi, UiO

Kapittel 7: Mer om arv

Velkommen til INF2100

Klasser, objekter, pekere og UML. INF gruppe 13

INF5110, 15/ Dagens temaer: Avslutning kap. 4 Begynne på kap. 5 Se på oppgave. Stein Krogdahl, Ifi UiO

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

Dagens tema: Resten av det dere trenger til del 1

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

En kompilator for Pascal. Kompendium for INF2100

Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

UNIVERSITETET I OSLO

INF Seminaroppgaver til uke 3

Løse reelle problemer

GUI («Graphical User Interface») del 2

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

Velkommen til INF2100

IN våren 2019 Onsdag 16. januar

IN våren 2018 Tirsdag 16. januar

Hjemmeeksamen 2 i INF3110/4110

Kapittel 1. Datamaskiner og programmeringsspråk. 1.1 Programmering

Obligatorisk Innlevering 2

Språktyper og syntaksanalyseteknikker. Dagens temaer. Hvordan lage en deterministisk automat? Fra jernbanediagram til ID-automat

Kapittel 1: Datamaskiner og programmeringsspråk

Jentetreff INF1000 Debugging i Java

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

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

Programmeringsspråket C

En kompilator for Pascal. Kompendium for INF2100

GUI («Graphical User Interface») del 2

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

UNIVERSITETET I OSLO

Transkript:

Dagens tema Hva er kompilering? Hvordan foreta syntaksanalyse av et program? Hvordan programmere dette i Java? Hvordan oppdage syntaksfeil?

Kildekode Hva er kompilering? Anta at vi lager dette lille programmet mini.pas (kalt kildekoden): /* Et minimalt Pascal-program */ program Mini; begin write( x ); end.

Maskinkode Dette programmet kan ikke kjøres direkte på noen datamaskin, men det finnes en x86-kode (kalt maskinkoden) som gjør det samme: $ od -t x1 mini 0000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 0000020 02 00 03 00 01 00 00 00 40 83 04 08 34 00 00 00 0000040 24 08 00 00 00 00 00 00 34 00 20 00 08 00 28 00 0000060 1e 00 1b 00 06 00 00 00 34 00 00 00 34 80 04 08 0000100 34 80 04 08 00 01 00 00 00 01 00 00 05 00 00 00 0000120 04 00 00 00 03 00 00 00 34 01 00 00 34 81 04 08 0000140 34 81 04 08 13 00 00 00 13 00 00 00 04 00 00 00 0000160 01 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08 0000200 00 80 04 08 cc 05 00 00 cc 05 00 00 05 00 00 00 0000220 00 10 00 00 01 00 00 00 cc 05 00 00 cc 95 04 08 0000240 cc 95 04 08 00 01 00 00 08 01 00 00 06 00 00 00.

Maskinkode Det er ikke lett å lese slik kode det går bedre i assemblerkode som kan oversettes til maskinkode av en assembler: # Code file created by Pascal2100 compiler 2015-09-15 22:06:52.extern write_char.extern write_int.extern write_string.globl _main.globl main _main: main: call prog$mini_1 # Start program movl $0,%eax # Set status 0 and ret # terminate the program prog$mini_1: enter $32,$1 # Start of mini movl $120,%eax # char 120 pushl %eax # Push param #1. call write_char addl $4,%esp # Pop parameter. leave # End of mini ret

Kompilatoren Kompilatoren En kompilator leser Pascal2100-koden og lager x86-assemblerkoden. En slik kompilator skal dere lage.

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

Et tre er den beste representasjonsformen Programtreet De færreste programmeringsspråk kan oversettes linje for linje, men det ville vært mulig med Pascal2100. 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 tre er den beste representasjonsformen Et Pascal2100-program Et program består av en navngitt blokk: program program name ; block.

Et tre er den beste representasjonsformen Programmet mini.pas representeres da av <program> /* Et minimalt Pascal-program */ program Mini; begin write( x ); end. <block>.........

Et tre er den beste representasjonsformen Det fulle programmet mini.pas ser slik ut: <program> <block> /* Et minimalt Pascal-program */ program Mini; begin write( x ); end. <statm list> <proc call> <empty statm> <expression> Slike trær skal vi lage. <simple expr> <term> <char literal>

Analyse av naturlige språk Syntaksanalyse På skolen hadde vi grammatikkanalyse hvor vi fant subjekt, predikat, indirekte og direkte objekt: Faren ga datteren en ball. (Det er ikke alltid like enkelt: Fanger krabber så lenge de orker. ) Syntaksanalyse er på samme måte å finne hvilke språkelementer vi har og bygge syntakstreet.

Analyse av programmeringsspråk Heldigvis: Analyse av programmeringsspråk er enklere enn naturlige språk: Programmeringsspråk har en klar og entydig definisjon i jernbanediagrammer eller tilsvarende. Programmeringsspråk er laget for å kunne analyseres rimelig enkelt.

Syntaksdiagram Grammatikk Grammatikken (i form av jernbanediagrammene) er et ypperlig utgangspunkt for å analysere et program og bygge opp syntakstreet: while-statm while expression do statement

Syntaksdiagram while-statm while expression do statement Utifra dette vet vi: 1 Først kommer symbolet while. 2 Så kommer en expression. 3 Etter den kommer en do. 4 Til sist kommer et statement.

Analyse av et Pascal2100-program Programmering av syntaksanalyse Utifra jernbanediagrammet kan vi lage en skisse for en metode som analyserer en while-setning i et Pascal2100-program: class WhileStatm extends Statement {. static WhileStatm parse(scanner s) { Sjekk at vi har lest while Expression.parse(s); Sjekk at vi har lest do Statement.parse(s);

Analyse av et Pascal2100-program Stort sett gjør vi to ting: Terminaler (i rundinger) sjekkes. Ikke-terminaller (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? Mange programmeringsspråk (som Pascal men ikke Java, C og C++) er designet slik at denne teknikken kalt recursive descent 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. Pascal2100 er LL(2). 1 1 Det finnes ett unntak; det skal vi se på neste uke.

Veien er alltid gitt! Veien er alltid klar statement assign statm compound statm empty statm if-statm proc call while-statm

Hvordan skrive dette i Java? Hvordan programmerer vi dette i Java? Husk at målet med analysen er tofoldig: 1 Vi skal sjekke at programmet er riktig. 2 Vi skal bygge opp et korrekt syntakstre.

Hvordan skrive dette i Java? Det er naturlig å koble analysemetoden til den klassen som skal inngå i syntakstreet. Hver ikke-terminal i jernbanediagrammet implementeres av en Java-klasse. 2 Hver av disse klassene får en metode static xxx parse(scanner s) {... som kan analysere «seg selv» og returnere et objekt som representerer «seg selv». 2 Dette er bare nesten riktig mer om dette siden.

Hvordan skrive dette i Java? Pascal2100-kompilatoren kan ha disse klassene til å representere ikke-terminaler. (Abstrakte klasser er satt i hakeparenteser og innrykk markerer subklasser.) CodeFile LogFile Main [PascalSyntax] - Block - - Library - ConstDeclPart - Expression - [Factor] - - [Constant] - - - CharLiteral - - - NamedConst - - - NumberLiteral - - - StringLiteral - - FuncCall - - InnerExpr - - Negation - - Variable - [Operator] - - FactorOperator - - PrefixOperator - - RelOperator - - TermOperator - ParamDeclList - [PascalDecl] - - ConstDecl - - EnumLiteral - - ParamDecl - - ProcDecl - - - FuncDecl - - Program - - TypeDecl - - VarDecl - SimpleExpr - [Statement] - - AssignStatm - - CompoundStatm - - EmptyStatm - - IfStatm - - ProcCallStatm - - WhileStatm - StatmList - Term - [Type] - - ArrayType - - EnumType - - RangeType - - TypeName - TypeDeclPart - VarDeclPart Scanner Token TokenKind

Hva er statiske objektelementer? Statiske deklarasjoner Vanlige variabler i klasser Vanlige variabler oppstår når et objekt opprettes. Det kan derfor være vilkårlig mange av dem. static-variabler Disse ligger i «selve klassen» så det vil alltid være nøyaktig én av dem.

Hva er statiske objektelementer? 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(); Resultatet a.id = 1 b.id = 2 System.out.println("a.id = "+a.id); System.out.println("b.id = "+b.id);

Hva er statiske objektelementer? Vanlige metoder i klasser Vanlige metoder ligger logisk sett i det enkelte objektet. Når de refererer til variabler, menes variabler i samme objekt eller static-variabler 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-variabler.

Strukturen vår Prosjektet vårt i Java 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...

Rot-klassene Rot-klassen Vi lar alle parser-klassene være subklasser av PascalSyntax. package no.uio.ifi.pascal2100.parser; import no.uio.ifi.pascal2100.main.*; public abstract class PascalSyntax { public int linenum; PascalSyntax(int n) { linenum = n; boolean isinlibrary() { return linenum < 0; abstract void check(block curscope, Library lib); abstract void gencode(codefile f); abstract public String identify(); abstract void prettyprint(); void error(string message) { Main.error("Error at line " + linenum + ": " + message);

Rot-klassene Alle deklarasjonene er også subklasser av PascalDecl: package no.uio.ifi.pascal2100.parser; public abstract class PascalDecl extends PascalSyntax { String name, progprocfuncname; int decllevel = 0, decloffset = 0; Type type = null; PascalDecl(String id, int lnum) { super(lnum); name = id;

Rot-klassene Klassen Program kan da se slik ut: package no.uio.ifi.pascal2100.parser; import no.uio.ifi.pascal2100.main.*; import no.uio.ifi.pascal2100.scanner.*; import static no.uio.ifi.pascal2100.scanner.tokenkind.*; /* <program> ::= program <name> ; <block>. */ public class Program extends PascalDecl { Block progblock; Program(String id, int lnum) { super(id, lnum); @Override public String identify() { return "<program> " + name + " on line " + linenum;

Rot-klassene public static Program parse(scanner s) { enterparser("program"); s.skip(programtoken); s.test(nametoken); Program p = new Program(s.curToken.id, s.curlinenum()); s.readnexttoken(); s.skip(semicolontoken); p.progblock = Block.parse(s); p.progblock.context = p; s.skip(dottoken); leaveparser("program"); return p;

Rot-klassene Husk I scanner.scanner har vi public void test(tokenkind t) { if (curtoken.kind!= t) testerror(t.tostring()); public void testerror(string message) { Main.error(curLineNum(), "Expected a " + message + " but found a " + curtoken.kind + "!"); public void skip(tokenkind t) { test(t); readnexttoken(); og i main.main har vi public static void error(string message) { log.noteerror(message); throw new PascalError(message);

Syntaksanalysatoren og skanneren Samarbeid med skanneren 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!

Hvordan finner man programmeringsfeil? 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.

Hvordan finner man programmeringsfeil? Et eksempel var decl part var var decl var decl name : type ; var v : integer = 5 ;

Parsering av While-setning package no.uio.ifi.pascal2100.parser; import no.uio.ifi.pascal2100.main.*; import no.uio.ifi.pascal2100.scanner.*; import static no.uio.ifi.pascal2100.scanner.tokenkind.*; /* <while-statm> ::= while <expression> do <statement> */ class WhileStatm extends Statement { Expression expr; Statement body; WhileStatm(int lnum) { super(lnum); @Override public String identify() { return "<while-statm> on line " + linenum; static WhileStatm parse(scanner s) { enterparser("while-statm"); WhileStatm ws = new WhileStatm(s.curLineNum()); s.skip(whiletoken); ws.expr = Expression.parse(s); s.skip(dotoken); ws.body = Statement.parse(s); leaveparser("while-statm"); return ws;