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]) :-
(
/*** Uncomment the following lines to see the steps the top
)(
down parser takes ***/
)(
%%% nl, write('String to recognize: '), write([Word|Reststring]),
)(
%%% nl, write('Category to recognize: '), write(Category),
)
lex(Word,Category).
parse_topdown(Category,String,Reststring,[Category|Subtrees]) :-
Category ---> RHS,
(
/*** Uncomment the following lines to see the steps the top
)(
down parser takes ***/
)(
%%% nl, write('Rule: '), write((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: