DD1361 Programmeringsparadigm. Formella Språk & Syntaxanalys. Per Austrin

Relevanta dokument
DD1361 Programmeringsparadigm. Formella Språk & Syntaxanalys. Per Austrin

Föreläsning 7: Syntaxanalys

Inlämningsuppgift MiniPlotter

Automatateori (2) Idag: Sammanhangsfria språk. Dessa kan uttryckas med Grammatik PDA

Reguljära uttryck Grammatiker Rekursiv nedåkning Allmänna kontextfria grammatiker. Syntaxanalys. Douglas Wikström KTH Stockholm

Alfabeten, strängar och språk. String

Idag: Reguljära språk Beskrivs av Reguljära uttryck DFA Grammatik

Kontextfria grammatiker

Grammatik. BNF-grammatik

Definition. Mängden av reguljära uttryck på alfabetet Σ definieras av. om α och β är reguljära uttryck så är (α β) ett reguljärt uttryck

Föreläsning 7: Syntaxanalys

Föreläsning 9: Turingmaskiner och oavgörbarhet. Turingmaskinen. Den maximalt förenklade modell för beräkning vi kommer använda är turingmaskinen.

DD1361 Programmeringsparadigm. Formella Språk & Syntaxanalys. Per Austrin

Linjärt minne. Sammanhängande minne är ej flexibelt. Effektivt

PROV I MATEMATIK Automatateori och formella språk DV1 4p

Turingmaskiner och oavgörbarhet. Turingmaskinen. Den maximalt förenklade modell för beräkning vi kommer använda är turingmaskinen.

Föreläsning 13. Träd

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson

11. Reguljära uttryck och grammatiker

Parsning. TDP007 Konstruktion av datorspråk Föreläsning 6. Peter Dalenius Institutionen för datavetenskap

Klassdeklaration. Metoddeklaration. Parameteröverföring

Grundläggande datalogi - Övning 9

11. Reguljära uttryck och grammatiker

b) S Ø aa, A Ø aa» bb, B Ø aa» bc, C Ø ac» bc» 2. Låt L vara språket över 8a< som nedanstående NFA accepterar.

Föreläsning 2 5/6/08. Reguljära uttryck 1. Reguljära uttryck. Konkatenering och Kleene star. Några operationer på språk

Kompilatorer och interpretatorer

Kompilatorteknik. Görel Hedin Datavetenskap Lunds Tekniska Högskola. Temaföreläsning, Datorer i system, 2009

12. Relationer och funktioner

kind spelling Scanning

Obligatorisk uppgift: Numerisk kalkylator

Lite mer psykologi. L2: Automater, Sökstrategier. Top-down. Kimballs sju principer

DAB760: Språk och logik

i=1 c i = B och c i = a i eller c i = b i för 1 i n. Beskriv och analysera en algoritm som löser detta problem med hjälp av dynamisk programmering.

Programmering A. Johan Eliasson

MÄLARDALENS HÖGSKOLA. CD5560 Formella språk, automater och beräkningsteori. Användarmanual. för simulatorn JFLAP

Introduktion till formella metoder Programmeringsmetodik 1. Inledning

12. Relationer och funktioner

Föreläsning 3. Stack

Tentamen Datastrukturer D DAT 035/INN960

Föreläsning 11. ADT:er och datastrukturer

Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt

10. Mängder och språk

Övningsexempel i Artificiella språk och syntaxanalys 2D1373

Användarhandledning Version 1.2

lex källkod lex.l lexkompilator lex.yy.c C- kompilator lex.yy.c a.out sekvens av tokens a.out input specifikation av tokens mha reguljära uttryck

Introduktion till programmering och Python Grundkurs i programmering med Python

Extra övningar på SDD:er/SDT:er

Matematik för språkteknologer

Introduktion till algoritmer - Lektion 4 Matematikgymnasiet, Läsåret Lektion 4

Användning av stack: evaluera uttryck i RPN

Objektorienterad modellering och diskreta strukturer. 13. Problem. Sven Gestegård Robertz. Datavetenskap, LTH

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Introduktion till programmering SMD180. Föreläsning 4: Villkor och rekursion

Introduktion till programmering D0009E. Föreläsning 1: Programmets väg

Dynamisk programmering

Datorspråk Breddgivande föreläsning

Grundläggande datalogi - Övning 1

Kungl. Tekn. Högskolan Förel 1, bild 1 Föreläsning 1: Introduktion ffl Kursinnehåll ffl Javarepetition ffl Referenser ffl Nyckelordet static ffl Klass

Föreläsning 3. Stack

TDDC77 Objektorienterad Programmering

TENTAMEN I PROGRAMSPRÅK -- DVG C kl. 08:15-13:15

Föreläsning 3: Typomvandling, villkor och val, samt textsträngar

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

TENTAMEN: Algoritmer och datastrukturer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Konstruktion av datorspråk

DD1361 Programmeringsparadigm. Carina Edlund

Objektorienterad programmering E. Algoritmer. Telefonboken, påminnelse (och litet tillägg), 1. Telefonboken, påminnelse (och litet tillägg), 2

Översikt. Varför lära sig detta? Motivering Syntax och semantik Imperativa språkets byggstenar och Python. PL-boken Kap 1 (repetition):

Datalogi I, grundkurs med Java 10p, 2D4112, Fiktiv tentamen, svar och lösningar och extra kommentarer till vissa uppgifter 1a) Dividera förs

Datorlingvistisk grammatik

Algoritmer. Två gränssnitt

Två fall: q Tom sekvens: () q Sekvens av element: (a b c) ; (sum-rec '(2 4 6)) = 12. q Första elementet uppfyller vissa villkor: (2 a b c)

Sökning och sortering

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Obligatorisk uppgift 5

Tentamen Datastrukturer (DAT037)

Dynamisk programmering

Programmering för språkteknologer II, HT2011. Rum

Programmeringsmetodik DV1 Programkonstruktion 1. Moment 9 Om högre ordningens funktioner. PK1&PM1 HT-06 moment 9 Sida 1 Uppdaterad

Tentamen Datastrukturer (DAT036)

Teoretisk del. Facit Tentamen TDDC (6)

Svar till vissa uppgifter från första veckan.

Tentamen Datastrukturer (DAT036)

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Övning 5 - Tillämpad datalogi 2013

Repetition C-programmering

Språket Python - Del 1 Grundkurs i programmering med Python

Grundläggande logik och modellteori

BINÄRA TRÄD. (X = pekarvärdet NULL): struct int_bt_node *pivot, *ny; X X X 12 X X 12 X X -3 X X

Tentamen i Objektorienterad modellering och diskreta strukturer

Inledning. Vad är ett datorprogram, egentligen? Olika språk. Problemlösning och algoritmer. 1DV433 Strukturerad programmering med C Mats Loock

Bakgrund och motivation. Definition av algoritmer Beskrivningssätt Algoritmanalys. Algoritmer. Lars Larsson VT Lars Larsson Algoritmer 1

Algoritmer och datastrukturer H I HÅKAN S T R Ö M B E R G N I C K L A S B R A N D E F E L T

Användar- och systemdokumentation

Föreläsning Datastrukturer (DAT037)

F3: Recursive descent, tokenisering, avbildningar och undantag. Carl Nettelblad

Tentamen Datastrukturer (DAT036)

Algoritmer, datastrukturer och komplexitet

DD1361 Programmeringsparadigm HT15

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Transkript:

DD1361 Programmeringsparadigm Formella Språk & Syntaxanalys Föreläsning 3 Per Austrin 2015-11-13

Huvudkoncept hittils: Snabb repetition Formellt språk en mängd strängar Reguljära språk den klass av formella språk som kan beskrivas med reguljära uttryck eller ändliga automater (DFA:er) viktigt: reguljära uttryck och automater lika kraftfulla, kan beskriva samma saker Grammatiker verktyg för att beskriva språk som med enkla rekursiva definitioner Stackautomater automat med minne i form av en stack

Idag Stackautomater (forts.) Lexikal analys Härledningar och syntaxträd Omskrivning av grammatiker Rekursiv medåkning och LL(1)-grammatiker

Idag Stackautomater (forts.) Lexikal analys Härledningar och syntaxträd Omskrivning av grammatiker Rekursiv medåkning och LL(1)-grammatiker

Stackautomater (repetition från förra fredagen) Stackautomat (PDA, Push-Down Automaton): som DFA, men har ett obegränsat minne i form av en stack

Stackautomater (repetition från förra fredagen) Stackautomat (PDA, Push-Down Automaton): som DFA, men har ett obegränsat minne i form av en stack a, ɛ/a c, a/ɛ a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z start c, b/ɛ b, ɛ/b b, a/ɛ

Stackautomater (repetition från förra fredagen) Stackautomat (PDA, Push-Down Automaton): som DFA, men har ett obegränsat minne i form av en stack a, ɛ/a c, a/ɛ a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z start c, b/ɛ b, ɛ/b Läs a:n och b:n och lägg på stacken b, a/ɛ

Stackautomater (repetition från förra fredagen) Stackautomat (PDA, Push-Down Automaton): som DFA, men har ett obegränsat minne i form av en stack start a, ɛ/a b, ɛ/b a, b/ɛ c, a/ɛ c, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z När det kommer ett c, hoppa till något av de accepterande tillstånden beroende på om det översta tecknet på stacken är a eller b b, a/ɛ

Stackautomater (repetition från förra fredagen) Stackautomat (PDA, Push-Down Automaton): som DFA, men har ett obegränsat minne i form av en stack a, ɛ/a c, a/ɛ a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z start c, b/ɛ b, ɛ/b b, a/ɛ Om sista tecknet innan c var ett b: fortsätt läsa b:n från indata och kolla att det ligger minst lika många a:n på stacken

Stackautomater (repetition från förra fredagen) Stackautomat (PDA, Push-Down Automaton): som DFA, men har ett obegränsat minne i form av en stack a, ɛ/a c, a/ɛ a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z start c, b/ɛ b, ɛ/b b, a/ɛ Automaten accepterar om den är i ett accepterande tillstånd OCH stacken är tom när indata är slut

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b b, a/ɛ

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ Stacken:

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ Stacken: b pushas

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ Stacken: a pushas b

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ Stacken: a pushas a b

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ Stacken: b pushas a a b

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ Stacken: b poppas a a b

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ Stacken: a poppas a b

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ Stacken: a poppas b

Exempelkörning, stackautomat (repetition) a, b/ɛ x, y/z: läs x, poppa y från stacken, pusha z a, ɛ/a c, a/ɛ start c, b/ɛ b, ɛ/b Indata: baabcbbb b, a/ɛ Stacken: Övergång saknas, för tecknet b måste vi ha ett a högst upp på stacken automaten accepterar inte b

Stackautomat för balanserade parentesuttryck En grammatik för balanserade parentesuttryck: Expr ɛ (Expr)Expr

Stackautomat för balanserade parentesuttryck En grammatik för balanserade parentesuttryck: Expr ɛ (Expr)Expr Vi kan också lätt konstruera en PDA för språket, vi behöver faktiskt bara ett enda tillstånd! (Plus det implicita fail-tillståndet.) start (, ɛ/( ), (/ɛ

Stackautomat för balanserade parentesuttryck En grammatik för balanserade parentesuttryck: Expr ɛ (Expr)Expr Vi kan också lätt konstruera en PDA för språket, vi behöver faktiskt bara ett enda tillstånd! (Plus det implicita fail-tillståndet.) start (, ɛ/( När vi ser en vänsterparentes, pusha på vänsterparentes på stacken ), (/ɛ

Stackautomat för balanserade parentesuttryck En grammatik för balanserade parentesuttryck: Expr ɛ (Expr)Expr Vi kan också lätt konstruera en PDA för språket, vi behöver faktiskt bara ett enda tillstånd! (Plus det implicita fail-tillståndet.) start (, ɛ/( När vi ser en vänsterparentes, pusha på vänsterparentes på stacken ), (/ɛ När vi ser högerparentes, poppa en vänsterparentes från stacken

Från grammatiker till stackautomater Parentesuttryck var enkelt att bygga stackautomat för.

Från grammatiker till stackautomater Parentesuttryck var enkelt att bygga stackautomat för. Kan man alltid konvertera en grammatik till en stackautomat?

Från grammatiker till stackautomater Parentesuttryck var enkelt att bygga stackautomat för. Kan man alltid konvertera en grammatik till en stackautomat? Nej, det kan man inte!

Från grammatiker till stackautomater Parentesuttryck var enkelt att bygga stackautomat för. Kan man alltid konvertera en grammatik till en stackautomat? Nej, det kan man inte! Exempel: Palindrom över {a, b} Palin ɛ a b a Palin a b Palin b Det existerar inte någon PDA som känner igen detta språk.

Från grammatiker till stackautomater Parentesuttryck var enkelt att bygga stackautomat för. Kan man alltid konvertera en grammatik till en stackautomat? Nej, det kan man inte! Exempel: Palindrom över {a, b} Palin ɛ a b a Palin a b Palin b Det existerar inte någon PDA som känner igen detta språk. Intuition: PDA:n borde, när den kommit exakt halvvägs in i strängen, börja matcha av tecken mot de som den redan sett, men det finns inget sätt för den att veta när den är halvvägs.

Från grammatiker till stackautomater Parentesuttryck var enkelt att bygga stackautomat för. Kan man alltid konvertera en grammatik till en stackautomat? Nej, det kan man inte! Exempel: Palindrom över {a, b} Palin ɛ a b a Palin a b Palin b Det existerar inte någon PDA som känner igen detta språk. Intuition: PDA:n borde, när den kommit exakt halvvägs in i strängen, börja matcha av tecken mot de som den redan sett, men det finns inget sätt för den att veta när den är halvvägs. Man kan bevisa detta med ett pumping-lemma för PDA:er, liknande beviset vi såg för DFA:er (ingår ej i kursen).

Grammatiker vs. stackautomater Om stackautomater inte är tillräckligt kraftfulla för att kunna användas till alla grammatiker, vad är poängen?

Grammatiker vs. stackautomater Om stackautomater inte är tillräckligt kraftfulla för att kunna användas till alla grammatiker, vad är poängen? Poängen är att de kan användas för de flesta grammatiker, t.ex. (nästan?) alltid de man får när man konstruerar programspråk.

Idag Stackautomater (forts.) Lexikal analys Härledningar och syntaxträd Omskrivning av grammatiker Rekursiv medåkning och LL(1)-grammatiker

Grammatik för aritmetiska uttryck Låt oss skriva en grammatik för aritmetiska uttryck med heltal, operatorerna +,,, /, och parenteser.

Grammatik för aritmetiska uttryck Låt oss skriva en grammatik för aritmetiska uttryck med heltal, operatorerna +,,, /, och parenteser. Möjlig grammatik: Expr Number Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr) Number Digit Digit Number Digit 0 1 2 3 4 5 6 7 8 9 Icke-slutsymboler: Expr (representerar uttryck) Number (representerar heltal) Digit (representerar siffror)

Det väsentliga i den här grammatiken är de rekursiva reglerna för hur man formar ett uttryck. Onödigt komplicerat? Expr Number Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr) Number Digit Digit Number Digit 0 1 2 3 4 5 6 7 8 9

Det väsentliga i den här grammatiken är de rekursiva reglerna för hur man formar ett uttryck. Reglerna för vad som är ett tal känns lite som ett bihang som vi var tvungna att ha med för att göra grammatiken fullständig. Onödigt komplicerat? Expr Number Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr) Number Digit Digit Number Digit 0 1 2 3 4 5 6 7 8 9

Det väsentliga i den här grammatiken är de rekursiva reglerna för hur man formar ett uttryck. Reglerna för vad som är ett tal känns lite som ett bihang som vi var tvungna att ha med för att göra grammatiken fullständig. Onödigt komplicerat? Expr Number Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr) Number Digit Digit Number Digit 0 1 2 3 4 5 6 7 8 9 Att känna igen tal är ju väldigt enkelt (kan t.ex. göras med det reguljära uttrycket [0-9]+), är lite overkill att använda grammatik för det.

Pre-processa heltal Idé: pre-processa indata-strängen för att ta hand om de delar som utgör enkla beståndsdelar av grammatiken

Pre-processa heltal Idé: pre-processa indata-strängen för att ta hand om de delar som utgör enkla beståndsdelar av grammatiken Exempel: låt oss titta på strängen 378*232*(582-01)

Pre-processa heltal Idé: pre-processa indata-strängen för att ta hand om de delar som utgör enkla beståndsdelar av grammatiken Exempel: låt oss titta på strängen 378*232*(582-01) Detta är teckensekvensen 3, 7, 8, *, 2, 3, 2, *, (, 5, 8, 2, -, 0, 1, )

Pre-processa heltal Idé: pre-processa indata-strängen för att ta hand om de delar som utgör enkla beståndsdelar av grammatiken Exempel: låt oss titta på strängen 378*232*(582-01) Detta är teckensekvensen 3, 7, 8, *, 2, 3, 2, *, (, 5, 8, 2, -, 0, 1, ) Vi pre-processar detta till den nya sekvensen Number, *, Number, *, (, Number, -, Number, )

Pre-processa heltal Idé: pre-processa indata-strängen för att ta hand om de delar som utgör enkla beståndsdelar av grammatiken Exempel: låt oss titta på strängen 378*232*(582-01) Detta är teckensekvensen 3, 7, 8, *, 2, 3, 2, *, (, 5, 8, 2, -, 0, 1, ) Vi pre-processar detta till den nya sekvensen Number, *, Number, *, (, Number, -, Number, ) Elementen i den nya sekvensen kallas för tokens.

Pre-processa heltal Idé: pre-processa indata-strängen för att ta hand om de delar som utgör enkla beståndsdelar av grammatiken Exempel: låt oss titta på strängen 378*232*(582-01) Detta är teckensekvensen 3, 7, 8, *, 2, 3, 2, *, (, 5, 8, 2, -, 0, 1, ) Vi pre-processar detta till den nya sekvensen Number, *, Number, *, (, Number, -, Number, ) Elementen i den nya sekvensen kallas för tokens. Några tokens är helt enkelt enstaka tecken från indata-strängen, men andra består av delsträngar från indata-strängen som getts en typ (i det här fallet Number )

Pre-processa heltal Idé: pre-processa indata-strängen för att ta hand om de delar som utgör enkla beståndsdelar av grammatiken Exempel: låt oss titta på strängen 378*232*(582-01) Detta är teckensekvensen 3, 7, 8, *, 2, 3, 2, *, (, 5, 8, 2, -, 0, 1, ) Vi pre-processar detta till den nya sekvensen Number, *, Number, *, (, Number, -, Number, ) Elementen i den nya sekvensen kallas för tokens. Några tokens är helt enkelt enstaka tecken från indata-strängen, men andra består av delsträngar från indata-strängen som getts en typ (i det här fallet Number ) Vi betraktar denna tokensekvens som ett indata att parsa

Åter till grammatiken Vad händer med vår grammatik? Expr Number Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr) Number Digit Digit Number Digit 0 1 2 3 4 5 6 7 8 9

Åter till grammatiken Vad händer med vår grammatik? Expr Number Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr) Number Digit Digit Number Digit 0 1 2 3 4 5 6 7 8 9

Åter till grammatiken Vad händer med vår grammatik? Expr Number Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr) Number Digit Digit Number Digit 0 1 2 3 4 5 6 7 8 9 Man kan säga att vi har uppgraderat (eller nedgraderat?) Number till en slut-symbol istället för en icke-slutsymbol

Lexikal analys Lexikal analys är processen att transformera en indatasträng (sekvens av tecken) till en sekvens av tokens. Syften: 1. Abstrahera bort smådetaljer ur grammatiken. 2. Städa bort irrelevanta delar av indata Kommentarer i programmeringsspråk Whitespace Vi vill antagligen att 12+5 och 12 + 5 ska behandlas likadant, men att 1 2+5 ska behandlas annorlunda

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Vad är lämpliga val av tokens i Haskell? Förslag: Where/Let/Derives/etc alla keywords i språket Equal/Plus/Minus/Times/etc operatorer Int/Double/etc tal av olika typer Name Variabel/funktionsnamn (och många fler)

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys:

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Detta är en kommentar så vi ignorerar den

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int, Times

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int, Times, Name

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int, Times, Name, Where

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int, Times, Name, Where Detta är en kommentar så vi ignorerar den

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int, Times, Name, Where, Name

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int, Times, Name, Where, Name, Equal

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int, Times, Name, Where, Name, Equal, Name

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int, Times, Name, Where, Name, Equal, Name, Minus

Lexikal analys, exempel Betrakta följande Haskell-funktion -- Det här är min funktion minfunktion alfa beta = 5*x where -- beräkna differensen x = alpha-beta Möjlig tokenisering/lexikal analys: Name, Name, Name, Equal, Int, Times, Name, Where, Name, Equal, Name, Minus, Name

Idag Stackautomater (forts.) Lexikal analys Härledningar och syntaxträd Omskrivning av grammatiker Rekursiv medåkning och LL(1)-grammatiker

Språk inte bara syntax Hittills har vi bara pratat om syntax: givet en sträng, ligger den i språket, ja eller nej?

Språk inte bara syntax Hittills har vi bara pratat om syntax: givet en sträng, ligger den i språket, ja eller nej? Exempel Är 4*(5+3) ett syntaktiskt korrekt aritmetiskt uttryck? Är min java-fil ett giltigt java-program?

Språk inte bara syntax Hittills har vi bara pratat om syntax: givet en sträng, ligger den i språket, ja eller nej? Exempel Är 4*(5+3) ett syntaktiskt korrekt aritmetiskt uttryck? Är min java-fil ett giltigt java-program? Men ofta har ju strängarna i språken en mening en semantik som man vill kunna analysera

Språk inte bara syntax Hittills har vi bara pratat om syntax: givet en sträng, ligger den i språket, ja eller nej? Exempel Är 4*(5+3) ett syntaktiskt korrekt aritmetiskt uttryck? Är min java-fil ett giltigt java-program? Men ofta har ju strängarna i språken en mening en semantik som man vill kunna analysera Exempel Vad är värdet av 4*(5+3)? Vad händer när man kör mitt java-program?

Härledning En härledning av en indatasträng är en sekvens av grammatikregler som producerar strängen Expr Num Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr)

Härledning En härledning av en indatasträng är en sekvens av grammatikregler som producerar strängen Exempel: Låt oss härleda 4*(5+3), dvs token-sekvensen Num, *, (, Num, +, Num, ) Expr Num Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr)

Härledning En härledning av en indatasträng är en sekvens av grammatikregler som producerar strängen Exempel: Låt oss härleda 4*(5+3), dvs token-sekvensen Num, *, (, Num, +, Num, ) Expr Num Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr) Härledning: Expr Expr Expr Num Expr Num (Expr) Num (Expr+Expr) Num (Num+Expr) Num (Num+Num)

Härledning En härledning av en indatasträng är en sekvens av grammatikregler som producerar strängen Exempel: Låt oss härleda 4*(5+3), dvs token-sekvensen Num, *, (, Num, +, Num, ) Expr Num Expr + Expr Expr Expr Expr Expr Expr/Expr (Expr) Härledning: Expr Expr Expr Num Expr Num (Expr) Num (Expr+Expr) Num (Num+Expr) Num (Num+Num) Varje steg använder en av produktionsreglerna, och vi landar till slut i indata-sekvensen

Syntaxträd Det bästa sättet att representera härledningar på är med syntaxträd

Syntaxträd Det bästa sättet att representera härledningar på är med syntaxträd Härledning Expr Expr Expr Num Expr Num (Expr) Num (Expr+Expr) Num (Num+Expr) Num (Num+Num)

Syntaxträd Det bästa sättet att representera härledningar på är med syntaxträd Härledning Visualiserat som syntaxträd Expr Expr Expr Num Expr Num (Expr) Num (Expr+Expr) Num (Num+Expr) Num (Num+Num) Num Expr Expr * Expr ( Expr ) Expr Num + Expr Num

Semantik från härledningar/syntaxträd Uttryck: 4*(5+3) Syntaxträd: Expr Expr * Expr Num ( Expr ) Expr Num + Expr Num

Semantik från härledningar/syntaxträd Uttryck: 4*(5+3) För att kunna beräkna värdet av uttrycket behöver vi ju veta exakt vilka tal som de olika Num-elementen var. Syntaxträd: Num Expr Expr * Expr ( Expr ) Expr Num + Expr Num

Semantik från härledningar/syntaxträd Uttryck: 4*(5+3) För att kunna beräkna värdet av uttrycket behöver vi ju veta exakt vilka tal som de olika Num-elementen var. Syntaxträd: Expr Num(4) Expr * Expr ( Expr ) Varje Num-token taggas med semantisk data som talar om vilket tal det representerar Expr + Expr Num(5) Num(3)

Semantik från härledningar/syntaxträd Uttryck: 4*(5+3) För att kunna beräkna värdet av uttrycket behöver vi ju veta exakt vilka tal som de olika Num-elementen var. Syntaxträd: Expr Num(4) Expr * Expr ( Expr ) Varje Num-token taggas med semantisk data som talar om vilket tal det representerar Expr + Expr Num(5) Num(3) Man kan nu beräkna värdet med en enkel sökning i trädet. if leafnode: value = token.value() if plusnode: value = left.value() + right.value() if mulnode: value = left.value() * right.value() etc...

Uttryck: 3*2+1 Syntaxträd, exempel 2

Uttryck: 3*2+1 Syntaxträd, exempel 2 Anna hävdar att det har följande syntaxträd: Expr Bengt hävdar att det har följande syntaxträd: Expr Expr * Expr Expr + Expr Num(3) Expr + Expr Expr * Expr Num(1) Num(2) Num(1) Num(3) Num(2) Vem har rätt?

Uttryck: 3*2+1 Syntaxträd, exempel 2 Anna hävdar att det har följande syntaxträd: Expr Bengt hävdar att det har följande syntaxträd: Expr Expr * Expr Expr + Expr Num(3) Expr + Expr Expr * Expr Num(1) Num(2) Num(1) Num(3) Num(2) Vem har rätt? Båda är korrekta syntaxträd för uttrycket enligt grammatiken!

Tvetydighet Båda är korrekta syntaxträd för uttrycket enligt grammatiken

Tvetydighet Båda är korrekta syntaxträd för uttrycket enligt grammatiken Grammatiken är tvetydig det finns flera olika syntaxträd för samma sträng

Tvetydighet Båda är korrekta syntaxträd för uttrycket enligt grammatiken Grammatiken är tvetydig det finns flera olika syntaxträd för samma sträng Om vi utvärderar uttrycket med de olika träden får vi olika svar: 3 (2 + 1) = 9 vs. (3 2) + 1 = 7

Tvetydighet Båda är korrekta syntaxträd för uttrycket enligt grammatiken Grammatiken är tvetydig det finns flera olika syntaxträd för samma sträng Om vi utvärderar uttrycket med de olika träden får vi olika svar: 3 (2 + 1) = 9 vs. (3 2) + 1 = 7 Att en grammatik är tvetydig spelar ingen roll för syntaxen (ändrar inte vad som är giltiga strängar), men gör att det finns flera olika semantiska tolkningar av strängarna i språket.

Tvetydighet Båda är korrekta syntaxträd för uttrycket enligt grammatiken Grammatiken är tvetydig det finns flera olika syntaxträd för samma sträng Om vi utvärderar uttrycket med de olika träden får vi olika svar: 3 (2 + 1) = 9 vs. (3 2) + 1 = 7 Att en grammatik är tvetydig spelar ingen roll för syntaxen (ändrar inte vad som är giltiga strängar), men gör att det finns flera olika semantiska tolkningar av strängarna i språket. Sådan dubbeltydighet kan vara charmig i naturliga språk, men antagligen inget man vill ha i sitt programmeringsspråk...

Idag Stackautomater (forts.) Lexikal analys Härledningar och syntaxträd Omskrivning av grammatiker Rekursiv medåkning och LL(1)-grammatiker

Exempel: 3*2+1 5-2*3/2+3*(5-3) Varför blev det tvetydigt?

Exempel: 3*2+1 5-2*3/2+3*(5-3) Varför blev det tvetydigt? Vi vill att * och / ska ha högre prioritet än + och -

Exempel: 3*2+1 5-2*3/2+3*(5-3) Varför blev det tvetydigt? Vi vill att * och / ska ha högre prioritet än + och - Men detta finns inte med i grammatiken

Exempel: 3*2+1 5-2*3/2+3*(5-3) Varför blev det tvetydigt? Vi vill att * och / ska ha högre prioritet än + och - Men detta finns inte med i grammatiken Ett mer detaljerat resonemang om hur aritmetiska uttryck ser ut: ett uttryck består av en eller flera termer (separerade av + eller ) varje term består av en eller flera faktorer (separerade av eller /) varje faktor är antingen ett tal, eller ett uttryck omgivet av parenteser

Grammatik för aritmetiska uttryck, version 3 Ny, bättre, grammatik för aritmetiska uttryck: Expr Term Expr + Term Expr Term Term Factor Term Factor Term/Factor Factor Num (Expr)

Grammatik för aritmetiska uttryck, version 3 Ny, bättre, grammatik för aritmetiska uttryck: Syntaxträd för 3*2+1: Expr Term Expr + Term Expr Term Term Factor Term Factor Term/Factor Factor Num (Expr) Expr Expr + Term Term Factor Term * Factor Num(1) Factor Num(2) Num(3)

Eliminera tvetydighet Tyvärr är det i allmänhet väldigt svårt att se på en grammatik om den är tvetydig eller inte

Eliminera tvetydighet Tyvärr är det i allmänhet väldigt svårt att se på en grammatik om den är tvetydig eller inte Har man tur (eller otur...) och hittar två olika syntax-träd för samma sträng så vet man att grammatiken är tvetydig

Eliminera tvetydighet Tyvärr är det i allmänhet väldigt svårt att se på en grammatik om den är tvetydig eller inte Har man tur (eller otur...) och hittar två olika syntax-träd för samma sträng så vet man att grammatiken är tvetydig Men det finns inget enkelt sätt att övertyga sig om att en grammatik är otvetydig (Att avgöra om en grammatik är tvetydig är ett så kallat oavgörbart problem det existerar ingen algoritm för att göra detta.)

Idag Lexikal analys Härledningar och syntaxträd Omskrivning av grammatiker Rekursiv medåkning och LL(1)-grammatiker

Grammatik för binära träd BinTree Leaf LParen Number RParen Branch LParen BinTree Comma BinTree RParen

Grammatik för binära träd BinTree Leaf LParen Number RParen Branch LParen BinTree Comma BinTree RParen Slutsymboler: Leaf: strängen leaf Branch: strängen branch Number: [0-9]+ LParen, RParen, Comma: parenteser och kommatecken

Grammatik för binära träd BinTree Leaf LParen Number RParen Branch LParen BinTree Comma BinTree RParen Slutsymboler: Leaf: strängen leaf Branch: strängen branch Number: [0-9]+ LParen, RParen, Comma: parenteser och kommatecken Exempel: branch(branch(leaf(17),leaf(42)),leaf(5))

Grammatik för binära träd BinTree Leaf LParen Number RParen Branch LParen BinTree Comma BinTree RParen Slutsymboler: Leaf: strängen leaf Branch: strängen branch Number: [0-9]+ LParen, RParen, Comma: parenteser och kommatecken Exempel: branch(branch(leaf(17),leaf(42)),leaf(5)) Efter lexikal analys: Branch, LParen, Branch, LParen, Leaf, LParen, Number, RParen, Comma, Leaf, LParen, Number, RParen, RParen, Comma, Leaf, LParen, Number, RParen, RParen

Rekursiv medåkning Rekursiv medåkning är en meta-algoritm för att konstruera en parser för en grammatik.

Rekursiv medåkning Rekursiv medåkning är en meta-algoritm för att konstruera en parser för en grammatik. Huvudidé: en funktion per icke-slutsymbol, som är ansvarig för att parsa den icke-slutsymbolen. tittar på nästa token i indata och väljer produktionsregel baserat på det sedan rekursiva anrop för att parsa de olika delarna av högerledet

Rekursiv medåkning för binära träd BinTree Leaf(Number) Branch(BinTree, BinTree)

Rekursiv medåkning för binära träd BinTree Leaf(Number) Branch(BinTree, BinTree) Bara en icke-slutsymbol, vi ska ha en funktion BinTree som är ansvarig för att parsa BinTree

Rekursiv medåkning för binära träd BinTree Leaf(Number) Branch(BinTree, BinTree) Bara en icke-slutsymbol, vi ska ha en funktion BinTree som är ansvarig för att parsa BinTree ParseTree BinTree() { Token t = NextToken(); if (t.type == Leaf) { if (NextToken().type!= LParen) throw SyntaxError(); Token Num = NextToken(); if (Num.type!= Number) throw SyntaxError(); if (NextToken().type!= RParen) throw SyntaxError(); return new LeafNode(Num.data); } else if (t.type == Branch) { if (NextToken().type!= LParen) throw SyntaxError(); ParseTree left = BinTree(); if (NextToken().type!= Comma) throw SyntaxError(); ParseTree right = BinTree(); if (NextToken().type!= RParen) throw SyntaxError(); return new BranchNode(left, right); } }

Rekursiv medåkning för binära träd BinTree Leaf(Number) Branch(BinTree, BinTree) Fullständig Java-implementation av lexikal Bara en icke-slutsymbol, analys och rekursiv vi skamedåknings-parser ha en funktion BinTree för som är ansvarig för binära att parsa trädbintree finns på kurshemsidan under kursmaterial för dagens föreläsning ParseTree BinTree() { Token t = NextToken(); if (t.type == Leaf) { if (NextToken().type!= LParen) throw SyntaxError(); Token Num = NextToken(); if (Num.type!= Number) throw SyntaxError(); if (NextToken().type!= RParen) throw SyntaxError(); return new LeafNode(Num.data); } else if (t.type == Branch) { if (NextToken().type!= LParen) throw SyntaxError(); ParseTree left = BinTree(); if (NextToken().type!= Comma) throw SyntaxError(); ParseTree right = BinTree(); if (NextToken().type!= RParen) throw SyntaxError(); return new BranchNode(left, right); } }

Rekursiv medåkning för aritmetiska uttryck? För att skriva en parser för detta med rekursiv medåkning ska vi ha tre funktioner Expr, Term, Factor Expr Term Expr + Term Expr Term Term Factor Term Factor Term/Factor Factor Num (Expr)

Rekursiv medåkning för aritmetiska uttryck? För att skriva en parser för detta med rekursiv medåkning ska vi ha tre funktioner Expr, Term, Factor ParseTree Factor() { Token t = NextToken(); if (t.type == Num) { // produktionsregel 1 return NumberNode(t.value); } else { // produktionsregel 2 if (t.type!= LParen) throw SyntaxError(); ParseTree subexpression = Expr(); if (NextToken().type!= RParen) throw SyntaxError(); } } Expr Term Expr + Term Expr Term Term Factor Term Factor Term/Factor Factor Num (Expr)

Rekursiv medåkning för aritmetiska uttryck? För att skriva en parser för detta med rekursiv medåkning ska vi ha tre funktioner Expr, Term, Factor ParseTree Factor() { Token t = NextToken(); if (t.type == Num) { // produktionsregel 1 return NumberNode(t.value); } else { // produktionsregel 2 if (t.type!= LParen) throw SyntaxError(); ParseTree subexpression = Expr(); if (NextToken().type!= RParen) throw SyntaxError(); } } ParseTree Term() { Token t = NextToken(); TODO: hur veta vilken produktionsregel som ska användas??? } Expr Term Expr + Term Expr Term Term Factor Term Factor Term/Factor Factor Num (Expr)

LL(1)-grammatiker En grammatik som man kan parsa med rekursiv medåkning kallas för en LL(1)-grammatik Expr Term Expr + Term Expr Term Term Factor Term Factor Term/Factor Factor Num (Expr)

LL(1)-grammatiker En grammatik som man kan parsa med rekursiv medåkning kallas för en LL(1)-grammatik Den här grammatiken för aritmetiska uttryck är inte LL(1) och kan inte parsas med rekursiv medåkning Expr Term Expr + Term Expr Term Term Factor Term Factor Term/Factor Factor Num (Expr)

LL(1)-grammatiker En grammatik som man kan parsa med rekursiv medåkning kallas för en LL(1)-grammatik Den här grammatiken för aritmetiska uttryck är inte LL(1) och kan inte parsas med rekursiv medåkning Expr Term Expr + Term Expr Term Term Factor Term Factor Term/Factor Factor Num (Expr) (Ettan står för att vi tittar ett token framåt och bestämmer oss för vilken produktionsregel som ska användas, mer generellt finns LL(k) där vi tittar på de kommande k tokens när vi ska välja produktionsregel)

Nästa föreläsning Olika typer av grammatiker Kontextfria LL-grammatiker LR-grammatiker Kanske lite om parser-generatorer Sammanfattning av kursavsnittet och anvisningar för kontrollskrivningen