150 likes | 219 Views
Explore the concept of Bottom-Up Filtering in parser design, making parsing more efficient by focusing on left corner parsing and utilizing data structures for shift/reduce operations.
E N D
Bottom Up Filtering • We know the current input word must serve as the first word in the derivation of the unexpanded node the parser is currently processing. • Therefore the parser should not consider grammar rule for which the current word cannot serve as the "left corner" • The left corner is the first word (or preterminal node) along the left edge of a derivation.
Left Corner fl fl The nodes Verb and prefer are each left corners of VP
Left Corner • B is a left corner of A iffA * Bαfor non-terminal A, pre-terminal B and symbol string α. • Possible left corners of all non-terminal categories can be determined in advance and placed in a table.
How to use the Left Corner Table • If attempting to parse category A, only consider rules A → Bαfor which category(current input) LeftCorners(B) • S → NP VPS → Aux NP VPS → VP
Next Week • Problems with top down parser • left recursion • repeated work • Early Algorithm • Assignment • See J & M ch 10
Top Down Implementation • Parser takes form of predicate parse(C,S1,S) : parse a constitutent C starting with input string S1 and ending with input string S.?- parse(s,[the,dog,barked],[]). • If C is a pre-terminal category, check, use lexicon to determine that current input word has that category. • Otherwise expand C using grammar rules and parse rhs constitutents.
Top Down Parser parse(C,[Word|S],S) :- word(C,Word). parse(C,S1,S) :- rule(C,Cs), parse_list(Cs,S1,S). parse_list([],S,S). parse_list([C|Cs],S1,S) :- parse(C,S1,S2), parse_list(Cs,S2,S).
% Grammar rule(s,[np,vp]). rule(np,[d,n]). rule(vp,[v]). rule(vp,[v,np]). % Lexicon word(d,the). word(n,dog). word(n,cat). word(n,dogs). word(n,cats). word(v,chase). word(v,chases). Recoding the Grammar/Lexicon
Shift/Reduce Algorithm • Two data structures • input string • stack • Repeat until input is exhausted • Shift word to stack • Reduce stack using grammar and lexicon until no further reductions • Unlike top down, algorithm does not require category to be specified in advance. It simply finds all possible trees.
Shift/Reduce Operation →| Step Action Stack Input 0 (start) the dog barked 1 shift the dog barked 2 reduce d dog barked 3 shift dog d barked 4 reduce n d barked 5 reduce np barked 6 shift barked np 7 reduce v np 8 reduce vp np 9 reduce s
parse(S,Res) :- sr(S,[],Res). sr(S,Stk,Res) :- shift(Stk,S,NewStk,S1), reduce(NewStk,RedStk), sr(RedStk,S1,Res). sr([],Res,Res). shift(X,[H|Y],[H|X],Y). reduce(Stk,RedStk) :- brule(Stk,Stk2), reduce(Stk2,RedStk). reduce(Stk,Stk). Shift/Reduce Implementation
Notice that the reduce operation always operates on the leftmost elements of the stack. Rules are stored in reverse order. We can reuse existing lexicon reduce(Stk,RedStk) :- brule(Stk,Stk2), reduce(Stk2,RedStk). reduce(Stk,Stk). %grammar brule([vp,np|X],[s|X]). brule([n,d|X],[np|X]). brule([np,v|X],[vp|X]). brule([np,v|X],[vp|X]). %interface to lexicon brule([Word|X],[C|X] :- word(C,Word). Shift/Reduce Implementation
Principles for success • Left recursive structures must be found, not predicted • Empty categories must be predicted, not found • An alternative way to fix things • Grammar transformations can fix both left-recursion and epsilon productions • But then you parse the same language but with different trees