home *** CD-ROM | disk | FTP | other *** search
- /* This is a parser for Prolog program schemes as described in
- the August Expert Toolbox column in AI Expert.
-
- DEEP STRUCTURE OF SCHEMA INPUT
-
- % a schema definition is a list of items (clauses or comments)
- scheme_def --> item | scheme_def | []
-
- % an item is a clause or comment
- item --> clause | comment
-
- % an clause is a fact or rule
- clause --> fact | rule
- %%%%%%%%%
-
- % a fact is a term followed by a period
- fact --> term .
-
- % a rule is a term (the head) followed by the neck symbol
- % followed by a (rule) body followed by a period
- rule --> term :- body .
-
- % a body is a comment followed by body
- % or a term followed by a comma followed by a body
- % or a term
- body --> comment body | term , body | term | comment
-
- % a term is a functor symbol followed by an argument list
- % or a set or a constant or a variable
- term --> functor_symbol arg_list | set | constant | variable
-
- % an arg_list is a term_list in parens
- arg_list --> ( termlist )
-
- % a term_list is a term followed by a ter_list or a term
- term_list --> term term_list | term
-
- % a functor symbol is an atom or variable
- functor_symbol --> atom | variable
-
- % a set is a list of terms or the empty list
- set --> [ set_termlist | []
-
- % a termlist is a term followed by a comma followed by a termlist
- % or a term followed by a right bracket
- set_termlist --> term, set_termlist | term ]
-
-
- % a comment is a comment starter followed by a (comment)
- % word list
- comment --> start_comment word_list
-
- % a word_list is a word followed by a word_list
- % or an end of comment
- word_list --> word word_list | end_comment
-
- % a word is a variable or a token
- word --> variable | token
-
- */
-
- % def. of comment start marker
- % start_comment --> /*
-
- % def. of comment end marker
- % end_comment --> */
-
- %%%%%%%%%%%%%%%%%%%%% traces %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % to turn off trace, comment out the next line.
- p_trace.
- p_trace(X) :- p_trace, trace_message(X),!.
- p_trace(_).
- p_trace(X,Y) :- p_trace, trace_message(X,Y),!.
- p_trace(_,_).
-
-
- trace_message(X):- leadoff, write_message(X).
- trace_message(X,Y):- leadoff, write_message(X), write_message(Y).
-
- leadoff :- nl,
- write('**TRACE***: ').
-
- write_message(X) :- string(X),!, write(X).
- write_message(X) :- writeq(X).
-
- %%%%%%%%%%%%%%%%%%%%% scheme_def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- scheme_def(Scheme) --> item(H), scheme_def( T),
- {Scheme= [ H | T],
- p_trace($Scheme : $, Scheme)},!.
- scheme_def([],[],[]) :- p_trace($Scheme = [] $),!.
-
- %%%%%%%%%%%%%%%%%%%%% item %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- item(X) --> fact(X) , !,{p_trace($item : $, X)}.
- item(X) --> rule(X) , !,{p_trace($item : $, X)}.
- item(X) --> comment(X) , !,{p_trace($item : $, X)}.
-
-
- %%%%%%%%%%%%%%%%%%%%% fact %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- fact(fact(Fact)) --> term( Fact), [$.$],
- {p_trace($Fact : $,Fact)}.
-
- %%%%%%%%%%%%%%%%%%%%% rule %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- rule(Rule) --> term(Head), [$:-$],
- {p_trace($starting rule body$)},
- body(Body),
- {Rule = rule((Head :- Body)),
- p_trace($Rule : $,Rule)}.
-
- %%%%%%%%%%%%%%%%%%%%% body %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- body( Body ) --> comment(H), body(T),!,
- { Body = [H | T],
- p_trace($Body : $,Body)}.
- body( Body ) --> term(H), [$,$], body(T),!,
- { Body = [H | T],
- p_trace($Body : $,Body)}.
- body( [Term]) --> term( Term), [$.$],!,
- {p_trace($Body : $, Term)}.
- body( [Comment]) --> comment(Comment), [$.$],!,
- {p_trace($Body : $, Comment)}.
-
- %%%%%%%%%%%%%%%%%%%%% term %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % a term is a functor symbol followed by an argument list
- % or a set or a constant or a variable or a set
- term(Term) --> variable(Variable), [$($],
- {p_trace($entering arg_list $)},
- arg_list(Arg_list), !,
- {Term = var_functor_term( Variable, Arg_list),
- p_trace($term: $,Term)}.
-
- term(Term) --> is_atom(X), [$($], arg_list(Arg_list), !,
- {Term = const_functor_term( X, Arg_list),
- p_trace($term: $,Term)}.
-
- term(X) --> set(X), ! , { p_trace($term: $,X)}.
-
- term(X) --> is_atomic(X), ! , { p_trace($term: $,X)}.
-
- term(X) --> variable(X), ! , { p_trace($term: $,X)}.
-
- %%%%%%%%%%%%%%%%%%%%% arg_list %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- arg_list(Arglist = [Term | Termlist]) --> term(Term) ,
- arg_list_hlpr(Termlist),!,
- { Arglist = [Term | Termlist],
- p_trace($arg_list: $,Arglist)}.
-
- arg_list_hlpr([]) --> [$)$] , !,
- { p_trace($arg_list_hlpr: []$)}.
- arg_list_hlpr(Termlist) --> [$,$] , arg_list( Termlist) , !,
- { p_trace($arg_list_hlpr: $,
- Termlist )}.
-
- %%%%%%%%%%%%%%%%%%%%% set %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % set --> [ termlist
- set( Set ) --> [$[$], termlist(Set),!,{p_trace($Set : $,Set)}.
- % set --> [ ]
- set( Set ) --> [$[$,$]$],{Set = [], p_trace($Set : $,Set)}.
-
- %%%%%%%%%%%%%%%%%%%%% termlist %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % termlist --> term, termlist | term
- termlist(Termlist) --> term(H), termlist_hlpr(T),
- { Termlist = [H | T],
- p_trace($termlist : $, Termlist)}.
- termlist_hlpr([]) --> [$]$],!,{p_trace($termlist : []$)}.
- termlist_hlpr(T) --> [$|$], term(T),[$]$],!,
- {p_trace($termlist : $, T)}.
- termlist_hlpr(T) --> comma($,$), termlist(T), !,
- {p_trace($termlist : $, T)}.
-
- %%%%%%%%%%%%%%%%%%%%% comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- comment( Comment ) --> start_comment( H), word_list(T),
- { Comment = comment([H | T]),
- p_trace($Comment : $,Comment) }.
-
- %%%%%%%%%%%%%%%%%%%%% end_comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % the straightforward implementation, like that of
- % start_comment, did not work properly
- end_comment($*/$) --> [$*/$].
-
- %%%%%%%%%%%%%%%%%%% start_comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- start_comment($/*$) --> [$/*$].
-
- %%%%%%%%%%%%%%%%%%%%% word_list %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % word_list --> word word_list | end_comment
- word_list( [H | T] ) --> word(H), word_list( T ), !.
- word_list( [H] ) --> end_comment( H ).
-
- %%%%%%%%%%%%%%%%%%%%% word %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % word --> variable | token
- word(X) --> variable(X),!.
- % don't let an end of comment be a word
- word(X) --> end_comment(X), !, {fail}.
- word(X) --> token(X).
-
- %%%%%%%%%%%%%%%%%%%%% variable %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % returns a variable inside a var(*) marker
- variable(var(X)) --> [X], % get the next token
- % get its first character
- {nth_char(0,X,Char),
- % see if it's upper case
- is_uc(Char)}.
-
- %%%%%%%%%%%%%%%%%%%%% is_atom %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % get an atom from input stream
- is_atom(X) --> [X], % get the next token
- % get its first character
- {nth_char(0,X,Char),
- % see if it's lower case
- is_lc(Char)}.
-
-
- %%%%%%%%%%%%%%%%%%%%% is_atomic %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % get an atomic structure from input stream
- is_atomic(X) --> [X], % get the next token
- % see if it's atomic
- {atomic(X)},!.
-
-
- %%%%%%%%%%%%%%%%%%%%% comma %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- comma(X) --> [$,$],!.
-
- %%%%%%%%%%%%%%%%%%%%% token %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % returns an arbitrary token as itself
- token(X) --> [X],!.
-
- %%%%%%%%%%%%%%%%%%%%% test %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- test :-
- % Input is a tokenized user-supplied scheme
- Input =
- [$/*$, $Predicate_name$, $User_defined_purpose$, $*/$,
- $/*$, $Predicate_name$, $maps$, $null$, $set$, $into$, $null$, $set$, $*/$,
- $Predicate_name$, $($, $[$, $]$, $,$, $[$, $]$, $)$, $:-$, $!$, $.$,
- $/*$, $recursive$, $rule$, $for$, $Predicate_name$, $*/$,
- $Predicate_name$, $($, $[$, $H$, $|$, $T$, $]$, $,$,
- $[$, $H1$, $|$, $T1$, $]$, $)$,
- $:-$,
- $/*$, $apply$, $Element_predicate$, $to$, $head$, $of$, $list$, $*/$,
- $Element_predicate$, $($, $H$, $,$, $H1$, $)$, $,$,
- $/*$, $recurse$, $with$, $Predicate_name$, $on$,
- $tail$, $of$, $list$, $*/$,
- $Predicate_name$, $($, $T$, $,$, $T1$, $)$, $.$],
- % which is parsed using the top level grammar rules
- scheme_def(Structure, Input, []),
- % and the result is written out
- nl, write($scheme_def = $), writeq(Structure), nl.
-
- e :-
- shell($pe2 proparse.ari$),
- nl,write($reconsulting proparse.ari$),
- reconsult($proparse.ari$).
-
- /*
- test0 :-
- Input = [ $/*$, $recursive$, $rule$, $for$, $Predicate_name$, $*/$],
- comment( Structure, Input, []),
- nl, write($comment = $), writeq(Structure), nl.
-
- test3 :-
- Input =
- [$Predicate_name$, $($, $[$, $]$, $,$, $[$, $]$, $)$, $:-$, $!$, $.$],
- rule( Structure, Input, []),
- nl, write($rule = $), writeq(Structure), nl.
-
- test4 :-
- Input = [$[$, $H$, $|$, $T$, $]$],
- set( Structure, Input, []),
- nl, write($set = $ ), writeq(Structure), nl.
-
- test :- test0, test3, test4.
- */
- ]$],
- set( Structure, In