Ontleden nNon-deterministisch m.b.v. Parser-combinators nDeterministisch m.b.v. Stack-machine type Parser a b = [a] [ (b, [a]) ] type Parser a b = [a] (b, [a]) Eén oplossing Mag ambigu zijn
Deterministisch ontleden …m.b.v. Stack-machine nLL-ontleden uLeft-to-right input processing uLeftmost derivation nLR-ontleden uLeft-to-right input processing uRightmost derivation “Top-down” ontleden “Botton-up” ontleden
Stackmachine voor LL-ontleden check :: String Bool check input = run [’S’] input run :: Stack String Bool run [ ] [ ]= True run (a:as)(x:xs) | isT a && a==x = run as xs | isN a = run (rs++as) (x:xs) | otherwise= False where rs= select a x run _ _ = False
Kiezen van de regel bij LL-ontleden select a x = snd ( hd ( filter ok ( prods gram))) where ok = n==a && x lahP gram p lahP
Grammatica voor expressies met + en * en () E T E T + E T F T F * T F N F ( E ) N 1 N 2 N 3 Linksfactoriseren (geen regels met gelijk beginstuk): E T P P P + E T F M M M * T F N F ( E ) N 1 N 2 N 3
Bepalen van empty, first, lookahead E T P P P + E T F M M M * T F N F ( E ) N 1 N 2 N 3 S E # E T P P P + E T F M M M * T F N F ( E ) N 1 N 2 N 3 nee ja nee ja nee ( * follow(P) follow(M) first(E) first(T) first(F) first(N) + * ( ( ) # ) #
Stackmachine voor LR-ontleden check :: String Bool check input = run [ ] input run :: Stack String Bool run [’S’] [ ]= True run [’S’] _= False run as(x:xs)= case aktie of Shift run (x:as) xs Reduce a n run (a:drop n as) (x:xs) Error False where aktie = select’ as x
Kiezen van de regel bij LR-ontleden select’ as x | null items = Error | null redItems= Shift | otherwise= Reduce a (length rs) where items= dfa as redItems= filter red items (a, rs, _)= hd redItems dfa red
Items nEen item is een productieregel met daarin een “cursorpositie” Bijvoorbeeld productieregel: …geeft bestaansrecht aan deze items: F ( E ) F 2 M M
Toestandsautomaat nConstructie van een NFA: utoestanden zijn Items bij de grammatica A A X u…met toestandsovergangen: A X X Z S ustarttoestand: X Voor elke regel X
E T + E E T + E E T + E E T + E S E S E E TE T T NT N T N * T T N * TT N * TT N * T T ( E ) T ( E ) T ( E ) T ( E ) E T E T + E T N T N * T T ( E ) S E E T E T + E T N T N * T T ( E )
Transformatie NFA DFA nNieuwe toestanden: verzamelingen van oude toestanden nNieuwe overgangen: als er een overgang tussen een van de elementen uit de verzamelingen was
S E E T E T + E T ( E ) T N * T T N E T + E E T + E E T E T + E T ( E ) T N * T T N E T E T + E T N * T T N T N * T T ( E ) T N * T T N T ( E ) E T E T + E T ( E ) T N * T T N T ( E ) T ( E ) T N * T S E E T N N N N T T ( E E ( ) (( + * T
Kiezen van de regel bij LR-ontleden select’ as x null items = Error null redItems= Shift otherwise= Reduce a (length rs) where items= dfa as redItems= filter red items (a, rs, _)= hd redItems dfa red red (a,r,c)= c == length r && x follow a E T E T + E red: Cursor aan het eind
Stackmachine voor LR-ontleden run :: Stack String Bool run [’S’] [ ]= True run [’S’] _= error run as(x:xs)= case aktie of Shift run (x:as) xs Reduce a n run (a:drop n as) (x:xs) Error error where aktie = select’ as x select’ as x = …… where items = dfa as …… Zonde van het werk om dfa steeds opnieuw uit te rekenen
Optimalisatie uitrekenen DFA nDFA wordt steeds uitgerekend op de symbolen in de stack nBewaar die waarde op de stack erbij
S E E T E T + E T ( E ) T N * T T N E T + E E T + E E T E T + E T ( E ) T N * T T N E T E T + E T N * T T N T N * T T ( E ) T N * T T N T ( E ) E T E T + E T ( E ) T N * T T N T ( E ) T ( E ) T N * T S E E T N N N N T T ( E E ( ) (( + * S E E T E T + E T ( E ) T N * T T N E T + E E T + E E T E T + E T ( E ) T N * T T N E T E T + E T N * T T N T N * T T ( E ) T N * T T N T ( E ) E T E T + E T ( E ) T N * T T N T ( E ) T ( E ) T N * T S E T*N(*NT*N(*N T
Optimalisatie uitrekenen DFA nDFA wordt steeds uitgerekend op de symbolen in de stack nBewaar die waarde op de stack erbij nBereken eenmalig twee tabellen: ugoto:: (Int, Nonterm) Int uaction:: (Int, Term) Action type Action = Shift Int | Reduce Nonterm Int | Error | Accept
Goto en Action tabellen ngoto(i,X) = j ij X naction(i,x) = Reduce a |r| a r i && x follow a S N i naction(i,EOF) = Accept otherwisenaction(i,x) = Error a a x b i naction(i,x) = Shift j j
Soorten LR ontleden Zoals beschreven is alleen nog maar… nSLR: Simpel LR naction(i,x) = Reduce a |r| a r i && x follow a Te royaal: followset onafhankelijk van de context nSLR reduceert (iets) te vaak
Van SLR naar LR nSLR item: Regel uit grammatica met cursor T ( E ) nLR item: idem, plus bijbehorende follow-set T ( E ) + )+ )
LALR Wordt in de praktijk het meest gebruikt (yacc, Bison, …) Van LR naar LALR nSLR (Simpel LR) nadeel: reduceert te vaak nLR: met contextafhankelijke followsets nadeel: DFA krijgt erg veel toestanden nLALR (Lookahead LR) compromis: uMerge DFA-toestanden waarvan de items alleen qua lookahead verschillen