De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
De Parser
Compiler Constructie: Les 2
Pieter Wuille
October 23, 2006
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Overzicht
Introductie Structuur
Van woorden naar zinnen Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing
Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica LR Parsing
Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
YACC
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Overzicht
Introductie Structuur
Van woorden naar zinnen Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing
Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica LR Parsing
Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
YACC Conflicten
Voor volgende week
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Plaats in Compiler Schema
I Source −−→ Tokens Lex
I Tokens −−−→ Reductions Parse
I Reductions ParseActions
−−−−−−−→ Abstract Syntax
I ...
Parser: zet tokens om in reducties
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Overzicht
Introductie Structuur
Van woorden naar zinnen Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing
Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica LR Parsing
Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
YACC Conflicten
Voor volgende week
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Wat we hebben
I Voorlopig hebben we “woorden”
I Slechts opeenvolging van lexer tokens
I Geen hierarchische structuur
I Elk token kan op elke plaats
Besluit: we willen zinsstructuur bepalen
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Kan dat niet met lex?
I Lex staat afkortingen toe van stukjes syntax
I Stel:
digits = [0 - 9]+
sum = (digits “+”)* digits
I Nu herkennen we 28+301+9 als token
I Maar stel:
digits = [0 - 9]+
sum = expr “+” expr expr = “(” sum “)” | digits
I Herkennen we 28+(301+9) nu als token?
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Gebrek aan recursie
We hebben recursie nodig
Dit vereenvoudigt de notatie ook:
I expr = ab(c | d)e wordt:
aux = c aux = d
expr = a b aux e
I expr = (a b c)* wordt:
expr = (a b c) expr
expr =
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Context-Free Grammar
De verkregen taal heet “Context-Free Grammar”
I Definieert syntactische structuur
I Flexibeler dan reguliere expressies
I Kunnen ook lexicale tokens definieren
I DFA’s niet krachtig genoeg voor parsen ervan
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
CFG definitie
CFG’s worden gedefinieerd door productieregels van de vorm symbool → symbool symbool · · · symbool .
I Symbolen zijn terminaal (TS) of niet-terminaal (NTS)
I Terminale symbolen zijn lexer tokens
I Links van → staat NTS
I Er is een startsymbool (NTS)
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Afleidingen
De taal gedefinieerd door een grammatica is de verzameling van alle opeenvolgingen van TS’en die afgeleid kunnen worden van het startsymbool.
I NTS worden (volgens productieregels) vervangen
I Men stopt als enkel TS (tokens) overblijven
De parse-boom onstaat door elk symbool te verbinden
met hetgeen het van afgeleid is.
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Ambiguiteit
Een grammatica wordt ambigu genoemd als eenzelfde zin (opeenvolging van tokens) meerdere parse-bomen kan hebben.
I Parse-trees worden gebruikt om betekenis te bepalen
I We willen geen zinnen met meerdere betekenissen
I Bv: 1 − 2 − 3 zou (1 − 2) − 3 of 1 − (2 − 3) kunnen
betekenen
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Ambiguiteit wegwerken
Een ambigue grammatica kan vaak omgezet worden in een niet-ambigue.
Bv.: Een ambigue taal met + en ∗:
E→id E→(E)
E→E+E E→E*E
Wordt:
E→E+T T→T*F F→id
E→T T→F F→(E)
Een taal die niet niet-ambigu te schrijven is, is meestal
niet geschikt als programmeertaal
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Het parsen
Uiteindelijk wat de parser doet is:
I E´ en voor ´ e´ en de lexer tokens (TS) opvragen
I Groepjes symbolen samennemen tot NTS (reducties)
I Deze reducties zijn de “output” van de parser
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Overzicht
Introductie Structuur
Van woorden naar zinnen Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing
Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica LR Parsing
Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
YACC Conflicten
Voor volgende week
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Predictive parsing
De eenvoudigste grammatica’s → predictive parsing
I Ook wel recursive-descent genaamd (top-down)
I Elk NTS wordt ´ e´ en functie
I Elke functie beslist op basis van volgend token welke productieregel te gebruiken
I Dit is eigenlijk “gokken” welke regel te gebruiken
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Recursive descent voorbeeld
S→if E then S else S L→end
S→begin S L L→; S L
S→print E E→num = num
enum token{IF, THEN, ELSE, BEGIN, PRINT, SEMI, NUM, EQ};
extern enum token getToken(void);
enum token tok;
void advance() {tok=getToken();}
void eat(enum token t) {if (tok==t) advance(); else error();}
void S(void) {switch(tok) {
case IF: eat(IF); E(); eat(THEN); S(); eat(ELSE); S(); break;
case BEGIN: eat(BEGIN); S(); L(); break;
case PRINT: eat(PRINT); E(); break;
default: error();
}}
void L(void) {switch(tok) { case END: eat(END); break;
case SEMI: eat(SEMI); S(); L(); break;
default: error();
}
void E(void) {switch(tok) { eat(NUM); eat(EQ); eat(NUM);
}
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Grenzen van Recursive Descent
We moeten op basis van het actieve NTS en het volgende token beslissen welke productie regel te gebruiken.
Stel:
S→E $ ($: end-of-file)
E→E+T T→T*F F→num
E→T T→F F→(E)
void S(void) { E(); eat(EOF); } void E(void) {switch(tok) {
case ?: E(); eat(PLUS); T(); break;
case ?: T(); break;
default: error();
}
void T(void) {switch(tok) {
case ?: T(); eat(TIMES); F(); break;
case ?: F(); break;
default: error();
}
void F(void) {...}
Bv.: (1*2+3)+4 en (1*2+3). De E() functie heeft hier
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
FIRST en FOLLOW sets
Om te bepalen welke tokens welke productieregel
impliceren, introduceren we de FIRST en FOLLOW sets.
I FIRST set: FIRST(γ) is de verzameling van alle TS die eerste teken in een zin afgeleid van γ kunnen zijn.
I FOLLOW set: FOLLOW(X) is de verzameling van alle TS die in een afleiding X kunnen opvolgen.
Als 2 productieregels X→ α en X→ β een overlappende
FIRST(α) en FIRST(β) hebben, kan predictive parsing
niet.
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Voorbeeld
Z→d Y→ X→Y
Z→X Y Z Y→c X→a
I Het lijkt dat FIRST(Z) gelijk zou moeten zijn aan FIRST(X)
I FIRST(X) kan echter ook afleiden (het is nullable)
I FIRST(Y) behoort dus ook tot FIRST(Z)
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Algoritme
Z→d Y→ X→Y
Z→X Y Z Y→c X→a
Initialiseer FIRST en FOLLOW leeg, en nullable overal false;
foreach TS Z do FIRST[Z ] ← {Z } end
repeat
foreach productie X → Y1Y2· · · Ykdo for i = 1 to k, do for j = i + 1 to k do
if alle Yizijn nullable then nullable[X ] ← true end
if Y1· · · Yi −1zijn nullable then
FIRST[X ] ← FIRST[X ] ∪ FIRST[Yi] end
if Yi +1· · · Ykzijn nullable then
FOLLOW[Yi] ← FOLLOW[Yi] ∪ FOLLOW[X ] end
if Yi +1· · · Yj −1zijn nullable then
FOLLOW[Yi] ← FOLLOW[Yi] ∪ FIRST[Yj] end
end end
until FIRST, FOLLOW, nullable veranderen niet meer ;
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Uitgewerkt voorbeeld
Z→d Y→ X→Y
Z→X Y Z Y→c X→a
nullable FIRST FOLLOW
X yes a c a c d
Y yes c a c d
Z no a c d
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Predictive Parsing Tabel
nullable FIRST FOLLOW
X yes a c a c d
Y yes c a c d
Z no a c d
Hieruit kunnen we een Predictive Parsing Tabel opstellen:
I Links NTS, bovenaan TS
I In elk vakje de producties die ermee overeenkomen
a c d
X X→a, X→Y X→Y X→Y
Y Y→ Y→, Y→c Y→
Z Z→XYZ Z→XYZ Z→d, Z→XYZ
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
LL(k)-grammatica
I Talen die geen dubbele ingangen in de Predictive Parsing Table hebben, worden LL(1) genoemd.
I LL(k) staat voor “Left-to-right parse, Leftmost-derivation, k-symbol lookahead”
I Dit wil zeggen:
I
Left-to-right parse: het parsen gebeurt van links naar rechts
I
Leftmost-derivation: linkse afleiding: steeds het meest linkse NTS vervangen
I
k-symbol lookahead: beslissen welke productie
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Veelvoorkomende problemen
I Linkse recursie
I
Bv. E→E+T, E→T
I
FIRST(T ) en FIRST(E + T ) overlappen zowiezo:
LL(1) werkt niet
I
Linkse recursie moet in rechtse worden omgezet
I “Left factoring”
I
Bv. S→if E then S else S, S→if E then S
I
Twee producties voor zelfde NTS beginnen met zelfde deel
I
Left factoring: → S→if E then S X, X→, X→else S
I Foutherstelling
I
Voortgaan na een fout is informatiever
I
Tokens overslaan, vervangen of invoegen
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Overzicht
Introductie Structuur
Van woorden naar zinnen Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing
Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica LR Parsing
Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
YACC
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
De zwakte van LL
LL(k) parsers zijn niet krachtig genoeg
I LL(k) parsers voorspellen welke productie te gebruiken
I Ze kennen enkel de k eerste tokens van de afleiding
I We willen die beslissing achteraf pas nemen
→ LR(k) Parsing
I “Left-to-right parse, Rightmost-derivation, k-token lookahead”
I Left-to-right parse: we parseren van links naar rechts
I Rightmost-derivation: rechte afleiding: steeds het meest rechtse NTS vervangen
I k-symbol lookahead: k tekens vooruit kijken (zelden
> 1)
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
LR(k) techniek
I Hoe kunnen we een rechtse afleiding doen als parser links begint?
I Door een stack van symbolen (TS en NTS) bij te houden
I Op basis van de inhoud van de stack en komende symbolen:
I
Ofwel een token uit input op stack zetten
I
Ofwel aantal symbolen bovenop stack tot 1 NTS
reduceren
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Gebruik van DFA
Hoe implementeren we zo’n LR(k) parser?
I Zoals aangetoond zijn DFA’s niet voldoende krachtig
I We kunnen DFA wel gebruiken op stack ipv input
I Elke “positie” in een productieregel is een toestand
I Overgangen tussen toestanden zijn symbolen (TS of
NTS)
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten
Werking van DFA in LR parser
We kunnen bij elke toevoeging van een element onthouden in welke toestand de DFA daarmee komt, zodat niet telkens de hele stack doorlopen moet worden.
Zie figuur 3.17 in boek.
De acties in deze tabel:
Shift(n) Zet volgend token met state n op stack Reduce(k)
I Haal (# symbolen in rechterkant regel k) van stack
I Noem X de NTS aan linkerkant van regel k I Zoek in state nu bovenop stack de actie voor X I Volg de “goto b” daar, zet X (met state n)
bovenop stack
Accept Shiften van $: klaar
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Opstellen states en overgangstabel
Eerst moeten we alle states opstellen:
I We beginnen met de S’→.S$ state
I de “.” duidt het einde van de stack aan
I Volg nu volgende regels:
I
“.” staat voor NTS X: voeg alle X→.α regels toe aan state (closure)
I
“.” staat voor symbool γ: maak state n met zelfde regel maar “.” na γ (goto)
NTS zet goto(n) in overgangstabel TS zet shift(n) in overgangstabel
I
“.” staat op einde regel k: zet reduce(k) in overgangstabel
I
shift van $ is een accept
I Ga door tot er geen nieuwe states meer zijn.
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Shift-Reduce conflicten
Stel we proberen een LR(0) parser voor deze grammatica:
S→E$ E→T
E→T+E T→x
→ toestand “E→T.+E” en “E→T.” als regels. → Als er
“+” volgt, moet zowel een shift als een reduce gebeuren.
Dit heet een shift-reduce conflict.
→ Deze grammatica is niet LR(0).
→ We hebben iets krachtiger nodig
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
SLR Parser generatie
S→E$ E→T
E→T+E T→x
I LR(0) zet reduce op elk token in tabel
I Beter: enkel bij tokens uit FOLLOW(A) (bij A→ α regel) → minder Shift-Reduce conflicten (wegens minder Reduce’s)
I Dit heet SLR (Simple LR)
I Bovenstaande grammatica is SLR
I SLR is krachtiger dan LR(0)
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
Nog krachtiger dan SLR
SLR vermijdt een deel overbodige reduce’s, maar echt reduce’s laten afhangen van volgend token kan niet. → LR(1) parsers
I In toestandstabellen wordt extra volgend token opgenomen (niet na $)
I Toestanden zijn verschillend als volgend token verschilt
I Reduce acties worden enkel geplaatst bij die
volgende tokens.
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
LALR(1) parsers
Omdat LR(1) tables heel groot kunnen worden, voert men een vereenvoudiging door:
I Toestanden die op volgend token na identiek zijn worden samengenomen
I De bekomen parser heet LALR(1) (Look-Ahead LR(1))
I LALR(1) is krachtiger dan SLR (een SLR taal is ook LALR(1))
I LALR(1) is wel zwakker dan LR(1)
I Bijna alle praktische talen zijn LALR(1)
→ er zijn veel LALR(1) parser generators beschikbaar
(yacc, bison)
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC
Ambiguiteit en Shift-Reduce conflicten
I Stel een grammatica als: “S→if E then S else S”,
“S→if E then S”.
I Dit laat zinnen als “if a then if b then s1 else s2” toe
I Er zijn 2 interpretaties:
I
if a then { if b then s1 else s2 }
I
if a then { if b then s1 } else s2
I Dit wordt een shift-reduce conflict in een LR parse table
I We kunnen kiezen om toch te shiften, door voor het
eerste te kiezen
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Overzicht
Introductie Structuur
Van woorden naar zinnen Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing
Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica LR Parsing
Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
YACC Conflicten
Voor volgende week
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC
YACC
Het genereren van LR(1) (en vooral LALR(1)) parse tables kan geautomatiseerd worden.
De traditionale applicatie hiervoor is YACC (Yet Another Compiler-Compiler),
maar er zijn modernere implementaties zoals Bison.
Werking:
I Neemt als input een “grammar file”
I LALR(1) parse table wordt opgesteld
I Parse table + LALR(1) parse algoritme → C code
I Code bevat functie yyparse()
I
roept functie yylex() aan om de tokens te verkrijgen
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
YACC grammar
De syntax van YACC grammar files:
I Eerst een specifieke header voor declaratie yylex() en yyparse()
I Vernoeming alle lexer tokens (TS)
I Vernoemen startsymbool
I Eventueel wat opties zoals voorrangsregels
I Dan een lijst met alle productieregels
(zie voorbeeld)
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators
YACC en conflicten
I YACC detecteert shift-reduce en reduce-reduce conflicten
I Standaard is dit geen error, maar wordt dit gedaan:
I
Bij Shift-Reduce conflicten wordt shift gekozen
I
Bij Reduce-Reduce conflicten wordt eerst vermeldde regel gekozen
I Er kunnen prioriteitsregels gegeven worden om dit gedrag te veranderen
(zie voorbeeld)
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers
Parser generators YACC Conflicten Voor volgende week
Semantiek is voor volgende week
Men kan geneigd zijn een parser teveel te laten doen:
I De parser moet enkel de structuur van de zinnen achterhalen
I Niet alle operatoren mogen misschien op alle argumenten
I Zaken als data-types horen niet thuis in de grammatica
→ Deze dingen worden in de semantische analyse gedaan
De Parser Pieter Wuille
Overzicht
Introductie Structuur Van woorden naar zinnen
Wat we hebben Kan dat niet met lex?
Context-Free Grammar Het parsen
Predictive parsing Eenvoudige grammatica First en Follow sets De predictive parser LL(k)-grammatica
LR Parsing Techniek LR(0) parsers SLR parsers LR(1) parsers Parser generators