compileren & interpreteren - compileren: vertalen (omzetten) - interpreteren: vertolken - belangrijkste punten: - ontleden van de programmatekst - bijhouden van de datastructuren Data Structuren en Algoritmen - Sorteren september 2013 1
voorbeeldprogramma in Java void main (String [] args) { int k = 1, kw = 1; while (k < 10) /* invariant: kw = k 2 */ { kw += k ++; kw += k; Data Structuren en Algoritmen - Sorteren september 2013 2
ontleedboom Data Structuren en Algoritmen - Sorteren september 2013 3
vertalen naar 68000 assembly registergebruik: d1 = k d2 = kw move.w #1, d1 ; k = 1 move.w #1, d2 ; kw = 1 while: cmp.w #10, d1 ; if (k < 10) bge endwhile ; add.w d1, d2 ; kw = kw + k add.w #1, d1 ; k = k + 1 add.w d1, d2 ; kw = kw + k bra while endwhile: vertaling komt tot stand door ontleedboom te doorlopen while-lus nagebootst met sprongen naar labels Data Structuren en Algoritmen - Sorteren september 2013 4
interpretatie in een opzoektabel staan de namen van de variabelen met hun waarde Data Structuren en Algoritmen - Sorteren september 2013 5
interpretatie interpreteren is dus (recursief) ontleedboom doorlopen en opdrachten nabootsen Data Structuren en Algoritmen - Sorteren september 2013 6
ontleden Data Structuren en Algoritmen - Sorteren september 2013 7
ontleden void main (String []) { int k = 1, kw = 1; while (k < 10) { kw += k ++; kw += k; Data Structuren en Algoritmen - Sorteren september 2013 8
lexicon - woordenboek - token woord uit tekst + tokentype - beschrijvingsmiddel reguliere expressies - ebnf-notatie ::= definitie keuze [ ] optioneel (0 of 1 keer) { herhaling ( 0) - voorbeelden letter ::= 'A'... 'Z' 'a'... 'z' cijfer ::= '0'... '9' identifier ::= ( '_' letter ) { '_' letter cijfer getal ::= [ ' ' '+' ] cijfer { cijfer Data Structuren en Algoritmen - Sorteren september 2013 9
lexicale analysator enum Token {Ident, Number, LPar, RPar, Plus, Times, Minus, Divide, Eof, Invalid; class Tokenizer { public Tokenizer(String ins) ; // initialize with string public Tokenizer(File ins); // initialize with file public void close(); // close tokenizer public Token gettokentype(); // return type of token public String gettokenstring(); // return string of token public int gettokenvalue(); // return value of integer token public void getnexttoken(); // shift to next token Data Structuren en Algoritmen - Sorteren september 2013 10
lexicale analysator (vervolg) - een lexicale analysator wordt in het algemeen gemaakt vanuit een reguliere expressie - dit proces kan worden geautomatiseerd - de reguliere expressie wordt daartoe eerst omgezet in een eindige automaat - van de eindige automaat wordt een programma afgeleid - gereserveerde woorden worden meestal opgezocht in een tabel Data Structuren en Algoritmen - Sorteren september 2013 11
grammatica - een grammatica beschrijft de structuur van de zinnen van een taal via produktieregels - (vgl. redekundig ontleden) voorbeeld: statements van C startsymbool: statement eindsymbolen: de tokens van de lexicale analyse produkties: statement ::= if_statement assignment... if_statement ::= if ( expressie ) rest_if rest_if ::= statement [ else statement ] etc. Data Structuren en Algoritmen - Sorteren september 2013 12
probleem schrijf een programma dat een rekensom inleest en het antwoord afdrukt voorbeelden van rekensommen 12 100 25 20 + 3 8 (9 3) / 2 + 7 (3 1) een rekensom bestaat uit: - getallen (zonder teken) - haken (netjes in paren) - operatoren '+', ' ', ' ', '/' '+' en ' ' hebben dezelfde prioriteit ' ' en '/' hebben dezelfde prioriteit ' ' en '/' gaan voor '+' en ' ' Data Structuren en Algoritmen - Sorteren september 2013 13
lexicale analyse getal ::= ('1'... '9') { '0'... '9' lhaak rhaak plus min maal deel ::= '(' ::= ')' ::= '+' ::= ' ' ::= ' ' ::= '/' scheidingsteken ::= '\n ' semantiek (= betekenis) waarde (getal) wordt bepaald door - waarde (c 0 ) = c 0 - '0' - waarde (c n-1... c 0 ) = 10 waarde (c n-1... c 1 ) + waarde (c 0 ) Data Structuren en Algoritmen - Sorteren september 2013 14
grammatica: eerste poging startsymbool : expressie expressie ::= getal expressie plus expressie expressie min expressie expressie maal expressie expressie deel expressie lhaak expressie rhaak Data Structuren en Algoritmen - Sorteren september 2013 15
semantiek semantische regels voor waarde (expressie): waarde (getal) = getal waarde (expressie 1 plus expressie 2 ) = waarde (expressie 1 ) + waarde (expressie 2 ) waarde (expressie 1 min expressie 2 ) = waarde (expressie 1 ) waarde (expressie 2 ) waarde (expressie 1 maal expressie 2 ) = waarde (expressie 1 ) waarde (expressie 2 ) waarde (expressie 1 deel expressie 2 ) = waarde (expressie 1 ) / waarde (expressie 2 ) waarde (lhaak expressie rhaak) = waarde (expressie) Data Structuren en Algoritmen - Sorteren september 2013 16
voorbeelden grammatica is ambigu (= dubbelzinnig) Geef een andere parsetree die ook bij deze expressie mogelijk is. Data Structuren en Algoritmen - Sorteren september 2013 17
grammatica: tweede poging startsymbool : expressie expressie ::= term { ( plus min ) term term ::= factor { ( maal deel ) factor factor ::= getal lhaak expressie rhaak de keuze van de produkties hangt samen met de prioriteiten van de operatoren voorbeeld semantische regel: waarde (term 1 - term 2 + term 3 ) = waarde (term 1 ) - waarde (term 2 ) + waarde (term 3 ) Data Structuren en Algoritmen - Sorteren september 2013 18
voorbeelden deze afleiding kan worden gevonden door boven in de boom te beginnen met het startsymbool expressie een expressie begint altijd met een term een term begin altijd met een factor het token is getal, dus factor gevonden het volgende token is plus, dus term gevonden nu op zoek naar de volgende term van expressie Data Structuren en Algoritmen - Sorteren september 2013 19
recursieve ontleedfuncties voor lexicale analyse: enum Token{ Ident,, Eof, Invalid ; Token gettokentype; int gettokenvalue;/* waarde getal */ String gettokenstring(); void getnexttoken (); /* shift next*/ voor ontleding: int expressie (); int term (); int factor (); invariant: gettokentype() geeft eerstvolgende tokentype elke functie leest / berekent een zo groot mogelijke expressie, term of factor Data Structuren en Algoritmen - Sorteren september 2013 20
recursieve ontleedfuncties int expressie() throws Exception { int waarde = term(); while (tkn.gettokentype() == Token.Plus tkn.gettokentype() == Token.Minus) { if (tkn.gettokentype() == Token.Plus) { tkn.getnexttoken(); waarde += term(); else { tkn.getnexttoken(); waarde -= term(); return waarde; int term() throws Exception { int waarde = factor(); while (tkn.gettokentype() == Token.Times tkn.gettokentype() == Token.Divide) { if (tkn.gettokentype() == Token.Times) { tkn.getnexttoken(); waarde *= factor(); else { tkn.getnexttoken(); waarde /= factor(); return waarde; Data Structuren en Algoritmen - Sorteren september 2013 21
recursieve ontleedfuncties int factor() throws Exception { int waarde = 0; if (tkn.gettokentype() == Token.Number) { waarde = tkn.gettokenvalue(); tkn.getnexttoken(); // voor invariant else if (tkn.gettokentype() == Token.LPar) { tkn.getnexttoken(); waarde = expressie(); if (tkn.gettokentype()!= Token.RPar) { throw new Exception(") expected"); tkn.getnexttoken(); // voor invariant else { throw new Exception("Unexpected token " + tkn.gettokentype()); return waarde; Factor leest getallen en haakjes. Expressie en term lezen de operatoren! Bij foute invoer wordt er een exceptie gegenereerd. Data Structuren en Algoritmen - Sorteren september 2013 22
recursieve ontleedfuncties het ontleden wordt gestart met: tkn = new Tokenizer(input); tkn.getnexttoken(); // invariant int result = expressie(); dezelfde structuur kan worden gebruikt om een ontleedboom op te bouwen als je eenmaal een geschikte grammatica hebt, is het tamelijk eenvoudig de recursieve ontleedfuncties te schrijven helaas is niet elke grammatica geschikt voor deze ontleedmethode valkuilen: oneindige recursie meer dan één keuzemogelijkheid (tokentype geeft geen uitsluitsel) het is wel altijd mogelijk een grammatica om te werken zodat deze wel geschikt wordt! Data Structuren en Algoritmen - Sorteren september 2013 23
waarom hier geen oneindige recursie dus elke functie consumeert een stuk van de invoer (en aan het eind van de invoer stopt factor) waarom hier geen keuzeproblemen expressie ::= term { ( plus min ) term term ::= factor { ( maal deel ) factor factor ::= getal lhaak expressie rhaak aan tokentype kan direct worden afgelezen welke keuze gemaakt moet worden Data Structuren en Algoritmen - Sorteren september 2013 24