DAB760:Språk och logik: 22 aprilParsning
-
Upload
haley-frost -
Category
Documents
-
view
29 -
download
0
description
Transcript of DAB760:Språk och logik: 22 aprilParsning
Växjö 22 april -04 Språk & logik: Parsning med kontextfria grammatiker 1
DAB760: Språk och logik:22 april Parsning
Leif Grönqvist ([email protected])Växjö Universitet (MSI)
GSLT (Sveriges nationella forskarskola i språkteknologi)
Göteborg Universitet (Institutionen för lingvistik)
2Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
Dagens föreläsning
Lite om ambiguitet som inte hanns med igår
Parsning I allmänhet Recursive-Descent-parsning Problem Tabelldriven parsning
3Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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
4Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
Icke-ambiguös grammatik för aritmetiska uttryck
Vi lägger till nya syntaktiska kategorier för termer och faktorer:1. <e> <e> + <t> | <e> - <t> | <t>2. <t> <t> * <f> | <t> / <f> | <f>3. <f> ( <e> ) | <n>4. <n> <n> <d> | <d>5. <d> 1|2|3|4|5|6|7|8|9|0e=expression, t=term, f=factor, n=number, d=digit
Regel 1 och 2 garanterar att 1-2+3 och 1/2*3 grupperas korrekt
5Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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)
6Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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)
7Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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
8Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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
9Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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
10Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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;
}
11Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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
12Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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;
}
13Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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(””);
}
14Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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-kod1. <balanced> ε2. <balanced> ( balanced> ) | <balanced> Parsa: ( ) ( ) ENDM
15Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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> | ε
16Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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
17Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
Tabelldriven parsning, algoritmen
1. Först läggs startsymbolen på stacken och NextTerminal är första symbolen i strängen som skall parsas
2. Om stacken inte är tom så poppas översta symbolen på stacken x:
1. 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
2. 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).
3. Om strängen är slut och stacken tom så lyckas parsningen annars misslyckas den
18Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
Exempel på tabelldriven parsning
På sidan 627 i boken finns i fig 11.33 en grammatik:1. <s> w c <s>2. <s> { <t>3. <s> s ;4. <t> <s> <t>5. <t> }
Tabellen T blir:
Låt oss testa att parsa: {w c s ; s ; } END
w c { } s ; END
<s> 1 2 3
<t> 4 4 5 4
19Språk & logik: Parsning med kontextfria grammatikerVäxjö 22 april -04
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