190 likes | 334 Views
DAB760: Språk och logik: 22 april Parsning. Leif Grönqvist (leif.gronqvist@msi.vxu.se) Växjö Universitet (MSI) GSLT (Sveriges nationella forskarskola i språkteknologi) Göteborg Universitet (Institutionen för lingvistik). Dagens föreläsning. Lite om ambiguitet som inte hanns med igår
E N D
DAB760: Språk och logik:22 april Parsning Leif Grönqvist (leif.gronqvist@msi.vxu.se) Växjö Universitet (MSI) GSLT (Sveriges nationella forskarskola i språkteknologi) Göteborg Universitet (Institutionen för lingvistik) Språk & logik: Parsning med kontextfria grammatiker
Dagens föreläsning • Lite om ambiguitet som inte hanns med igår • Parsning • I allmänhet • Recursive-Descent-parsning • Problem • Tabelldriven parsning Språk & logik: Parsning med kontextfria grammatiker
Ambiguitet • För uttrycket 1+2+3 finns två olika parsträd: • 1+2 + 3 • 1 + 2+3 • Eftersom det finns uttryck som kan beskrivas av flera olika parsträd så är grammatiken ambiguös • Att en grammatik är icke-ambiguös är mycket svårt att bevisa • Problem kan uppstå om evaluering av uttryck i språket blir olika beroende på parsträd: • 1-2+3 • if a then if b then c else d Språk & logik: Parsning med kontextfria grammatiker
Icke-ambiguös grammatik för aritmetiska uttryck • Vi lägger till nya syntaktiska kategorier för termer och faktorer: • <e> <e> + <t> | <e> - <t> | <t> • <t> <t> * <f> | <t> / <f> | <f> • <f> ( <e> ) | <n> • <n> <n> <d> | <d> • <d> 1|2|3|4|5|6|7|8|9|0 e=expression, t=term, f=factor, n=number, d=digit • Regel 1 och 2 garanterar att 1-2+3 och 1/2*3 grupperas korrekt Språk & logik: Parsning med kontextfria grammatiker
Parsning • Vi vill lösa två olika uppgifter • Givet en kontextfri grammatik G vill vi klara: • Igenkänning: avgör om en sträng s єΣT* ingår i språket L(G) • Parsning: bygg upp ett parsträd för s om s є L(G) • Vi har sett hur parsträdet kan se ut men inte hur man systematiskt kan konstruera det • Vi skall titta på två parsningsalgoritmer som inte klarar riktigt alla kontextfria grammatiker • Att klara alla CFG går men algoritmerna är långsammare (CYK, Earley) • En annan känd algoritm är LR-parsning (Left to Right) Språk & logik: Parsning med kontextfria grammatiker
Recursive-Descent-parsning • Fungerar top-down • Metoden bygger på idén att göra en funktion för varje icke-terminal-symbol • Denna funktion skall avgöra om en sträng kan härledas från sin symbol och göra ett parsträd • Fungerar bara för vissa typer av grammatiker (inte så allvarligt – se lite senare) Språk & logik: Parsning med kontextfria grammatiker
Recursive-Descent, algoritmen för igenkänning • Strängen som skall parsar finns i x1…xn • NextTerminal innehåller xi, den senast inlästa symbolen • s ΣN finns en funktion fs som: • Returnerar True om xi…xj kan härledas från s • Sätter NextTerminal till xj+1 • Igenkänning av x1…xn som en s (startsymbolen) sker genom att anropa fs • Om svaret blir True och NextTerminal är xn+1 så ingår x1…xn i språket, annars inte Språk & logik: Parsning med kontextfria grammatiker
Recursive-Descent-igenkänning, algoritmens funktioner • fs där s är en icke-terminal symbol med m produktionsregler (exklusive en eventuell s ε) kan konstrueras enligt: • m-1 if-satser efter varandra: if(cond1) { }; if(cond2) { }; if(condm) { }; • Om s ε finns returneras true, annars false Språk & logik: Parsning med kontextfria grammatiker
Recursive-Descent-parsning, algoritmens funktioner, forts. • if-satsen som svarar mot s x1…xk matchar symbolerna x1…xk enligt: • Om xi är en terminal symbol: om xi=NextTerminal fortsätt till nästa symbol, annars returnera false • Om xi är en icke-terminal t: om ft returnerar true så fortsätt, annars returnera false • Om x1…xk matchats returneras true Språk & logik: Parsning med kontextfria grammatiker
Funktionen för “faktor”-projektionen • Pseudokoden svarande mot: <faktor> ( <expr> ) | <num> Boolean function factor(void) { if(*NextTerminal==‘(‘)) { NextTerminal++; if(expr()) { return *NextTerminal==‘)’; } else return false; } if(num()) return true; return false; } Språk & logik: Parsning med kontextfria grammatiker
Recursive-Descent-parsning • Liknar igenkänningsalgoritmen men funktionerna modifieras: • De skall returnera träd istället för boolean (misslyckad parsning returnerar NULL) • Rotnoden skapas som A och svarar mot en projektion s x1…xn , och har n barn: • Om xi är en terminal så skapas barn i som ett löv med etiketten xi. • Om xi är en icke-terminal så är barn i det träd som returneras av fxi Språk & logik: Parsning med kontextfria grammatiker
Funktionen för “faktor”-projektionen (parsning) • Pseudokoden svarande mot: <faktor> ( <expr> ) | <num> Tree *function factorTree(void) { if(*NextTerminal==‘(‘)) { NextTerminal++; if(expr()) { if(*NextTerminal==‘)’) return node3(“factor”, node0(‘(‘), expTree(), node0(‘)’)); else return NULL; } else return NULL; } if(num()) return node1(“factor”, numTree()); return NULL; } Språk & logik: Parsning med kontextfria grammatiker
Funktionen för “balanced”-projektionen (parsning) • Pseudokoden svarande mot: <balanced> ε, <balanced> ( balanced> ) <balanced> Tree *function balancedTree(void) { if(*NextTerminal==‘(‘)) { NextTerminal++; if(balanced()) { if(*NextTerminal==‘)’) { if(balanced()) return node4(“balanced”, node0(‘(‘), balancedTree(), node0(‘)’), balancedTree()); else return NULL; } else return NULL; } else return NULL; } return node0(””); } Språk & logik: Parsning med kontextfria grammatiker
Exempel på Recursive-Descent-parsning • Svårt att handexekvera rekursiva funktioner… • I boken finns exempel 11.9 som är rätt bra, med tillhörande riktig C-kod • <balanced> ε • <balanced> ( balanced> ) | <balanced> • Parsa: ( ) ( ) ENDM Språk & logik: Parsning med kontextfria grammatiker
Problem med Recursive-Descent-parsning • Vänster-rekursion får inte förekomma, dvs regler av typen s s x2…xn • Dessa skulle leda till oändlig rekursion • Den vänsterrekursiva regeln <s> <s> a | b kan skrivas om som två regler: <s> b <s’> och <s’> a <s’> | ε • Valet av produktion för en icke-terminal måste vara entydigt bestämd av första symbolen i kroppen. Problem: <num> → <digit> <num> | <digit> • Kan skrivas om som: <num> → <digit> <digits> <digits> → <num> | ε Språk & logik: Parsning med kontextfria grammatiker
Tabelldriven parsning • Den stora nackdelen med Recursive-Descent-parsning är att man måste skriva ett nytt program för varje grammatik • En tabelldriven parser lagrar grammatiken i en tabell men programmet är samma för alla grammatiker • Två strukturer behövs: • En (tvådimensionell) tabell T: • En rad för varje icke-terminal symbol • En kolumn för varje symbol s som kan inleda en sträng, härledbar från en icke-terminal symbol • Produktionsregler i cellerna • En stack för återstående symboler att matcha Språk & logik: Parsning med kontextfria grammatiker
Tabelldriven parsning, algoritmen • Först läggs startsymbolen på stacken och NextTerminal är första symbolen i strängen som skall parsas • Om stacken inte är tom så poppas översta symbolen på stacken x: • Om x är en terminal så matchas den mot NextTerminal, om lika så läser vi nästa symbol i strängen, annars misslyckas parsningen • Om x är en icke-terminal så slås x, NextTerminal upp i T. Om platsen är tom så misslyckas parsningen, annars om x x1…xn hittas så läggs xn…x1 på stacken (x1 hamnar överst). • Om strängen är slut och stacken tom så lyckas parsningen annars misslyckas den Språk & logik: Parsning med kontextfria grammatiker
Exempel på tabelldriven parsning • På sidan 627 i boken finns i fig 11.33 en grammatik: • <s> w c <s> • <s> { <t> • <s> s ; • <t> <s> <t> • <t> } • Tabellen T blir: • Låt oss testa att parsa: {w c s ; s ; } END Språk & logik: Parsning med kontextfria grammatiker
Reguljära uttryck (RE) vs. kontextfria grammatiker (CFG) • I boken finns bevis för att: • Varje språk som kan beskrivas av ett RE kan också beskrivas av en CFG • I beviset gås varje konstruktion i RE igenom för att visa att man kan skapa en CFG för ett godtyckligt RE • RE är inte tillräckligt kraftfullt för att beskriva alla språk som kan beskrivas av en CFG • Se exempelvis på det oändliga språket: {01, 0011, 000111, …} • Beskrivs som CFG: <s> 0 <s> 1 | 01 Språk & logik: Parsning med kontextfria grammatiker