home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
aijournl
/
ai_aug88.arc
/
PROLCODE.ASC
< prev
Wrap
Text File
|
1988-05-04
|
10KB
|
292 lines
/* 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