8.4 Top Down Parsing in Prolog

It is easy to turn this recognizer into a parser --- and (unlike with bottomup_recognizer.pl ) it's actually worth doing this, because it is efficient on small grammars. As is so often the case in Prolog, moving from a recognizer to a parser is simply a matter of adding additional arguments to record the structure we find along the way.

Here's the code. The ideas involved should be familiar by now. Read what is going on in the fourth argument position declaratively:

?- op(700,xfx,--->).
 
parse_topdown(Category,[Word|Reststring],Reststring,[Category,Word]) :-
        lex(Word,Category).
parse_topdown(Category,String,Reststring,[Category|Subtrees]) :-
        Category ---> RHS,
        matches(RHS,String,Reststring,Subtrees).
 
matches([],String,String,[]).
matches([Category|Categories],String,RestString,[Subtree|Subtrees]) :-
        parse_topdown(Category,String,String1,Subtree),
        matches(Categories,String1,RestString,Subtrees).

And here's the new driver that we need:

parse_topdown(String,Parse) :-
        parse_topdown(s,String,[],Parse).

Time to play. Here's a simple example:

parse_topdown([vincent,fell]).
 
[s,[np,[pn,vincent]],[vp,[iv,fell]]]
yes

And another one:

parse_topdown([vincent,shot,marsellus]).
 
[s,[np,[pn,vincent]],[vp,[tv,shot],[np,[pn,marsellus]]]]
yes

And here's a much harder one:

parse_topdown([jules,believed,the,robber,who,shot,the,robber,who,shot,the,
          robber,who,shot,marsellus,fell]).
 
[s,[np,[pn,jules]],[vp,[sv,believed],[s,[np,[det,the],
[nbar,[n,robber],[rel,[wh,who],[vp,[tv,shot],[np,[det,the],
[nbar,[n,robber],[rel,[wh,who],[vp,[tv,shot],[np,[det,the],
[nbar,[n,robber],[rel,[wh,who],[vp,[tv,shot],
[np,[pn,marsellus]]]]]]]]]]]]]],[vp,[iv,fell]]]]]
yes

As this last example shows, we really need a pretty-print output!


Patrick Blackburn and Kristina Striegnitz
Version 1.2.4 (20020829)