Inleiding Vertalerbouw, versie 2003

Maat: px
Weergave met pagina beginnen:

Download "Inleiding Vertalerbouw, versie 2003"

Transcriptie

1 Inleiding Vertalerbouw, versie 2003 Dr.ir. H. Meijer, Subfaculteit Informatica, KU Nijmegen Introductie Een vertaler is een programma, meer algemeen een systeem, dat een tekst in een bepaalde taal omzet in een tekst in een andere taal, maar met dezelfde betekenis. Bijvoorbeeld een C-programma in een Sparc-programma (machinecode), of een Engels document in een Noors idem. Wij zullen onze vingers niet branden aan het heikele vertaalprobleem voor natuurlijke talen en alleen kijken naar in- en uitvoertalen met een heldere syntax (= een stel vormregels) en een eenduidige semantiek (= een stel betekenisregels). Als de invoertaal een programmeertaal is wordt de vertaler ook wel een compiler genoemd, maar we zullen ons niet daartoe beperken. Eén van de doelstellingen is nu juist, aannemelijk te maken, dat veel gewone programma s kunnen worden opgevat als vertalers, en dat zo n perspectief vaak heel verhelderend kan zijn. In zekere zin kan namelijk ieder programma als vertaler worden opgevat. Immers, het totaal aan invoer, hoe ingewikkeld ook (tekst, interactief beeldmateriaal, gegevens uit een database, desnoods gecombineerd), kan worden gezien als een gestructureerde tekst, die aan vormregels voldoet die impliciet door het programma worden opgelegd. Het resultaat van het programma, hoe ingewikkeld ook, is dan de vertaling. Als het érg ingewikkeld wordt is dit paradigma misschien niet zo nuttig, maar het idee is iets om in het achterhoofd te houden. In elk geval worden veel conversieprogramma s (van HTML naar Word, bijvoorbeeld) eigenlijk vrij eenvoudig als ze worden opgevat als vertalers. We zullen daarop iets nader ingaan in hoofdstuk 5. Overigens noemen we een vertaler die de betekenis van zijn invoertekst oplevert liever een vertolker, al is het verschil niet principiëel. Immers, die opgeleverde betekenis zal toch op de een of andere manier wel gecodeerd zijn (in een taal). Is 24 de vertaling of de betekenis van het romeinse getal xxiv? Toch is er wel een interessant verschil tussen vertalen en vertolken. Als de invoertekst een programma is, kan dat programma zelf ook weer invoer hebben. Dat programma kan dan zonder de invoer te zien wel worden vertaald, maar niet worden vertolkt. Je kunt dat ook formeel opschrijven. Stel p is het te vertalen programma in programmeertaal P, en i zijn invoer. De vertolker is dan een functie v P, en het resultaat van p, met invoer i v P (p, i) Datzelfde resultaat wordt (per definitie) bereikt door een vertaling c(p) in een programmeertaal M, waarin c dus een vertaler is, toe te passen op i: v M (c(p), i) Tenslotte: de vertaler zelf is meestal ook een programma, geschreven in een programmeertaal. Als dat niet een algemene taal is zoals C, maar een taal die speciaal ontworpen is voor het schrijven van vertalers (bijvoorbeeld affix- of attribuutgrammatica s, die aan de orde komen in hoofdstuk 4.2), dan wordt de vertaler dáárvoor wel een vertalergenerator of compiler-compiler genoemd.

2 2 1 Vertolken 1 Vertolken In de eerste twee hoofdstukken gaan we in het wilde weg wat oefenen door een elementaire programmeertaal (Simplexp) te ontwikkelen en tegelijkertijd een vertolker/vertaler daarvoor, om hands-on te ervaren waar de problemen zitten. 1.1 De basis We beginnen uiterst elementair, met rekenkundige expressies met de operatoren +, -, *, / en ^, getallen van één cijfer, en zonder haakjes. Bijvoorbeeld 1+2*3-4 Als wij dat zelf evalueren beginnen we met 2*3 omdat * een hoge prioriteit heeft (want Meneer Van Dalen Wacht Op Antwoord), vervolgens 1+6 en tenslotte 7-4. Als we het iets systematischer aanpakken en stap voor stap werken, van links naar rechts (andersom zou ook kunnen) en de voortgang aangeven met een index (.) wordt dit.1+2* * * * * * Het deel achter de index is de nog te verwerken rest van de invoer en het deel vóór de index noemen we de stapel (of stack) 1. In principe schuiven we steeds het volgende symbool van de invoer op de stapel, tenzij dat symbool een operator is met een prioriteit lager dan die van de operator die bovenop (d.w.z. het meest rechts) op de stapel staat. In dat geval evalueren we de enkelvoudige expressie die boven op de stapel staat. Er vindt dus, afhankelijk van de onderlinge prioriteit van operatoren, één van twee bewerkingen plaats, die ook wel shift en reduce worden genoemd. Dat is het principe, maar er is een aantal details waar we op moeten letten. In de invoer staan cijfers, maar op de stapel kunnen als gevolg van de evaluaties getallen van meer cijfers terechtkomen. Daarom zal het minder handig zijn de stapel in een vertolker werkelijk als een tekenrij voor te stellen. De stapel bestaat uit een afwisseling van (positieve of negatieve) getallen en operatoren, die als een lijst kan worden geïmplementeerd, of als twee nauw samenwerkende lijsten. Een dergelijke representatie betekent dat bij het schuiven de cijfers moeten worden geconverteerd naar getallen en de operatoren naar de voor hen gekozen interne representatie. Merk op dat de stapel in principe willekeurig groot moet kunnen worden (alleen beperkt door het beschikbare geheugen). We gaan dus niet zitten rommelen met arbitrair gekozen bovengrenzen. 1 We zouden die stapel kunnen vermijden door met recursieve functies te gaan werken, maar dat doen we op educatieve gronden nu juist niet.

3 1 Vertolken 3 Maar hoe zit het nu precies met de prioriteit van de operatoren? Een operator moet worden geshift als zijn prioriteit groter is dan die van de hoogste operator op de stapel. Dus geldt sowieso dat ^ groter is dan * en / (die onderling even groot zijn) en dat die weer groter zijn dan + en - (die ook onderling even groot zijn). Maar: uit 2 32 komt 512 en niet 64. Want ^ is rechtsassociatief. Het zijn allemaal maar afspraken (om minder haakjes te hoeven schrijven), maar toch. Operatoren die onderling een gelijke prioriteit hebben zijn (onderling) linksassociatief (uit komt 4 en niet 0) of rechtsassociatief. Als het niet uitmaakt, denk bijvoorbeeld aan , heet de operator associatief, maar zullen we hem als linksassociatief beschouwen. Al met al is de prioriteit van operatoren een ietwat arbitraire relatie op operatoren, die in ons eenvoudige geval kan worden geschreven als {+, - < {*, /, ^ < {^ en die het beste met een tabel kan worden vastgelegd. Merk op dat < in het algemeen geen (partiële) ordening is. In zekere zin is < een impliciet linkerhaakje 2. Zolang operatoren van gelijke prioriteit óf allemaal rechtsassociatief zijn óf allemaal (links)associatief, is ook een simpeler implementatie mogelijk: iedere operator krijgt een numeriek prioriteitsniveau en een associativiteitsattribuut (L of R). Zie voor ons eenvoudige geval de tabel hiernaast. De regel is nu dat er moet worden geschoven als de prioriteit van de hoogste operator op de stapel kleiner is dan die van het eerstvolgende (operator-)symbool in de invoer én als die prioriteiten gelijk zijn en de betrokken operator rechtsassociatief is. + 1 L - 1 L * 2 L / 2 L ^ 3 R Het begin van de algoritme loopt ietwat stroef, als je met een lege stapel begint: de eerste operator valt immers nergens mee te vergelijken. Je kunt dit (dus) versoepelen door vantevoren een beginmarker op de stapel te zetten. Iets dergelijks doet zich voor bij de laatste operator. Daarom nemen we aan dat er een endmarker achter de expressie staat. De begin- en eindmarker kunnen worden gezien als operatoren met een prioriteit die lager is dan alle andere. We maken ze hier even zichtbaar als vierkante haken. Je begint dus met [.1+2*3-4] en eindigt in de situatie [7.] d.w.z. op het moment dat je de markers vergelijkt. Oefening Bestudeer de C-code van deze elementaire vertolker zoals gegeven in appendix A. Let vooral op 1 de implementatie van de stapel, 2 de representatie van de operatoren en hun prioriteit en 3 de overall-structuur van de algoritme. 1.2 Simplexp Voor een wat realistischer vertolker, met grotere getallen en met haakjes, kunnen we volstaan met een tamelijk eenvoudige uitbreiding van de eerste versie. Wat de getallen betreft kunnen we als volgt te werk gaan: als we een cijfer zien, kijken we of er nog meer cijfers volgen. Zo ja, dan vermenigvuldigen we bij elk daarvan wat we al hebben met 2 In de parseertheorie staat de relatie bekend als een precedentie-relatie. Wij zullen de bijbehorende, ietwat ouderwetse, precedence parsers niet behandelen.

4 4 1 Vertolken 10 en tellen er de waarde van het nieuwe cijfer bij op. Je kunt dat ook zó zien dat er tussen elk tweetal cijfers een onzichtbare links-associatieve operator maal-10-plus staat. Dus: als je een operator verwacht en er staat een cijfer, dan doe je alsof je die operator hebt gelezen. Haakjes zijn makkelijk. Je zet een linkerhaakje, dat je kunt krijgen als je een operand verwacht, áltijd op de stapel, en blijft een operand verwachten. Een rechterhaakje, dat je kunt krijgen als je een operator verwacht, dwingt élke operator op de stapel tot evaluatie. De evaluatie van een linkerhaakje bestaat daarbij uit het zichzelf én het rechterhaakje verwijderen. Aldus blijft het resultaat van de deelexpressie op de top van de stapel over en kan er een nieuwe operator verwacht worden. En passant kunnen we voor de leesbaarheid ook makkelijk spaties toelaten in de tekst van de expressie. Opdracht 1 Breid de in appendix A gegeven vertolker uit volgens de tot nu toe besproken ideeën. Vervolgens introduceren we variabelen, en dus ook definities. Voor het definitieteken nemen we =, en variabelen bestaan uit kleine letters en cijfers, als de eerste maar een kleine letter is. We lezen tekst ongeveer zoals we getallen lezen. (Wie een expliciete operator maal-10-plus heeft kan hier een concatenatie invoeren.) Een programma gaat nu bestaan uit een expressie, voorafgegaan door een mogelijk lege rij definities, elk afgesloten door een puntkomma. Een definitie bestaat achtereenvolgens uit een variabele, een definitieteken en een expressie. Let op: als je als eerste operand een variabele aantreft, weet je nog niet of het een definitie wordt, of de eindexpressie! 3 Om de waarden van variabelen te kunnen onthouden, moeten we een naamlijst maken, waarin naam-waarde-paren staan. Omdat we niet weten hoeveel variabelen er komen heeft een lineaire lijst weer de voorkeur boven een rij met vaste lengte. De variabelen kunnen voorts verschijnen waar we operanden verwachten. Hun evaluatie bestaat in het algemeen uit het op de stapel zetten van hun in de naamlijst opgezochte waarde. Maar bij de variabelen die in de linkerkant van een definitie moeten we natuurlijk heel iets anders doen. Oefening Breid je vertolker uit met variabelen en definities zoals hierboven besproken. De volgende stap is het invoeren van voorwaardelijke expressies IF a < b THEN 3 ELSE 4 FI We voeren om te beginnen een stuk of 6 vergelijkingsoperatoren in (bijvoorbeeld <, <=, >, >=, == en <>). Op zichzelf is dat geen probleem want het zijn gewone operatoren met een prioriteit onder die van +. Wel moeten we vanaf nu ook operatoren van meer dan één teken aankunnen. 4 Met het invoeren van de operator == kan het definitieteken = problematisch worden. 5 Maar wat is het resultaat van a<b? Inderdaad: waar of niet waar. Je zou er pakweg 17 (voor waar ) of 19 (voor niet waar ) uit kunnen laten komen 6, maar we zullen netjes een nieuw type boolean introduceren, zoals in de meeste talen gebruikelijk is met constanten TRUE en FALSE. Waarden van dat type komen op de stapel terecht, dus ziet het ernaar uit dat ze intern toch als 3 Dit is een voorbeeld van het look-ahead-probleem dat we nu ad hoc oplossen, maar systematisch zullen aanpakken in hoofdstuk Deze aanpassing kan wat tijd kosten als je je programma niet goed hebt opgezet. Let er op dat het ongebruikelijk is om in samengestelde symbolen spaties toe te staan; voor sleutelwoorden als IF is het zelfs ongewenst. 5 Een mogelijke (ad hoc) aanpak: een variabele komt alleen dan nog niet in de naamlijst voor als de stapel leeg is; en dan (en alleen dan) wordt hij gevolgd door een definitieteken en bovendien zitten we dan (en alleen dan) nog niet in de eindexpressie. 6 C heeft zoiets, maar dat is dan ook een (symbolische) machinetaal.

5 1 Vertolken 5 geheel getal moeten worden gerepresenteerd. Maar hoe hou je dan de boolean 17 en de integer 17 uit elkaar? Eén manier is, de elementen op de stapel een extra kenmerk te geven, m.a.w. te typeren. Je kunt dan in één moeite door ook de operatoren als operator typeren 7. Van elke constante en elke operator weet je welk type hij oplevert, en elke operator moet (en kan) bij evaluatie het type van zijn operanden checken. Dit wordt dynamische typering genoemd. De conditional is in wezen ook een gewone operatie, met 1 boolean operand en 2 integer (of boolean) operanden. Je zou IF kunnen behandelen als een linkerhaakje, en THEN, ELSE en FI als rechterhaakjes met dien verstande dat alléén de FI evalueert: deze verwacht dat de top van de stapel er uitziet als... if x then y else z waarin x, y en z de resultaten van de operand-expressies zijn. FI moet dus het hele zaakje vervangen door y, als x waar blijkt te zijn, en anders door z, en zelf verdwijnen. Opdracht 2 Breid je vertolker (inclusief grotere getallen, haakjes, layout, variabelen en definities) uit met voorwaardelijke expressies zoals hierboven besproken. Vragen 1 Als je uit de stapel de operanden weglaat, bestaat hij uit één of meer segmenten die beginnen met een haakje (mogelijk in de vorm van een beginmarker, IF, etc.) gevolgd door een al of niet leeg rijtje operatoren. Wat voor systematiek zit er in zo n rijtje? 2 Onze prioriteitsrelatie < is minimaal. Ook maximaal? 3 Motiveer de keuze voor de representatie van operatoren op de stapel. 4 Waarom is < geen ordening? 5 Waarom moet de operator maal-10-plus links-associatief zijn? 6 Waarom heet het look-aheadprobleem look-ahead probleem? 7 Is het wel of niet mogelijk te vermijden dat namen van variabelen op de stapel terechtkomen? 8 Zou het zinvol zijn de naamlijst als boom te implementeren? 9 Waarom mogen sleutelwoorden als IF, TRUE, etc. geen spaties bevatten? 10 Waarom heet de ingevoerde typering dynamisch? 7 Je zou in het operatortype zelfs het aantal operanden en hun type kunnen vastleggen, maar dat voert nu even te ver. We komen daar op terug in hoofdstuk 6.2.

6 6 2 Vertalen 2 Vertalen We zullen nu proberen een zo natuurlijk mogelijke overgang te maken naar een vertaler voor Simplexp. 2.1 Vertalen naar prefixcode Op het eerste gezicht kunnen we nu net zo makkelijk herhalingen introduceren, in de vorm van een operator WHILE... DO... OD met 2 operanden. Helaas! Zoiets heeft alleen zin als er in de tweede operand toekenningen staan, en dan krijgen we een heel ander verhaal. 8 Zo n verhaal krijgen we ook als we in de tweede en derde operand van de conditional toekenningen toelaten. Een toekenning induceert immers een globaal effect. Als a in IF a == 0 THEN r = x ELSE a = a - 1 FI nul is, mag a niet nog eens met 1 worden verlaagd. De tweede en derde operand van zo n IF moeten pas worden geëvalueerd als t nodig is, en de operanden van WHILE elke keer opnieuw. Tot nu toe hebben we eerst de operanden geëvalueerd, en daarna de operator toegepast op de resultaten. Dat willen we dus niet voor operanden die toekenningen (kunnen) bevatten 9 en mogelijk minder dan één keer of meer dan één keer moeten worden geëvalueerd. Voor minder dan één keer zouden we nog kunnen verzinnen de betreffende operand op de een of andere manier gewoon over te slaan, maar meer dan één keer betekent dat we de operand moeten bewaren. Dat wordt een heel gedoe. Als we een WHILE tegenkomen kunnen we de eerste operand nog wel ter plekke evalueren, maar moeten we hem toch ook meteen ergens opslaan. Afhankelijk van de gevonden waarde moeten we de tweede operand overslaan, of evalueren en bewaren. In het laatste geval moeten we de eerste operand herevalueren, maar nu niet vanuit de invoer, maar vanuit de opgeslagen tekst. Enzovoort. Verder is het zo, dat de tekst zowel bij het overslaan als het bewaren als ook het herevalueren steeds opnieuw moet worden geanalyseerd, al is het maar om er achter te komen waar de betrokken deelexpressie ophoudt. Dat vraagt om maatregelen. Ten eerste is er veel voor te zeggen de hele expressie maar meteen vantevoren ergens in random access geheugen te zetten en dan van daaruit de evaluatie te doen. We kunnen dan nog steeds een leeswijzer (index, pointer) gebruiken om bij te houden waar we zijn maar deze desgewenst een eind terug of een eind verder zetten. Zo n leeswijzer kennen we natuurlijk al onder de naam program counter (PC). Ten tweede zou het bij het evalueren van een (deel)expressie niet onhandig zijn van meet af aan te weten wat diens operator is. Dan weet je vantevoren van elke operand of je die moet evalueren of overslaan. Dat is te bereiken door de omzetting van de expressie naar zijn prefixvorm (waarbij steeds een interne code voor de operatie wordt gevolgd door zijn operanden in prefixvorm), bijvoorbeeld 15+21*3 naar +15 *21 3 TRUE simpelweg naar T IF ab > 0 THEN a + b ELSE b - a FI naar pakweg?>ab 0 +a b -b a 8 Alleen in dit hoofdstuk zullen we werken met toekenningen, en = duiden als toekenningsteken. Definities worden even opgevat als declaraties van variabelen met initialisaties, en variabelen mogen meer dan eens als linkerkant van een toekenning optreden. 9 In talen zonder toekenningen of andere globale effecten zul je ongetwijfeld recursieve functies vinden en dan leidt strikte evaluatie van conditionals tot non-terminatie. De uitgestelde evaluatie van hun tweede en derde operand is dus een fundamentele eigenschap.

7 2 Vertalen 7 Getallen en namen worden afgesloten door een apostrof. De conditional is een gewone, enkelvoudige operator geworden, met 3 operanden. Prefixnotatie is equivalent met een boomstructuur, en heeft als bijkomend voordeel dat het zich heel gemakkelijk laat analyseren. (Maar de notatie is voor ons minder goed leesbaar.) Oefening Teken de boomstructuur van bovengenoemde expressies. Hoe zou je ten opzichte van de boomstructuur de prefix-, infix- en postfix-notatie kunnen karakteriseren? En daarmee hebben we de notie van een vertaler geïntroduceerd! De vertaler zet de expressie om in prefixvorm en elimineert daarbij spaties, haakjes, prioriteitsregels en de distfix -notatie van sommige operanden waardoor de evaluatie veel eenvoudiger wordt. De evaluator kijkt aan de hand van de PC welke operator, constante of naam aan de beurt is. Bij een constante of een naam zet hij de PC daarvoorbij en plaatst tegelijk de waarde ervan op de stapel (shift). Bij een operator met strikte operanden 10, zet hij de PC ervoorbij, roept zichzelf zo vaak aan als de operator operanden heeft, en vervangt evenzoveel waarden op de stapel door het resultaat van de erop toegepaste betrokken operatie (reduce). Intussen ligt het heel erg voor de hand voor de stapel nu die van C te gebruiken, en wel door de operandwaarden aan locale variabelen 11 toe te kennen. Merk op dat een constante of naam veel weg heeft van een operator zonder operanden, en dat alleen het aantal operanden en de uit te voeren operatie operatorspecifiek zijn. Als de operator een herhaling is, moet de evaluator bovendien de waarde van de PC onthouden. Als een operand moet worden overgeslagen, moet de evaluator in elk geval elke toekenningsoperatie daarin onderdrukken, maar kán hij ook het op de stapel plaatsen van waarden, en dus ook het berekenen ervan, onderdrukken. In het laatste geval moet hij bij een conditional tussentijds even op de stapel kijken om te zien welke operand moet worden onderdrukt. Oefening Schrijf een evaluator voor prefixcode. De evaluator leest alvorens met de evaluatie te beginnen een prefixexpressie in z n geheel van standaard-invoer en schrijft het resultaat naar standaard-uitvoer. Als je de evaluator wilt construeren uit je Simplexp-vertolker (wat heel goed kan), werk dan op een kopie. Intermezzo Een alternatieve evaluatievorm is herschrijven. In z n meest elementaire vorm vind je dat in de λ-calculus: λ-expressies zijn in prefixvorm en elke operator is zelf een expressie, met placeholders voor z n operanden. Het resultaat van een expressie is de operator, met de operanden (ongeëvalueerd) ingevuld voor de placeholders. Onze eerste vertolkers evalueerden elke operand strikt. De prefix-evaluator slaat operanden soms over, afhankelijk van de omstandigheden, en evalueert de overige strikt. Herschrijvers evalueren alleen operatoren, geen operanden. Een operand wordt ongeëvalueerd overgeslagen als-ie nooit een operator wordt, bijvoorbeeld doordat er geen placeholder voor is. Ook macro-processoren werken op basis van herschrijven, evenals de meeste functionele talen. Niet alleen de evaluator, maar ook de vertaler kan met weinig moeite worden afgeleid uit de vertolker die we tot nu toe hebben ontwikkeld. Voor de vertaler geldt: dat is gewoon de vertolker, met dien verstande dat elke operatie nu niet een integer of boolean waarde oplevert, maar een tekst die zijn prefixvorm bevat. Dus het resultaat van de expressie 1+2*3 is nu niet 7, maar +αβ waarin α het resultaat is van 1 (dus 1 ) en β dat van 2*3 (dus *2 3 ). In deze 10 Operanden die precies één keer moeten worden geëvalueerd. 11 In C-terminologie: automatic variables.

8 8 2 Vertalen context zijn alle operanden strikt! Elke vertaler kan met enige goede wil worden gezien als een vertolker met een incompleet proto-resultaat. Oefening Leid nu uit de in opdracht 2 verkregen vertolker een vertaler af volgens de gegeven richtlijnen. De vertaler schrijft zijn vertaling naar standaard-uitvoer. 2.2 Vertalen naar machinecode Onze vertaler is een echte, zij het nog simpele, vertaler. De prefixcode is de machinecode, en de vertolker daarvan, onze evaluator, is de machine. Compilers zetten programma s om in een equivalente vorm die gemakkelijk door een echte machine kan worden geïnterpreteerd (geëvalueerd, vertolkt). Een saillant detail is daarbij dat ook bij een machine als de Sparc elke instructie bestaat uit een operator met operanden, en eerst moet worden gedecodeerd. Om te komen tot een wat realistischer vertaler, zullen we nog een paar stappen zetten. Van operanden die mogelijk moeten worden overgeslagen kan de vertaler gemakkelijk de lengte berekenen. Die lengten plaatsen we op zo n manier vóór de betrokken operanden, dat de evaluator de PC zonder verder gedoe kan aanpassen als het nodig is. Aldus hebben we in feite (conditionele) sprongopdrachten ingevoerd. De volgende stap betreft de stapel. Ook hier kan de vertaler belangrijk voorwerk doen. Hij kan bepalen op welke positie van de stapel het resultaat van een (deel)expressie terechtkomt 12, volgens de volgende eenvoudige inductieve redenering. De resultaten van de operanden van de hele expressie komen op de posities 1, 2,... Algemeen, als het resulaat van een operand, die zelf een expressie is, op positie i komt, komen de resultaten van de operanden van die expressie op de posities i, i + 1,... Dit betekent dat de vertaler de associatie van waarden aan stapelposities zelf kan doen, en de stapelposities ( interne ) variabelen worden, met bijvoorbeeld de namen r1, r2,... De vertaling van 9+8*7 wordt dan (met = als toekenningsteken) ;=r1 9 ;=r2 8 ;=r3 7 ;=r2 *r2 r3 =r1 +r1 r2 Als we de puntkomma ( wordt gevolgd door ) op het topniveau nog even infix en als nieuwe regel schrijven, 13 staat er =r1 9 =r2 8 =r3 7 =r2 *r2 r3 =r1 +r1 r2 Dit lijkt ineens heel veel op echte machinecode (al is het maar vanwege de onleesbaarheid... ), en dat is natuurlijk geen toeval. In een soort assemblernotatie staat er zoiets als con r1,9 con r2,8 con r3,7 mul r2,r3 add r1,r2 De evaluator ( machine ) wordt intussen steeds simpeler, en de vertaler kan nóg meer doen. Om 12 Zodra we functies in onze expressietaal introduceren kan dat niet meer! Daarover gaat hoofdstuk Tussen DO en OD e.d. gaat dat niet zonder meer!

9 2 Vertalen 9 te voorkomen dat de evaluator de waarde van variabelen in een lijst moet opzoeken, kan de vertaler elke variabele toewijzen aan een vaste geheugenpositie ( adres ) v 1, v 2,... Ook aan elke constante moet hij dan een adres toewijzen (waarom?) en die met de waarde ervan initialiseren. Dat initialiseren kan statisch gebeuren, d.w.z. at compile time, of at run time met een speciale toekenningsoperator. Als alternatief kennen veel machines ook adresseringsmodes. Dan staat bijvoorbeeld #9 voor een het adres van een geheugenplaats met 9 als inhoud (een immediate ). In al deze gevallen hoeft de vertaler geen stapelpositie toe te kennen. Met nog een slimmigheidje (welk?) wordt ons machinecodeprogramma wel heel eenvoudig: mov r1,#8 mul r1,#7 add r1,#9 Zoals gezegd, kunnen we het overslaan van operanden probleemloos realiseren door middel van systematisch geplaatste relatieve sprong-instructies (die immers niets anders doen dan de program counter verhogen of verlagen). Opdracht 3 Pas je vertaler en evaluator aan zoveel mogelijk van de hier besproken nieuwste ontwikkelingen aan. Je vertaler moet nog steeds machinecode opleveren, geen assemblercode. Je evaluator zal nauwelijks veranderen. Nóg een stapje verder zou kunnen zijn: de vertaler kan net zo goed die operaties ook zelf doen, de gegevens zijn immers allemaal bekend. En inderdaad: de meeste compilers zullen expressies die niet afhangen van de invoer bij wijze van optimalisatie voorberekenen. Als er toekenningen in voorkomen kan dat leiden tot initialisatie van de betrokken variabelen. Wat de compiler in elk geval ook van de evaluator kan overnemen is het controleren van de typen. We zullen in hoofdstuk 6.2 zien in hoeverre de typen van expressies statisch kunnen worden vastgesteld. Hoe nu verder? We kunnen de taal eindeloos blijven uitbreiden, met datatypen als teksten, arrays of structures, of abstracte datatypen, en met blokstructuur en functies, of zelfs objecten en classes. Voor elk van die concepten zullen we slimme code moeten verzinnen, en we zullen dat in hoofdstuk 7 ten dele ook gaan doen. Maar eerst gaan we kijken of we die analyse, codegeneratie en typechecking niet eens iets systematischer kunnen aanpakken. Ook zullen we zien in hoeverre die systematiek voor andere vertalers dan compilers kan worden ingezet. Vragen 1 Waarom maken toekenningen (en niet, op zichzelf, de herhaling (WHILE)) het onvermijdelijk (delen van) expressies intern op te slaan? 2 Hoe kun je een (deel)expressie overslaan zonder z n lengte te kennen? 3 Waarom worden in de prefixvorm getallen en namen afgesloten door een apostrof? Is er een alternatief? 4 Je zou operatoren die hun operanden strikt evalueren, net zo goed in postfixvorm kunnen zetten. Waarom? 5 In hoeverre kan een constante worden gezien als een operator zonder operanden? 6 Hoe realiseren herschrijfsystemen niet-strikte operanden? 7 Aan welke stapelposities worden de operanden van de expressie 9*8+7 toegekend? 8 Waarom precies is het niet nodig de puntkomma (de wordt-gevolgd-door operator tussen o.a. toekenningen) in prefixvorm te brengen? 9 Typeer in enkele woorden (geen formele definitie) het begrip dynamisch typeren. 10 Ga voor jezelf na hoe je het datatype voor teksten in Simplexp zou inbouwen.

10 10 3 Herkenners 3 Herkenners We beginnen de systematische ontwikkeling van vertalers bij het herkennen van de invoertaal op basis van een formele beschrijving daarvan. Dit hoofdstuk is voor een deel een terugblik, uit een iets ander perspectief, op de stof van T Contextvrije grammatica s Het is niet moeilijk, de verschillende soorten expressies die onze vertolker of vertaler aan kan op te sommen. We hebben elementaire expressies, namelijk TRUE, FALSE, een getal of een variabele, en samengestelde, bijvoorbeeld de som die bestaat uit, achtereenvolgens, een expressie, een plus-teken en een expressie. In een (formele) contextvrije grammatica kunnen we dat in principe zó opschrijven: exp: true. exp: false. exp: getal. exp: variabele. exp: exp plus exp. exp: exp min exp. exp: if exp then exp else exp fi. getal: een. getal: twee. getal: drie. enzovoorts. We zien zogenaamde nonterminals (exp, getal, variabele) en terminals (true, plus,... ) als bouwstenen van productieregels. Elke productieregel bestaat uit een linkerkant en een rechterkant. De rechterkant is een mogelijk leeg rijtje terminals en nonterminals, en de linkerkant is altijd een nonterminal. Sterker nog: een grammaticaal symbool is dan en slechts dan een nonterminal als het de linkerkant van een productieregel is. Het idee is dat je precies alle geldige expressies kunt produceren als je met (een rijtje bestaande uit) de nonterminal exp begint, dan een nonterminal vervangt door één van diens rechterkanten en dat proces herhaalt tot alle nonterminals eruit zijn 14 : exp if exp then exp else exp fi if exp then exp plus exp else exp fi if true then exp plus exp else exp fi... if true then een plus twee else drie fi Dit is natuurlijk nog een enigszins abstracte versie van de geproduceerde expressie. Daarom zal er voor elke terminal ook nog zijn representatie gegeven zijn, waarmee deze expressie er uit gaat zien als Vandaar de term (non)terminal. 15 Hierin komen geen spaties voor omdat we die (nog) niet in de grammatica hebben gespecificeerd.

11 3 Herkenners 11 IFTRUETHEN1+2ELSE3FI Wij hebben de linker- en rechterkant van de productieregels gescheiden door een dubbele-punt, en elke regel afgesloten door een punt, maar er zijn allerlei notaties gangbaar. Soms worden de leden van de rechterkant gescheiden door komma s, en dan mogen er spaties in de namen van de (non)terminals voorkomen. Vaak worden productieregels met dezelfde linkerkant samengevoegd: de rechterkant bestaat dan uit de verzamelde rechterkanten (de zogenaamde alternatieven van de desbetreffende linkerkant), gescheiden door een puntkomma, of een vertikale streep: getal: een; twee; drie. Meestal schrijven we ook nog, in plaats van een terminal symbol, zijn representatie rechtstreeks op, tussen apostroffen. Daarmee kunnen we de grammatica voor onze expressietaal al een stuk completer opschrijven. expression: variable = exp ; expression; exp. exp: IF exp THEN exp ELSE exp FI ; ( exp ) ; exp op exp; variable; number; TRUE ; FALSE. variable: letter letdigs. letdigs: ; letter letdigs; digit letdigs. number: digit digits. digits: ; digit digits. letter: a ; b ; c ; d ; e ; f ; g ; h ; i ; j ; k ; l ; m ; n ; o ; p ; q ; r ; s ; t ; u ; v ; w ; x ; y ; z. digit: 0 ; 1 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7 ; 8 ; 9. op: + ; - ; * ; / ; ^ ; < ; <= ; > ; >= ; == ; <>. Deze grammatica heeft echter nog (minstens) 2 tekortkomingen: er is niet vastgelegd waar spaties mogen staan, en de typeringsregels zijn niet afgedwongen: bijvoorbeeld tussen IF en THEN kan gewoon een getal komen te staan. De layoutkwestie wordt vaak afzonderlijk geregeld. In dit geval zou je kunnen zeggen: aan elke terminal (en bestandseinde ) mogen spaties voorafgaan. Maar met behulp van een nonterminal space die een mogelijk leeg rijtje spaties produceert, kun je de layout ook precies in de grammatica vastleggen. De typering zou je kunnen regelen door onderscheid te maken tussen intexp en boolexp, en tussen intvariable en boolvariable, enzovoort. De grammatica wordt dan wel bijna twee keer zo groot. Overigens zullen we in hoofdstuk 6.2 zien dat contextvrije grammatica s ontoereikend zijn als de typering complexer wordt. Oefening Breid de gegeven grammatica aldus uit met layout en typering. 3.2 Een meer formele benadering Definitie Een contextvrije grammatica is een structuur (V, N, S, P ) waarin V een eindige verzameling symbolen is (een alfabet ), N V de nonterminals daarin, S N de startnonterminal en P N V een eindige verzameling productieregels. Hierin staat V voor de verzameling van eindige rijen van elementen van V, d.w.z. de kleinste verzameling met de eigenschap V = {ɛ V V, waarin ɛ de lege rij is en V W = {vw : v V w W. Zo n contextvrije grammatica beschrijft de taal

12 12 3 Herkenners {s (V \ N) : S s waarin de reflexieve transitieve afsluiting is van de relatie, gedefiniëerd als {(σaτ, σατ) V V : σ V τ V (A, α) P Oefening Behoort de rij zyxzy tot de taal beschreven door de volgende grammatica? ({s, t, x, y, z, {s, t, s, {(s, szs), (s, t), (t, ɛ), (t, x), (t, y)) Schrijf deze grammatica in de eerder in dit hoofdstuk gegeven notatie. Geef ook een zo beknopt mogelijke contextvrije grammatica voor de lege taal. Een rij α 0, α 1,..., α n (n 0) heet een afleiding als α i 1 α i (1 i n). Zo n rij wordt vaak geschreven als α 0 α 1... α n. Met een afleiding α β wordt een willekeurige afleiding bedoeld die begin met α en eindigt met β. Intermezzo Door de nonterminals op te vatten als variabelen, de terminals als verzamelingen van één element (hun represesentatie), de rechterkanten van productieregels als concatenatie van hun leden (met {ɛ als eenheidselement), voorts tussen de linker- en rechterkant een te zetten en de productieregels op te vatten als stelsel vergelijkingen met als oplossing de kleinste verzamelingen van rijen van (representaties van) terminals die aan die vergelijkingen voldoen, wordt S zelf de taal van de grammatica. Voor de grammatica van de voorlaatste oefening wordt dat stelsel dus s = (s {z s) t t = {ɛ {x {y Op de formele definitie is een uitgebreide theorie van contextvrije talen gebaseerd, waaraan we hier maar zeer ten dele aandacht zullen besteden. 16 Een (formele) taal is een deelverzameling van V, voor een alfabet V. De elementen van een taal worden wel zinnen genoemd. Een taal is contextvrij als-ie door een contextvrije grammatica kan worden beschreven. De theorie vertelt ons onder andere dat de klasse van contextvrije talen nogal klein is. Vrijwel geen enkele interessante taal blijkt contextvrij! Geen nood. Je definieert eerst een contextvrije superset van de beoogde taal, om de contextvrije aspecten van de taal vast te leggen en geeft dan via een ander formalisme nadere restricties, bijvoorbeeld met betrekking tot typering. Een typisch contextvrij aspect, om niet te zeggen het enige, is nesting (haakjesstructuren). In veel programmeertalen vind je de eis dat elke gebruikte variabele ook gedeclareerd moet zijn, wat neerkomt op de eis dat in zinnen van de vorm αxβxγ, waarin het aantal mogelijke producties van X alsmede de lengte van de productie van β niet beperkt zijn, beide voorkomens van X altijd dezelfde productie hebben. Dit kan niet contextvrij worden beschreven. 17 Dit is een onmiddellijk gevolg van het feit dat de producties contextvrij zijn: elke nonterminal kan ongeacht zijn context worden vervangen door één van zijn rechterkanten. Het meest wezenlijke aan een contextvrije grammatica is dus dat de linkerkant van elke productieregel uit precies één 16 Er is een omvangrijke literatuur over formele taaltheorie, o.a. M.A. Harrison, Introduction to Formal Language Theory, Addison-Wesley (1983). 17 Als de genoemde beperkingen er wel zijn kun je in theorie voor elk mogelijk geval een productieregel opschrijven.

13 3 Herkenners 13 nonterminal bestaat. Deze onmogelijkheid van contextvrije grammatica s om bepaalde overeenkomsten over willekeurig grote afstand voor te schrijven is ook de oorzaak van de beperkingen t.a.v. typering. Tot zover de belangrijkste resultaten van de theorie van contextvrije talen. We gaan nu proberen uit een gegeven contextvrije grammatica (V, N, S, P ) een herkenner te construeren, d.w.z. een programma dat van elk element in V zal vaststellen of het tot de beschreven taal hoort, of niet. Die herkenners zullen de basis vormen van de in verdere hoofdstukken te ontwikkelen vertalers. 3.3 Een recursive descent herkenner De definitie van contextvrije grammatica s suggereert een aanpak voor zo n herkenner. Minstens twee zelfs: een top-down methode, waarbij je naar de te herkennen zin toewerkt door, uitgaande van de rij die alléén het startsymbool bevat, telkens een nonterminal te vervangen door één van z n rechterkanten en een bottom-up methode, waarbij je naar het startsymbool toewerkt door, uitgaande van de zin, telkens een aaneengesloten vóórkomen van de rechterkant van een productieregel te vervangen door zijn linkerkant. Bottom-up methoden zijn krachtiger, maar ook iets moeilijker te begrijpen en te maken. Daarom kijken we eerst naar top-down methoden. De gesuggereerde algoritme is nog niet erg bruikbaar. We moeten om de haverklap een keuze maken: welke nonterminal moet worden vervangen, en door welke rechterkant? De eerste keuze is geen probleem: omdat de grammatica contextvrij is doet de keuze er namelijk helemaal niet toe. Om tot een terminale reeks te komen moeten we toch alle nonterminals vervangen, en ze kunnen elkáár niet wegkrijgen. Dus kiezen we steeds de eerste, of meest linkse. Als alles goed gaat is dan immers na verloop van tijd het eerste symbool een terminal en dat moet dan ook het eerste symbool van de te herkennen zin zijn. Zo ja, dan kunnen we die twee tegen elkaar wegstrepen en zo doorgaan tot de hele zin is afgevinkt. Zo niet, dan hoeven we (met deze afleiding) niet verder te gaan. Inderdaad: mits alles goed gaat. Maar het kán zijn dat er als eerste symbool een nonterminal verschijnt die dat al eerder was zonder dat er intussen terminals zijn afgevinkt en dan kan zich dat eindeloos herhalen. Definitie Een contextvrije grammatica (V, N, S, P ) heet linksrecursief, als X N, α, β V, u (V \ N) : S uxα + L uxβ (waarin + L de transitieve afsluiting is van L, gedefinieerd als {(uaτ, uατ) V V : u (V \ N) τ V (A, α) P ). Terminatie van top-down methoden is alleen gegarandeerd voor niet-linksrecursieve grammatica s. Overigens wijst de theorie uit dat er voor elke taal die wordt beschreven door een linksrecursieve grammatica ook een niet-linksrecursieve bestaat. Bovendien levert de theorie een aantal algoritmen voor linksrecursieverwijdering. In de praktijk is het meestal voldoende, de grammatica even kritisch te bekijken, en aan te passen. We zullen dat aanstonds doen met onze Simplexp-grammatica, die linksrecursief is. De tweede keuze is lastiger. We kunnen de keuze omzeilen en systematisch alle mogelijke keuzen vervolgen. We krijgen dan een backtracking recognizer, of varianten daarop. Zulke herkenners zijn in het algemeen erg inefficiënt Ze kunnen i.h.a. wel efficiënter worden gemaakt door een combinatie met de systematiek van vooruitkijken die hierna wordt beschreven.

14 14 3 Herkenners Wat ons rest is de volgende systematiek. Telkens wanneer de op dat moment meest linkse nonterminal X moet worden herschreven, wordt aan de hand van de terminals waarmee de (rest van de) te herkennen zin begint een eenduidige keuze gemaakt uit de beschikbare rechterkanten. We zullen dit eerst eens onderzoeken aan de hand onze concrete grammatica. Inspectie daarvan leert dat dit niet zonder slag of stoot gaat. Bekijk met name de nonterminal exp. Voor de meeste rechterkanten is de keuze gauw gemaakt: een number begint met een cijfer, een variable met een kleine letter, IF met een I, enzovoort. Alleen de rechterkant die begint met exp gooit roet in het eten, is zelfs linksrecursief! Het is evenwel niet moeilijk in te zien, dat die rechterkant ons vertelt dat een exp de structuur e op e op... op e heeft, waar elk van de één of meer e s gevormd is volgens één van de andere rechterkanten. Dat betekent, dat de nonterminal exp als volgt kan worden beregeld. 19 exp: e restexp. restexp: ; op e restexp. e: IF exp THEN exp ELSE exp FI ; ( exp ) ; variable; number; TRUE ; FALSE. Dit is overigens een voorbeeld van een (handmatig binnengesmokkelde) linksrecursieverwijdering, die ook het keuzeprobleem in principe oplost. Er is alleen één addertje binnengekropen: op grond waarvan kiezen we voor de lege rechterkant van restexp? Het antwoord is althans in dit geval duidelijk: als het eerstvolgende te herkennen teken een ;, bestandseinde, T, E, F of ) is. Dat zijn namelijk de tekens die na een exp, en dus een restexp kunnen komen. Ga dit na. Tenslotte is er ook nog een keuzeprobleem voor expression. Ook een exp kan met een variable beginnen. Dit kan op een aantal manieren worden opgelost, geen van alle erg elegant. Laten we het hier maar even zó doen: expression: variable expressiontail; nonvariable restexp. expressiontail: = exp ; expression; restexp. exp: e restexp. restexp: ; op e restexp. e: variable; nonvariable. nonvariable: IF exp THEN exp ELSE exp FI ; ( exp ) ; number; TRUE ; FALSE. Dit is een voorbeeld van een linksfactorisatie. Het is niet aan te bevelen grammatica s zelf zó te schrijven, omdat hun beschrijvende kracht erdoor achteruitholt. Daarom streven we naar krachtiger herkenningsmethoden (zie hoofdstuk 5.2) of transformatieprogramma s. Nu kunnen we (eindelijk) een systematische herkenner voor Simplexp schrijven. We schrijven daartoe voor elke nonterminal een eigen herkenner, volgens het volgende stramien: void restexp () { if (seeing_ahead (";TEF)") seeing_ahead_eof ()) { else if (seeing_ahead ("+-*/^<>=")) { op (); e (); restexp (); else { error ("Syntaxfout"); Een herkenner van dit type staat bekend als een recursive descent recognizer. Helaas zijn de 19 Wie zich hier ernstig zorgen begint te maken over de prioriteit van operatoren moet bedenken dat deze alleen relevant is voor de betekenis van de expressie.

15 3 Herkenners 15 eisen die we aan de grammatica moeten stellen om er zo n herkenner voor te kunnen schrijven, en die we straks preciezer zullen formuleren, nogal streng. Zó streng zelfs dat voor veel contextvrije talen geen grammatica te geven valt die aan die eisen voldoet. Opdracht 4 Schrijf een recursive descent herkenner voor Simplexp. 3.4 LL(k)-grammatica s We kunnen de contextvrije grammatica s waarvan de talen volgens dit stramien kunnen worden herkend nauwkeurig karakteriseren. Dit top-down stramien heet LL(k) hetgeen zoveel wil zeggen als recognizable while reading from Left to right, and rewriting Leftmost nonterminals, with k symbols lookahead. De populaire bottom-up tegenhanger is LR(k). 20 De methoden RR(k) en RL(k) worden nooit gebruikt. In de definitie van de LL(k)-eigenschap gebruiken we de onthoofd-operatie : N T waarin T een alfabet is: { t1 t k t 1 t n = n als n < k t 1 t k anders waarin t i T (1 i n) en een endmarker is die niet in V voorkomt, maar geacht wordt achter elke te lezen zin te staan. We zullen deze operatie ook toepassen op verzamelingen rijtjes: k L = {k w : w L. Definitie Een contextvrije grammatica (V, N, S, P ) met T = V \ N is een LL(k)-grammatica, als voor elk tweetal afleidingen S uxα uχα uv S uxα uξα uw en (met u, v, w T, α, χ, ξ V en X N) uit k v = k w volgt dat χ = ξ. Met andere woorden, de grammatica is LL(k) als hij zó in elkaar steekt dat er voor elke situatie waarin, in top-down stijl, 1 al een beginstuk u herkend is, 2 de eerste k symbolen (if any) van het vervolg bekend zijn, en 3 het begin van dat vervolg door een nonterminal X moet worden geproduceerd hoogstens één rechterkant van X daartoe in staat is. Het lijkt dus voor de hand te liggen, voor elke u T en (X, χ) P de richtverzamelingen k {v : α V : S uxα uχα uv te berekenen. Deze moeten disjunct zijn voor elk tweetal productieregels met dezelfde linkerkant en bepalen bij een k-lookahead de te gebruiken productieregel (if any). Helaas maakt de differentiatie naar linkercontext u T deze aanpak weinig praktisch! Daarom wordt de LL(k)-voorwaarde versterkt, door deze differentiatie te laten vallen: voor elke productieregel worden alle richtverzamelingen verenigd (waardoor de kans op overlap groter wordt). 20 Van links naar rechts, bottom-up lezend wordt steeds een rechterkant herschreven tot de bijbehorende linkerkant, die dan de meest rechtse nonterminal wordt. Zie verder hoofdstuk 5.2. Bij het evalueren van expressies van Simplexp hebben we ook zo n stramien gebruikt.

16 16 3 Herkenners Definitie Een contextvrije grammatica (V, N, S, P ) met T = V \ N is een sterke LL(k)-grammatica, als voor elk tweetal afleidingen S uxα uχα uv S zxβ zξβ zw en (met u, z, v, w T, α, β, χ, ξ V en X N) uit k v = k w volgt dat χ = ξ. Gelukkig kan worden bewezen dat elke LL(1)-grammatica ook een sterke LL(1)-grammatica is en het geval k = 1 wordt toch het meest gebruikt. Oefening Ga na dat de contextvrije grammatica met P = {(S, aaab), (S, babb), (A, a), (A, ɛ) wel LL(2), maar niet sterk LL(2) is. De richtverzameling k {v : α V, u T : S uxα uχα uv voor productieregel (X, χ) wordt overigens meestal berekend als FIRST k (χ FOLLOW k (X)), waarin FIRST k (α) = k {v T : α v FOLLOW k (α) = k {v T : u V : S uαv Voor algoritmen voor het berekenen van deze verzamelingen 21 verwijzen we naar de literatuur. In concrete gevallen laten ze zich meestal eenvoudig bepalen. Oefening Schrijf een LL(1)-grammatica die (algemene) contextvrije grammatica s beschrijft, d.w.z. alleen de productieregels in de niet-formele stijl zoals geïntroducerd in sectie 3.1 (dus o.a. met alternatieven). Construeer hieruit een recursive descent herkenner voor die grammatica s. Ook nu geldt weer dat een taal LL(k) is als hij door een LL(k)-grammatica kan worden beschreven. Overigens blijkt dat elke LL(k)-taal ook een LL(1)-taal is. (Een dergelijke eigenschap geldt niet voor LR(k)-talen.) 3.5 Lexical scanners In veel talen komen lexicale elementen voor ( tokens ), die uit een aantal karakters bestaan, maar toch een atomaire rol vervullen. Voorbeelden zijn samengestelde operatoren als <= of IF, namen van variabelen, getallen, etc. Deze tokens zijn er vaak de enige oorzaak van dat de betrokken grammatica niet LL(k) is, of niet LL(k) voor een bepaalde gewenste k. Het naast elkaar bestaan van de assignment-operator in de vorm = en de gelijkheidsoperator in de vorm == (i.h.a.: twee verschillende tokens met een gemeenschappelijke prefix van mogelijke onbepaalde lengte) was daarvan een voorbeeld. Ook was met onze oorspronkelijke grammatica voor Simplexp aan een kleine letter aan het begin van een nieuwe regel niet te zien is of naar het eerste dan wel het tweede alternatief van expression moest worden herschreven. Die grammatica was daardoor zelfs niet LL(k) voor enige k! Wij hebben dat tweede probleem kunnen oplossen door een linksfactorisatie, maar in het algemeen kan zo n probleem worden verholpen door de tokens tot terminals te degraderen. Vervolgens wordt de herkenner verrijkt met een scanner, ook wel lexical analyzer genoemd, die hij aanroept voor elk volgend benodigd token. Het kan zijn dat de scanner voor elk tokenklasse een aparte aanroep aanbiedt of één centrale aanroep die de gevonden klasse als resultaat levert 21 Deze algoritmen zijn voor het algemene geval net iets lastiger dan je zou denken.

17 3 Herkenners 17 (desgewenst samen met de concrete instantie, die nodig zal zijn als de herkenner een vertaler wordt). De inwendige structuur van tokens is bovendien meestal eenvoudiger-dan-contextvrij te beschrijven, namelijk door middel van reguliere expressies. Reguliere expressies zijn opgebouwd uit de lege rij ɛ, atomaire tekens (onze oorspronkelijke primitieve terminals), product (of concatenatie, genoteerd A B of AB, met reguliere expressies A en B), som (of keuze, genoteerd A + B, A B of A B), afsluiting (of herhaling, genoteerd A, recursief gedefinieerd als ɛ + A A ), en haakjes, met de gebruikelijke prioriteitsregels voor som en product. Met D = L = a+b+c+d+e+f +g+h+i+j +k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+z worden de number s van Simplexp gegeven door DD en de variable s door L(L + D). Dat reguliere expressies efficiënt door eindige automaten kunnen worden geïmplementeerd is een ander argument de tokens te laten afhandelen door een afzonderlijke scanner. Het is voorts gebruikelijk alle layout-kwesties (waar spaties mogen staan en waar niet) door de scanner te laten afhandelen. Bij gebruik van een scanner is de herkenner of vertaler vaak verrassend compact. Een formeel probleem is wel dat de verzameling terminals niet langer eindig is, maar wie daarop let is een kniesoor. Oefening Wijzig de Simplexp-herkenner zó dat op, number, variable, en hoofdletter-woorden, alsmede de layout, door een scanner worden herkend. Vragen 1 Als je spaties expliciet zou maken met behulp van een nonterminal space, zou je dan een algemene richtlijn kunnen geven waar die nonterminal in de grammatica zou moeten worden gebruikt? 2 Stel dat je de nonterminals intexp en boolexp zou invoeren zoals in de tekst gesuggereerd wordt. Wat worden dan de alternatieven van intexp? 3 In hoeverre is de eis dat de verzameling productieregels eindig is een formaliteit? 4 Laat zien dat de verzameling V van eindige rijtjes van elementen van V inderdaad de kleinste is die voldoet aan V = {ɛ V V. 5 Wat is de taal van de grammatica ({s, {s, s, {(s, ɛ))? 6 Is het zinvol te spreken over een linksrecursieve taal? 7 Het is ook mogelijk de elementaire recursive descent herkenners te schrijven als boolean functies, die geen foutmelding geven, maar terugkeren met FALSE. Wat wordt er anders in die herkenners? 8 Beschrijf de klasse van LL(0)-talen. 9 Waarom was de versie van Simplexp waarin beide alternatieven van expression met een variable konden beginnen niet LL(k) voor enige k? 10 Hoe kan de taal beschreven door de reguliere expressie a(b + c) in termen van (operaties op) verzamelingen worden weergegeven?

18 18 4 Transducers 4 Transducers Nu we de syntactisch correcte zinnen van een taal systematisch kunnen herkennen gaan we eveneens op een systematische manier aan die zinnen een betekenis of vertaling toekennen. Contextvrije grammatica s bouwen de zinnen hiërarchisch (recursief, inductief) op, bijvoorbeeld expressies opgebouwd uit deelexpressies. Het ligt voor de hand de betekenis van een zin op te bouwen langs dezelfde hiërarchie, d.w.z. compositioneel: de betekenis van een expressie wordt bepaald uit de betekenissen van zijn deelexpressies. Ter voorbereiding bespreken we eerst de notie van een ontleedboom (of parse tree of syntax tree). 4.1 Ontleedbomen Definitie Een ontleedboom van een contextvrije grammatica (V, N, S, P ) is een geordende boom met knopen H en een labeling l : H V {ε, waarin voor elke knoop h met kinderen h 1,..., h n (n > 0) geldt dat (l(h), l(h 1 )... l(h n )) P of, als n = 1 en l(h 1 ) = ε, (l(h), ɛ) P. De opbrengst (of yield) van een blad met label ε is de lege rij, de opbrengst van elk ander blad is diens label als singleton rij en de opbrengst van een knoop met kinderen h 1,..., h n (n > 0) is de rij y 1... y n waarin y i (1 i n) de opbrengst is van h i. Bijvoorbeeld exp exp op exp number digit digits + variable letter letdigs 1 ε a Definitie Een afleiding X m α met m 0, X N en α V correspondeert als volgt met een ontleedboom. Is m = 0 dan correspondeert hij met een boom bestaande uit één knoop, gelabeld X. Is m = 1 en α = ɛ dan correspondeert hij met een boom van twee knopen waarvan de wortel is gelabeld met X en het blad met ε. Anders kan de afleiding worden geschreven als X X 1... X n m 1 α 1... α n met n > 0, X i V, X i α i (1 i n). In dat geval correspondeert hij met een ontleedboom waarvan de wortel, die is gelabeld met X, n kinderen h 1,..., h n heeft zó dat h i (1 i n) de wortel is van een ontleedboom waarmee de afleiding X i α i correspondeert. De afleiding exp exp op exp exp op variable number op variable digit digits op variable digit digits + variable 1 digits + variable 1 digits + letter letdigs 1 digits + a letdigs 1 + a letdigs correspondeert met bovenstaande ontleedboom. Er zullen in het algemeen vele afleidingen zijn die corresponderen met dezelfde ontleedboom. Die afleidingen verschillen alleen in de volgorde waarin de nonterminals worden herschreven. Desgewenst kunnen, bijvoorbeeld, linkerafleidingen (waarbij steeds de meest linkse nonterminal wordt herschreven) worden gekozen als representanten van de aldus geïnduceerde equivalentieklassen. Ontleedbomen abstraheren dus van (de) niet-wezenlijke verschillen tussen afleidingen.

start -> id (k (f c s) (g s c)) -> k (f c s) (g s c) -> f c s -> s c

start -> id (k (f c s) (g s c)) -> k (f c s) (g s c) -> f c s -> s c Een Minimaal Formalisme om te Programmeren We hebben gezien dat Turing machines beschouwd kunnen worden als universele computers. D.w.z. dat iedere berekening met natuurlijke getallen die met een computer

Nadere informatie

Het omzetten van reguliere expressies naar eindige automaten, zie de vakken Fundamentele Informatica 1 en 2.

Het omzetten van reguliere expressies naar eindige automaten, zie de vakken Fundamentele Informatica 1 en 2. Datastructuren 2016 Programmeeropdracht 3: Patroonherkenning Deadlines. Woensdag 23 november 23:59, resp. vrijdag 9 december 23:59. Inleiding. Deze opdracht is gebaseerd op Hoofdstuk 13.1.7 in het boek

Nadere informatie

Onafhankelijke verzamelingen en Gewogen Oplossingen, door Donald E. Knuth, The Art of Computer Programming, Volume 4, Combinatorial Algorithms

Onafhankelijke verzamelingen en Gewogen Oplossingen, door Donald E. Knuth, The Art of Computer Programming, Volume 4, Combinatorial Algorithms Onafhankelijke verzamelingen en Gewogen Oplossingen, door Donald E. Knuth, The Art of Computer Programming, Volume 4, Combinatorial Algorithms Giso Dal (0752975) Pagina s 5 7 1 Deelverzameling Representatie

Nadere informatie

Automaten. Informatica, UvA. Yde Venema

Automaten. Informatica, UvA. Yde Venema Automaten Informatica, UvA Yde Venema i Inhoud Inleiding 1 1 Formele talen en reguliere expressies 2 1.1 Formele talen.................................... 2 1.2 Reguliere expressies................................

Nadere informatie

Uitleg van de Hough transformatie

Uitleg van de Hough transformatie Uitleg van de Hough transformatie Maarten M. Fokkinga, Joeri van Ruth Database groep, Fac. EWI, Universiteit Twente Versie van 17 mei 2005, 10:59 De Hough transformatie is een wiskundige techniek om een

Nadere informatie

1 Inleiding in Functioneel Programmeren

1 Inleiding in Functioneel Programmeren 1 Inleiding in Functioneel Programmeren door Elroy Jumpertz 1.1 Inleiding Aangezien Informatica een populaire minor is voor wiskundestudenten, leek het mij nuttig om een stukje te schrijven over een onderwerp

Nadere informatie

Lab Webdesign: Javascript 3 maart 2008

Lab Webdesign: Javascript 3 maart 2008 H5: OPERATORS In dit hoofdstuk zullen we het hebben over de operators (of ook wel: operatoren) in JavaScript waarmee allerlei rekenkundige en logische bewerkingen kunnen worden uitgevoerd. Daarbij zullen

Nadere informatie

Uitwerking tentamen Analyse van Algoritmen, 29 januari

Uitwerking tentamen Analyse van Algoritmen, 29 januari Uitwerking tentamen Analyse van Algoritmen, 29 januari 2007. (a) De buitenste for-lus kent N = 5 iteraties. Na iedere iteratie ziet de rij getallen er als volgt uit: i rij na i e iteratie 2 5 4 6 2 2 4

Nadere informatie

compileren & interpreteren - compileren: vertalen (omzetten) - interpreteren: vertolken

compileren & interpreteren - compileren: vertalen (omzetten) - interpreteren: vertolken compileren & interpreteren - compileren: vertalen (omzetten) - interpreteren: vertolken - belangrijkste punten: - ontleden van de programmatekst - bijhouden van de datastructuren Data Structuren en Algoritmen

Nadere informatie

Talen & Automaten. Wim Hesselink Piter Dykstra Opleidingsinstituut Informatica en Cognitie 9 mei 2008

Talen & Automaten. Wim Hesselink Piter Dykstra Opleidingsinstituut Informatica en Cognitie   9 mei 2008 Talen & Automaten Wim Hesselink Piter Dykstra Opleidingsinstituut Informatica en Cognitie www.cs.rug.nl/~wim 9 mei 2008 Talen & automaten Week 1: Inleiding Dit college Talen Automaten Berekenbaarheid Weekoverzicht

Nadere informatie

Syntax- (compile), runtime- en logische fouten Binaire operatoren

Syntax- (compile), runtime- en logische fouten Binaire operatoren Inhoud Syntax- (compile), runtime- en logische fouten Binaire operatoren Operaties op numerieke datatypen Evaluatie van expressies, bindingssterkte Assignment operaties en short-cut operatoren Controle

Nadere informatie

Deeltentamen Grammatica s en ontleden 22 december 2005

Deeltentamen Grammatica s en ontleden 22 december 2005 Tentamen Grammatica s en ontleden 22 december 2005 1 Deeltentamen Grammatica s en ontleden 22 december 2005 Let op: opgave 1 t/m 4 tellen voor (slechts) 5 punten mee, opgave 5 voor maar liefst 50 punten,

Nadere informatie

17 Operaties op bits. 17.1 Bitoperatoren en bitexpressies

17 Operaties op bits. 17.1 Bitoperatoren en bitexpressies 17 Operaties op bits In hoofdstuk 1 is gezegd dat C oorspronkelijk bedoeld was als systeemprogrammeertaal om het besturingssysteem UNIX te implementeren. Bij dit soort toepassingen komt het voor dat afzonderlijke

Nadere informatie

Combinatorische Algoritmen: Binary Decision Diagrams, Deel III

Combinatorische Algoritmen: Binary Decision Diagrams, Deel III Combinatorische Algoritmen: Binary Decision Diagrams, Deel III Sjoerd van Egmond LIACS, Leiden University, The Netherlands svegmond@liacs.nl 2 juni 2010 Samenvatting Deze notitie beschrijft een nederlandse

Nadere informatie

1 Rekenen in eindige precisie

1 Rekenen in eindige precisie Rekenen in eindige precisie Een computer rekent per definitie met een eindige deelverzameling van getallen. In dit hoofdstuk bekijken we hoe dit binnen een computer is ingericht, en wat daarvan de gevolgen

Nadere informatie

Als een PSD selecties bevat, deelt de lijn van het programma zich op met de verschillende antwoorden op het vraagstuk.

Als een PSD selecties bevat, deelt de lijn van het programma zich op met de verschillende antwoorden op het vraagstuk. HOOFDSTUK 3 3.1 Stapsgewijs programmeren In de vorige hoofdstukken zijn programmeertalen beschreven die imperatief zijn. is het stapsgewijs in code omschrijven wat een programma moet doen, net als een

Nadere informatie

Rekenen aan wortels Werkblad =

Rekenen aan wortels Werkblad = Rekenen aan wortels Werkblad 546121 = Vooraf De vragen en opdrachten in dit werkblad die vooraf gegaan worden door, moeten schriftelijk worden beantwoord. Daarbij moet altijd duidelijk zijn hoe de antwoorden

Nadere informatie

HOOFDSTUK 3. Imperatief programmeren. 3.1 Stapsgewijs programmeren. 3.2 If Then Else. Module 4 Programmeren

HOOFDSTUK 3. Imperatief programmeren. 3.1 Stapsgewijs programmeren. 3.2 If Then Else. Module 4 Programmeren HOOFDSTUK 3 3.1 Stapsgewijs programmeren De programmeertalen die tot nu toe genoemd zijn, zijn imperatieve of procedurele programmeertalen. is het stapsgewijs in code omschrijven wat een programma moet

Nadere informatie

Variabelen en statements in ActionScript

Variabelen en statements in ActionScript Ontwikkelen van Apps voor ios en Android Variabelen en statements in ActionScript 6.1 Inleiding Als we het in de informatica over variabelen hebben, bedoelen we een stukje in het geheugen van de computer

Nadere informatie

Programmeren A. Genetisch Programma voor het Partitie Probleem. begeleiding:

Programmeren A. Genetisch Programma voor het Partitie Probleem. begeleiding: Programmeren A Genetisch Programma voor het Partitie Probleem begeleiding: Inleiding Het Partitie Probleem luidt als volgt: Gegeven een verzameling van n positieve integers, vindt twee disjuncte deelverzamelingen

Nadere informatie

10 Meer over functies

10 Meer over functies 10 Meer over functies In hoofdstuk 5 hebben we functies uitgebreid bestudeerd. In dit hoofdstuk bekijken we drie andere aspecten van functies: recursieve functies dat wil zeggen, functies die zichzelf

Nadere informatie

Programmeermethoden. Recursie. week 11: november kosterswa/pm/

Programmeermethoden. Recursie. week 11: november kosterswa/pm/ Programmeermethoden Recursie week 11: 21 25 november 2016 www.liacs.leidenuniv.nl/ kosterswa/pm/ 1 Pointers Derde programmeeropgave 1 Het spel Gomoku programmeren we als volgt: week 1: pointerpracticum,

Nadere informatie

Automaten & Complexiteit (X )

Automaten & Complexiteit (X ) Automaten & Complexiteit (X 401049) Inleiding Jeroen Keiren j.j.a.keiren@vu.nl VU University Amsterdam Materiaal Peter Linz An Introduction to Formal Languages and Automata (5th edition) Jones and Bartlett

Nadere informatie

PYTHON REEKS 1: BASICS. Mathias Polfliet

PYTHON REEKS 1: BASICS. Mathias Polfliet PYTHON REEKS 1: BASICS Mathias Polfliet mpolflie@etrovub.be EENVOUDIGE REKENMACHINE 2 soorten getallen Getallen Z -> integers (gehele getallen) Getallen R -> floating points (reële getallen) Door beperkte

Nadere informatie

Datastructuren Programmeeropdracht 3: Expressies. 1 Expressies. Deadline. Dinsdag 8 december 23:59.

Datastructuren Programmeeropdracht 3: Expressies. 1 Expressies. Deadline. Dinsdag 8 december 23:59. Datastructuren 2015 Programmeeropdracht 3: Expressies Deadline. Dinsdag 8 december 23:59. Inleiding. Deze opdracht is losjes gebaseerd op Opdracht 5.13.2 in het boek van Drozdek. U wordt gevraagd expressies

Nadere informatie

Uitgebreide uitwerking Tentamen Complexiteit, mei 2007

Uitgebreide uitwerking Tentamen Complexiteit, mei 2007 Uitgebreide uitwerking Tentamen Complexiteit, mei 007 Opgave. a. Een beslissingsboom beschrijft de werking van het betreffende algoritme (gebaseerd op arrayvergelijkingen) op elke mogelijke invoer. In

Nadere informatie

7 Omzetten van Recursieve naar Iteratieve Algoritmen

7 Omzetten van Recursieve naar Iteratieve Algoritmen 7 Omzetten van Recursieve naar Iteratieve Algoritmen Het lijkt mogelijk om elke oplossings-algoritme, die vaak in eerste instantie recursief geformuleerd werd, om te zetten in een iteratieve algoritme

Nadere informatie

RuG-Informatica-cursus Discrete Structuren, versie 2009/2010

RuG-Informatica-cursus Discrete Structuren, versie 2009/2010 RuG-Informatica-cursus Discrete Structuren, versie 2009/2010 Handout 2B Jan Terlouw woensdag 17 februari 2010 Deze handout sluit aan op handout 2A van maandag 15 februari. De gepresenteerde stof valt grotendeels

Nadere informatie

BEGINNER JAVA Inhoudsopgave

BEGINNER JAVA Inhoudsopgave Inhoudsopgave 6 Configuratie Hallo wereld! Praten met de gebruiker Munt opgooien Voorwaarden Lussen......6 Configuratie Met deze Sushi kaarten ga je een simpel spel maken met één van de meest populaire

Nadere informatie

Tentamen Compilers (2M220) 19 maart 2002, 9.00u-12.00u

Tentamen Compilers (2M220) 19 maart 2002, 9.00u-12.00u 12/k Tentamen Compilers (2M220) 19 maart 2002, 9.00u-12.00u 1. Beschouw de volgende deelverzameling van de ASCII-karakters V = { 0, 1,..., 9, A, B,..., Y, Z, a, b,..., y, z } De karakters in V staan vermeld

Nadere informatie

Programmeermethoden NA. Week 5: Functies (vervolg)

Programmeermethoden NA. Week 5: Functies (vervolg) Programmeermethoden NA Week 5: Functies (vervolg) Kristian Rietveld http://liacs.leidenuniv.nl/~rietveldkfd/courses/prna/ Bij ons leer je de wereld kennen 1 Functies Vorige week bekeken we functies: def

Nadere informatie

FP-theorie. 2IA50, Deel B. Inductieve definities 1/19. / department of mathematics and computer science

FP-theorie. 2IA50, Deel B. Inductieve definities 1/19. / department of mathematics and computer science FP-theorie 2IA50, Deel B Inductieve definities 1/19 Inductieve definitie Definitie IL α, (Cons-)Lijsten over α Zij α een gegeven verzameling. De verzameling IL α van eindige (cons-)lijsten over α is de

Nadere informatie

colleges recursieve datastructuren college 9 prioriteit van operatoren prioriteit in recursive descent parser

colleges recursieve datastructuren college 9 prioriteit van operatoren prioriteit in recursive descent parser colleges recursieve datastructuren college 9 interpreteren: waarde van bomen bepalen transformeren: vorm van bomen veranderen parseren herkennen van expressie in de tekst herkennen van functies onderwerp

Nadere informatie

1 Delers 1. 3 Grootste gemene deler en kleinste gemene veelvoud 12

1 Delers 1. 3 Grootste gemene deler en kleinste gemene veelvoud 12 Katern 2 Getaltheorie Inhoudsopgave 1 Delers 1 2 Deelbaarheid door 2, 3, 5, 9 en 11 6 3 Grootste gemene deler en kleinste gemene veelvoud 12 1 Delers In Katern 1 heb je geleerd wat een deler van een getal

Nadere informatie

VERZAMELINGEN EN AFBEELDINGEN

VERZAMELINGEN EN AFBEELDINGEN I VERZAMELINGEN EN AFBEELDINGEN Het begrip verzameling kennen we uit het dagelijks leven: een bibliotheek bevat een verzameling van boeken, een museum een verzameling van kunstvoorwerpen. We kennen verzamelingen

Nadere informatie

Controle structuren. Keuze. Herhaling. Het if statement. even1.c : testen of getal even of oneven is. statement1 statement2

Controle structuren. Keuze. Herhaling. Het if statement. even1.c : testen of getal even of oneven is. statement1 statement2 Controle structuren De algemene vorm: 1 bloks door middel van indentatie Keuze Herhaling if expressie :...... In de volgende vorm is het else gedeelte weggelaten: if expressie :... Het if keuze- of conditioneel

Nadere informatie

Programmeermethoden NA. Week 5: Functies (vervolg)

Programmeermethoden NA. Week 5: Functies (vervolg) Programmeermethoden NA Week 5: Functies (vervolg) Kristian Rietveld http://liacs.leidenuniv.nl/~rietveldkfd/courses/prna2016/ Functies Vorige week bekeken we functies: def bereken(a, x): return a * (x

Nadere informatie

College Notatie, Recursie, Lijsten

College Notatie, Recursie, Lijsten College 2016-2017 2. Notatie, Recursie, Lijsten Doaitse Swierstra (Jeroen Bransen) Utrecht University September 13, 2016 Functieapplicatie functieapplicatie associeert naar links: als x in f x y moet kiezen

Nadere informatie

3 De stelling van Kleene

3 De stelling van Kleene 18 3 De stelling van Kleene Definitie 3.1 Een formele taal heet regulier als hij wordt herkend door een deterministische eindige automaat. Talen van de vorm L(r) met r een reguliere expressie noemen we

Nadere informatie

Honours projecten BSc Informatica: twee voorstellen

Honours projecten BSc Informatica: twee voorstellen Honours projecten BSc Informatica: twee voorstellen mogelijk ook geschikt voor BSc Kunstmatige Intelligentie Alban Ponse section Theory of Computer Science Informatics Institute, University of Amsterdam

Nadere informatie

Reguliere Expressies

Reguliere Expressies Reguliere Expressies Een reguliere expressie (regexp, regex, regxp) is een string (een woord) die, volgens bepaalde syntaxregels, een verzameling strings (een taal) beschrijft Reguliere expressies worden

Nadere informatie

Tentamen Compilers (2IC25) 21 juni 2010, 9.00u-12.00u

Tentamen Compilers (2IC25) 21 juni 2010, 9.00u-12.00u Tentamen Compilers (2IC25) 21 juni 2010, 9.00u-12.00u 1. Beschouw de reguliere expressie e = (a (a b) ) c (Er mag geen materiaal worden geraadpleegd.) (De TL-interpretator is als bijlage toegevoegd.) Faculteit

Nadere informatie

Opdracht 1 Topics on Parsing and Formal Languages - fall 2010

Opdracht 1 Topics on Parsing and Formal Languages - fall 2010 Opdracht 1 Topics on Parsing and Formal Languages - fall 2010 Rick van der Zwet 8 december 2010 Samenvatting Dit schrijven zal uitwerkingen van opgaven behandelen uit het boek [JS2009]

Nadere informatie

Examen Datastructuren en Algoritmen II

Examen Datastructuren en Algoritmen II Tweede bachelor Informatica Academiejaar 2016 2017, eerste zittijd Examen Datastructuren en Algoritmen II Naam :.............................................................................. Lees de hele

Nadere informatie

Automaten en Berekenbaarheid 2016 Oplossingen #4

Automaten en Berekenbaarheid 2016 Oplossingen #4 Automaten en Berekenbaarheid 2016 Oplossingen #4 28 oktober 2016 Vraag 1: Toon aan dat de klasse van context vrije talen gesloten is onder concatenatie en ster. Antwoord Meerdere manieren zijn mogelijk:

Nadere informatie

Formeel Denken. Herfst 2004

Formeel Denken. Herfst 2004 Formeel Denken Herman Geuvers Deels gebaseerd op het herfst 2002 dictaat van Henk Barendregt en Bas Spitters, met dank aan het Discrete Wiskunde dictaat van Wim Gielen Herfst 2004 Contents 1 Talen 1 1.1

Nadere informatie

Combinatoriek groep 1 & 2: Recursie

Combinatoriek groep 1 & 2: Recursie Combinatoriek groep 1 & : Recursie Trainingsweek juni 008 Inleiding Bij een recursieve definitie van een rij wordt elke volgende term berekend uit de vorige. Een voorbeeld van zo n recursieve definitie

Nadere informatie

Constanten. Variabelen. Expressies. Variabelen. Constanten. Voorbeeld : varid.py. een symbolische naam voor een object.

Constanten. Variabelen. Expressies. Variabelen. Constanten. Voorbeeld : varid.py. een symbolische naam voor een object. een symbolische naam voor een object. Variabelen Constanten Variabelen Expressies naam : geeft de plaats in het geheugen aan waarde : de inhoud van het object identifier : een rij van letters en/of cijfers

Nadere informatie

Maak automatisch een geschikte configuratie van een softwaresysteem;

Maak automatisch een geschikte configuratie van een softwaresysteem; Joost Vennekens joost.vennekens@kuleuven.be Technologiecampus De Nayer We zijn geïnteresseerd in het oplossen van combinatorische problemen, zoals bijvoorbeeld: Bereken een lessenrooster die aan een aantal

Nadere informatie

Modelleren en Programmeren

Modelleren en Programmeren Modelleren en Programmeren Jeroen Bransen 13 november 2015 Expressies Functies Ingebouwde functies Variabelenbereik Inleveropgave 1 Terugblik Programma is een lijst van opdrachten Terugblik Programma is

Nadere informatie

Vierde college complexiteit. 26 februari Beslissingsbomen en selectie Toernooimethode Adversary argument

Vierde college complexiteit. 26 februari Beslissingsbomen en selectie Toernooimethode Adversary argument Complexiteit 2019/04 College 4 Vierde college complexiteit 26 februari 2019 Beslissingsbomen en selectie Toernooimethode Adversary argument 1 Complexiteit 2019/04 Zoeken: samengevat Ongeordend lineair

Nadere informatie

Automaten & Complexiteit (X )

Automaten & Complexiteit (X ) Automaten & Complexiteit (X 401049) Beschrijven van reguliere talen Jeroen Keiren j.j.a.keiren@gmail.com VU University Amsterdam 5 Februari 2015 Talen Vorig college: Talen als verzamelingen Eindige automaten:

Nadere informatie

Gödels theorem An Incomplete Guide to Its Use and Abuse, Hoofdstuk 3

Gödels theorem An Incomplete Guide to Its Use and Abuse, Hoofdstuk 3 Gödels theorem An Incomplete Guide to Its Use and Abuse, Hoofdstuk 3 Koen Rutten, Aris van Dijk 30 mei 2007 Inhoudsopgave 1 Verzamelingen 2 1.1 Definitie................................ 2 1.2 Eigenschappen............................

Nadere informatie

Inhoud eindtoets. Eindtoets. Introductie 2. Opgaven 3. Terugkoppeling 6

Inhoud eindtoets. Eindtoets. Introductie 2. Opgaven 3. Terugkoppeling 6 Inhoud eindtoets Eindtoets Introductie 2 Opgaven 3 Terugkoppeling 6 1 Formele talen en automaten Eindtoets I N T R O D U C T I E Deze eindtoets is bedoeld als voorbereiding op het tentamen van de cursus

Nadere informatie

Een korte samenvatting van enkele FORTRAN opdrachten

Een korte samenvatting van enkele FORTRAN opdrachten Een korte samenvatting van enkele FORTRAN opdrachten Inhoud 1 Introductie 3 2 De structuur van een FORTRAN programma 3 3 Datatypen, variabelen en declaraties 3 4 Expressies-volgorde van uitwerking 4 5

Nadere informatie

Honours projecten BSc Informatica: twee voorstellen

Honours projecten BSc Informatica: twee voorstellen Honours projecten BSc Informatica: twee voorstellen mogelijk ook geschikt voor BSc Kunstmatige Intelligentie Alban Ponse section Theory of Computer Science Informatics Institute, University of Amsterdam

Nadere informatie

Opdracht 1 Topics on Parsing and Formal Languages - fall 2010

Opdracht 1 Topics on Parsing and Formal Languages - fall 2010 Opdracht 1 Topics on Parsing and Formal Languages - fall 2010 Rick van der Zwet 13 november 2010 Samenvatting Dit schrijven zal uitwerkingen van opgaven behandelen uit het boek [JS2009]

Nadere informatie

2. Syntaxis en semantiek

2. Syntaxis en semantiek 2. Syntaxis en semantiek In dit hoofdstuk worden de begrippen syntaxis en semantiek behandeld. Verder gaan we in op de fouten die hierin gemaakt kunnen worden en waarom dit in de algoritmiek zo desastreus

Nadere informatie

c, X/X a, c/λ a, X/aX b, X/X

c, X/X a, c/λ a, X/aX b, X/X ANTWOORDEN tentamen FUNDAMENTELE INFORMATICA 3 vrijdag 25 januari 2008, 10.00-13.00 uur Opgave 1 L = {x {a,b,c} n a (x) n b (x)} {x {a,b,c} n a (x) n c (x)}. a. Een stapelautomaat die L accepteert: Λ,

Nadere informatie

Achtste college algoritmiek. 8 april Dynamisch Programmeren

Achtste college algoritmiek. 8 april Dynamisch Programmeren Achtste college algoritmiek 8 april 2016 Dynamisch Programmeren 1 Werkcollege-opgave Dutch Flag Problem Gegeven een array gevuld met R, W, en B. Reorganiseer dit array zo dat van links naar rechts eerst

Nadere informatie

College Introductie

College Introductie College 2016-2017 Introductie Doaitse Swierstra (Jeroen Bransen) Utrecht University September 13, 2016 Waarom is FP anders? in plaats van opdrachten die na elkaar moeten worden uitgevoerd, definiëren we

Nadere informatie

Algoritmiek. 8 uur college, zelfwerkzaamheid. Doel. Hoe te realiseren

Algoritmiek. 8 uur college, zelfwerkzaamheid. Doel. Hoe te realiseren Algoritmiek Doel Gevoel en inzicht ontwikkelen voor het stapsgewijs, receptmatig oplossen van daartoe geëigende [biologische] probleemstellingen, en dat inzicht gebruiken in het vormgeven van een programmeerbare

Nadere informatie

Verzamelingen deel 2. Tweede college

Verzamelingen deel 2. Tweede college 1 Verzamelingen deel 2 Tweede college herhaling Deelverzameling: AB wil zeggen dat elk element van A ook in B te vinden is: als x A dan x B Er geldt: A=B AB en BA De lege verzameling {} heeft geen elementen.

Nadere informatie

Modelleren en Programmeren

Modelleren en Programmeren Modelleren en Programmeren Jeroen Bransen 11 december 2015 Ingebouwde datastructuren Meer boomstructuren Access specifiers Gebruikersinvoer Codestijl Packages SAT-solver Ingebouwde datastructuren Ingebouwde

Nadere informatie

3 Wat is een stelsel lineaire vergelijkingen?

3 Wat is een stelsel lineaire vergelijkingen? In deze les bekijken we de situatie waarin er mogelijk meerdere vergelijkingen zijn ( stelsels ) en meerdere variabelen, maar waarin elke vergelijking er relatief eenvoudig uitziet, namelijk lineair is.

Nadere informatie

1 Recurrente betrekkingen

1 Recurrente betrekkingen WIS1 1 1 Recurrente betrekkingen 1.1 De torens van Hanoi De torens van Hanoi Edouard Lucas, 1884: Gegeven 3 pinnen en 64 schijven van verschillende grootte. Startsituatie: 64 op linkerpin, geordend naar

Nadere informatie

Zelftest Inleiding Programmeren

Zelftest Inleiding Programmeren Zelftest Inleiding Programmeren Document: n0824test.fm 22/01/2013 ABIS Training & Consulting P.O. Box 220 B-3000 Leuven Belgium TRAINING & CONSULTING INLEIDING BIJ DE ZELFTEST INLEIDING PROGRAMMEREN Deze

Nadere informatie

Programmeermethoden. Recursie. Walter Kosters. week 11: november kosterswa/pm/

Programmeermethoden. Recursie. Walter Kosters. week 11: november kosterswa/pm/ Programmeermethoden Recursie Walter Kosters week 11: 20 24 november 2017 www.liacs.leidenuniv.nl/ kosterswa/pm/ 1 Vierde programmeeropgave 1 De Grote getallen programmeren we als volgt: week 1: pointerpracticum,

Nadere informatie

Bouwstenen voor PSE. Datatypes en Datastructuren

Bouwstenen voor PSE. Datatypes en Datastructuren Bouwstenen voor PSE Datatypes en Datastructuren Definitie Datatype Klasse van dataobjecten tesamen met operaties om ze te construeren, te manipuleren en te verwijderen. Een datatype omvat een specificatie

Nadere informatie

Over binaire beslissingsdiagrammen naar Donald E. Knuth s The Art of Computer Programming, Volume 4

Over binaire beslissingsdiagrammen naar Donald E. Knuth s The Art of Computer Programming, Volume 4 Over binaire beslissingsdiagrammen naar Donald E. Knuth s The Art of Computer Programming, Volume 4 Jonathan K. Vis 1 Inleiding (blz. 70 72) In dit essay behandelen we bladzijden 70 75 van Donald E. Knuth

Nadere informatie

Vorig college. IN2505-II Berekenbaarheidstheorie College 4. Opsommers versus herkenners (Th. 3.21) Opsommers

Vorig college. IN2505-II Berekenbaarheidstheorie College 4. Opsommers versus herkenners (Th. 3.21) Opsommers Vorig college College 4 Algoritmiekgroep Faculteit EWI TU Delft Vervolg NDTM s Vergelijking rekenkracht TM s en NDTM s Voorbeelden NDTM s 20 april 2009 1 2 Opsommers Opsommers versus herkenners (Th. 3.21)

Nadere informatie

Small Basic Programmeren Text Console 2

Small Basic Programmeren Text Console 2 Oefening 1: Hoogste getal Je leest een reeks positieve gehele getallen in totdat je het getal 0 (nul) invoert. Daarna stopt de invoer en druk je een regel af met het hoogste getal uit de reeks. Voorbeeld:

Nadere informatie

II. ZELFGEDEFINIEERDE FUNCTIES

II. ZELFGEDEFINIEERDE FUNCTIES II. ZELFGEDEFINIEERDE FUNCTIES In Excel bestaat reeds een uitgebreide reeks van functies zoals SOM, GEMIDDELDE, AFRONDEN, NU enz. Het is de bedoeling om functies aan deze lijst toe te voegen door in Visual

Nadere informatie

IN2505 II Berekenbaarheidstheorie Tentamen Maandag 2 juli 2007, uur

IN2505 II Berekenbaarheidstheorie Tentamen Maandag 2 juli 2007, uur TECHNISCHE UNIVERSITEIT DELFT Faculteit Elektrotechniek, Wiskunde en Informatica Mekelweg 4 2628 CD Delft IN2505 II Berekenbaarheidstheorie Tentamen Maandag 2 juli 2007, 14.00-17.00 uur BELANGRIJK Beschikbare

Nadere informatie

TENTAMEN Basismodellen in de Informatica VOORBEELDUITWERKING

TENTAMEN Basismodellen in de Informatica VOORBEELDUITWERKING TENTAMEN Basismodellen in de Informatica vakcode: 211180 datum: 2 juli 2009 tijd: 9:00 12:30 uur VOORBEELDUITWERKING Algemeen Bij dit tentamen mag gebruik worden gemaakt van het boek van Sudkamp, van de

Nadere informatie

Het minimale aantal sleutels op niveau h is derhalve

Het minimale aantal sleutels op niveau h is derhalve 1 (a) In een B-boom van orde m bevat de wortel minimaal 1 sleutel en maximaal m 1 sleutels De andere knopen bevatten minimaal m 1 sleutels en maximaal m 1 sleutels (b) In een B-boom van orde 5 bevat elke

Nadere informatie

OEFENINGEN PYTHON REEKS 1

OEFENINGEN PYTHON REEKS 1 Vraag 1: Expressies & Types OEFENINGEN PYTHON REEKS 1 Python maakt gebruik van enkele vaak voorkomende (data)types. Zo zijn er integers die behoren tot de gehele getallen (VB: 3), zijn er float s die behoren

Nadere informatie

Inleiding Programmeren 2

Inleiding Programmeren 2 Inleiding Programmeren 2 Gertjan van Noord November 26, 2018 Stof week 3 nogmaals Zelle hoofdstuk 8 en recursie Brookshear hoofdstuk 5: Algoritmes Datastructuren: tuples Een geheel andere manier om te

Nadere informatie

Zoemzinnen. Algemene info. Functies met een variabel aantal argumenten

Zoemzinnen. Algemene info. Functies met een variabel aantal argumenten Zoemzinnen Functies met een variabel aantal argumenten Bij het definiëren van een functie leg je in principe vast hoeveel argumenten er aan de functie moeten doorgegeven worden. Dit aantal correspondeert

Nadere informatie

3. Structuren in de taal

3. Structuren in de taal 3. Structuren in de taal In dit hoofdstuk behandelen we de belangrijkst econtrolestructuren die in de algoritmiek gebruikt worden. Dit zijn o.a. de opeenvolging, selectie en lussen (herhaling). Vóór we

Nadere informatie

recursie Hoofdstuk 5 Studeeraanwijzingen De studielast van deze leereenheid bedraagt circa 6 uur. Terminologie

recursie Hoofdstuk 5 Studeeraanwijzingen De studielast van deze leereenheid bedraagt circa 6 uur. Terminologie Hoofdstuk 5 Recursion I N T R O D U C T I E Veel methoden die we op een datastructuur aan kunnen roepen, zullen op een recursieve wijze geïmplementeerd worden. Recursie is een techniek waarbij een vraagstuk

Nadere informatie

rij karakters scanner rij tokens parser ontleedboom (filteren separatoren) (niet expliciet geconstrueerd) (+ add. inform.) (contextvrije analyse)

rij karakters scanner rij tokens parser ontleedboom (filteren separatoren) (niet expliciet geconstrueerd) (+ add. inform.) (contextvrije analyse) scanning and parsing 1/57 rij karakters scanner (filteren separatoren) rij tokens (+ add. inform.) (niet expliciet geconstrueerd) parser (contextvrije analyse) ontleedboom (parse tree) representeert syntactische

Nadere informatie

Getallensystemen, verzamelingen en relaties

Getallensystemen, verzamelingen en relaties Hoofdstuk 1 Getallensystemen, verzamelingen en relaties 1.1 Getallensystemen 1.1.1 De natuurlijke getallen N = {0, 1, 2, 3,...} N 0 = {1, 2, 3,...} 1.1.2 De gehele getallen Z = {..., 4, 3, 2, 1, 0, 1,

Nadere informatie

Recursion. Introductie 37. Leerkern 37. Terugkoppeling 40. Uitwerking van de opgaven 40

Recursion. Introductie 37. Leerkern 37. Terugkoppeling 40. Uitwerking van de opgaven 40 Recursion Introductie 37 Leerkern 37 5.1 Foundations of recursion 37 5.2 Recursive analysis 37 5.3 Applications of recursion 38 Terugkoppeling 40 Uitwerking van de opgaven 40 Hoofdstuk 5 Recursion I N

Nadere informatie

Numerieke benadering van vierkantwortels

Numerieke benadering van vierkantwortels HP Prime Grafische Rekenmachine Numerieke benadering van vierkantwortels Doel: De waarde van een vierkantswortel met een recursieve rij benaderen, het schrijven van een klein programma. Sleutelwoorden:

Nadere informatie

Datastructuren Uitwerking jan

Datastructuren Uitwerking jan Datastructuren Uitwerking jan 2015 1 1a. Een abstracte datastructuur is een beschrijving van een datastructuur, met de specificatie van wat er opgeslagen wordt (de data en hun structuur) en welke operaties

Nadere informatie

Uitwerking tentamen Algoritmiek 10 juni :00 13:00

Uitwerking tentamen Algoritmiek 10 juni :00 13:00 Uitwerking tentamen Algoritmiek 10 juni 2014 10:00 13:00 1. Dominono s a. Toestanden: n x n bord met in elk hokje een O, een X of een -. Hierbij is het aantal X gelijk aan het aantal O of hooguit één hoger.

Nadere informatie

RSA. F.A. Grootjen. 8 maart 2002

RSA. F.A. Grootjen. 8 maart 2002 RSA F.A. Grootjen 8 maart 2002 1 Delers Eerst wat terminologie over gehele getallen. We zeggen a deelt b (of a is een deler van b) als b = qa voor een of ander geheel getal q. In plaats van a deelt b schrijven

Nadere informatie

9 Meer over datatypen

9 Meer over datatypen 9 Meer over datatypen We hebben al gezien dat het gebruik van symbolische constanten de leesbaarheid van een programma kan verbeteren. Door een geschikte naam (identifier) voor een constante te definiëren,

Nadere informatie

Tiende college algoritmiek. 26 april Gretige algoritmen

Tiende college algoritmiek. 26 april Gretige algoritmen Algoritmiek 01/10 College 10 Tiende college algoritmiek april 01 Gretige algoritmen 1 Algoritmiek 01/10 Muntenprobleem Gegeven onbeperkt veel munten van d 1,d,...d m eurocent, en een te betalen bedrag

Nadere informatie

Tiende college algoritmiek. 14 april Gretige algoritmen

Tiende college algoritmiek. 14 april Gretige algoritmen College 10 Tiende college algoritmiek 1 april 011 Gretige algoritmen 1 Greedy algorithms Greed = hebzucht Voor oplossen van optimalisatieproblemen Oplossing wordt stap voor stap opgebouwd In elke stap

Nadere informatie

rh276a 0 We breiden nu bovenstaand programmafragment uit door assignments toe te voegen aan een nieuwe variabele m, aldus:

rh276a 0 We breiden nu bovenstaand programmafragment uit door assignments toe te voegen aan een nieuwe variabele m, aldus: rh276a 0 Een paar praktische stellinkjes 0 Standaardeindiging stelling (standaardeindiging 0) : Het volgende programmafragment eindigt, heeft als repetitie-invariant 0 n n N en als variante functie N n

Nadere informatie

opgaven formele structuren tellen Opgave 1. Zij A een oneindige verzameling en B een eindige. Dat wil zeggen (zie pagina 6 van het dictaat): 2 a 2.

opgaven formele structuren tellen Opgave 1. Zij A een oneindige verzameling en B een eindige. Dat wil zeggen (zie pagina 6 van het dictaat): 2 a 2. opgaven formele structuren tellen Opgave 1. Zij A een oneindige verzameling en B een eindige. Dat wil zeggen (zie pagina 6 van het dictaat): ℵ 0 #A, B = {b 0,..., b n 1 } voor een zeker natuurlijk getal

Nadere informatie

Verzamelingen. Hoofdstuk 5

Verzamelingen. Hoofdstuk 5 Hoofdstuk 5 Verzamelingen In de meest uiteenlopende omstandigheden kan het handig zijn om een stel objecten, elementen, of wat dan ook, samen een naam te geven. Het resultaat noemen we dan een verzameling.

Nadere informatie

Uitgebreide uitwerking Tentamen Complexiteit, juni 2017

Uitgebreide uitwerking Tentamen Complexiteit, juni 2017 Uitgebreide uitwerking Tentamen Complexiteit, juni 017 Opgave 1. a. Een pad van de wortel naar een blad stelt de serie achtereenvolgende arrayvergelijkingen voor die het algoritme doet op zekere invoer.

Nadere informatie

Modelleren en Programmeren

Modelleren en Programmeren Modelleren en Programmeren Jeroen Bransen 13 december 2013 Terugblik Fibonacci public class Fibonacci { public static void main(string[] args) { // Print het vijfde Fibonaccigetal System.out.println(fib(5));

Nadere informatie

OPDRACHT Opdracht 2.1 Beschrijf in eigen woorden wat het bovenstaande PSD doet.

OPDRACHT Opdracht 2.1 Beschrijf in eigen woorden wat het bovenstaande PSD doet. Les C-02: Werken met Programma Structuur Diagrammen 2.0 Inleiding In deze lesbrief bekijken we een methode om een algoritme zodanig structuur te geven dat er gemakkelijk programmacode bij te schrijven

Nadere informatie

Basiskennis lineaire algebra

Basiskennis lineaire algebra Basiskennis lineaire algebra Lineaire algebra is belangrijk als achtergrond voor lineaire programmering, omdat we het probleem kunnen tekenen in de n-dimensionale ruimte, waarbij n gelijk is aan het aantal

Nadere informatie

Een eenvoudig algoritme om permutaties te genereren

Een eenvoudig algoritme om permutaties te genereren Een eenvoudig algoritme om permutaties te genereren Daniel von Asmuth Inleiding Er zijn in de vakliteratuur verschillende manieren beschreven om alle permutaties van een verzameling te generen. De methoden

Nadere informatie

Netwerkdiagram voor een project. AON: Activities On Nodes - activiteiten op knooppunten

Netwerkdiagram voor een project. AON: Activities On Nodes - activiteiten op knooppunten Netwerkdiagram voor een project. AON: Activities On Nodes - activiteiten op knooppunten Opmerking vooraf. Een netwerk is een structuur die is opgebouwd met pijlen en knooppunten. Bij het opstellen van

Nadere informatie