220 likes | 314 Views
Ontleden. Non-deterministisch m.b.v. Parser-combinators Deterministisch m.b.v. Stack-machine. type Parser a b = [a] [ ( b , [a] ) ]. Mag ambigu zijn. type Parser a b = [a] ( b , [a] ). Eén oplossing. Deterministisch ontleden. …m.b.v. Stack-machine LL -ontleden
E N D
Ontleden • Non-deterministischm.b.v. Parser-combinators • Deterministischm.b.v. Stack-machine type Parser ab = [a][ (b, [a]) ] Mag ambigu zijn type Parser ab = [a] (b, [a]) Eén oplossing
Deterministisch ontleden …m.b.v. Stack-machine • LL-ontleden • Left-to-right input processing • Leftmost derivation • LR-ontleden • Left-to-right input processing • Rightmost 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 regelbij LL-ontleden select a x = snd ( hd ( filter ok ( prods gram))) • where • ok p@(n,_) = 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 E T P P P +E T F M M M *T F N F ( E ) N 1 N 2 N 3 Linksfactoriseren (geen regels met gelijk beginstuk):
nee ( 1 2 3 first(E) (1 2 3 nee ( 1 2 3 first(T) ja + follow(P) ) # + (1 2 3 nee ( 1 2 3 first(F) ja * follow(M) + ) # * nee ( 1 2 3 first(N) 1 2 3 ( nee 1 2 3 1 2 3 Bepalen van empty, first, lookahead S E # E T P P P +E T F M M M *T F N F ( E ) N 1 N 2 N 3 E T P P P +E T F M M M *T F N F ( E ) N 1 N 2 N 3
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 regelbij 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
Bijvoorbeeld productieregel: F(E) F2 M …geeft bestaansrecht aan deze items: F• (E) F •2 M • F( •E) F 2 • F( E•) F( E) • Items • Een item is een productieregelmet daarin een “cursorpositie”
…met toestandsovergangen: X A X A X • starttoestand: Voor elke regelX X Z S Toestandsautomaat • Constructie van een NFA: • toestanden zijn Items bij de grammatica A
S E E T +E E T+ E S E E T +E T ( E ) T ( E) E T +E T ( E ) E T E T T N*T T (E ) T N T N T N*T T N* T T N*T 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 NFADFA • Nieuwe toestanden:verzamelingen van oude toestanden • Nieuwe overgangen:als er een overgang tussen een van de elementen uit de verzamelingen was
+ E S E E T E T +E T (E ) T N*T T N T E T E T +E E T+ E E T E T +E T (E ) T N*T T N E T+E T T T N*T T N N N N E * N T N* T T (E ) T N*T T N S E ( E ( T ( E ) E T E T +E T (E ) T N*T T N T (E ) ) T T (E ) T N*T ( (
Kiezen van de regelbij 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 E T E T +E dfa red red: Cursor aanhet eind • red (a,r,c) = c == length r • && x follow a
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 werkom dfa steeds opnieuwuit te rekenen
Optimalisatieuitrekenen DFA • DFA wordt steeds uitgerekendop de symbolen in de stack • Bewaar die waarde op de stack erbij
+ E S E E T E T + E T ( E ) T N * T T N S E E T E T +E T (E ) T N*T T N T E T E T + E E T E T +E 5 E T + E E T E T + E T ( E ) T N * T T N E T+ E E T E T +E T (E ) T N*T T N 1 E T + E E T+E 7 T T N * T T N T N*T T N N N 3 6 N E * N T N * T T ( E ) T N * T T N T N* T T (E ) T N*T T N S E S E 2 ( E ( T ( E ) E T E T + E 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 ) 9 11 ) T T (E ) T ( E ) 10 T N * T T N*T 4 ( ( 8 T T * N ( * N T * N ( * N @ 4 11 3 8 11 3 1
Optimalisatieuitrekenen DFA • DFA wordt steeds uitgerekendop de symbolen in de stack • Bewaar die waarde op de stack erbij • Bereken eenmalig twee tabellen: • goto :: (Int, Nonterm) Int • action :: (Int, Term) Actiontype Action = Shift Int | Reduce Nonterm Int | Error | Accept
X i j a a xb j i • action(i,x) = Shift j a r i • action(i,x) = Reduce a |r| && x follow a S N i • action(i,EOF) = Accept otherwise • action(i,x) = Error Goto en Action tabellen • goto(i,X) = j
a r i • action(i,x) = Reduce a |r| && x follow a Soorten LR ontleden Zoals beschreven is alleen nog maar… • SLR: Simpel LR Te royaal:followset onafhankelijkvan de context • SLR reduceert (iets) te vaak
LR item:idem, plus bijbehorende follow-set T (E ) +) Van SLR naar LR • SLR item:Regel uit grammatica met cursor T (E )
Van LR naar LALR • SLR (Simpel LR)nadeel: reduceert te vaak • LR: met contextafhankelijke followsetsnadeel: DFA krijgt erg veel toestanden • LALR (Lookahead LR) compromis: • Merge DFA-toestanden waarvan de itemsalleen qua lookahead verschillen LALR Wordt in de praktijk het meest gebruikt (yacc, Bison, …)