














May 19
   Purpose: Read Prolog terms (with extended syntax).

/*  Modified by Alan Mycr
to regularise the functor modes.
    This is both easier to understand (ther
e no more '?'s),
    and also fixes bugs concerning the curious interact
of cut with
    the state of parameter instantiation.

    Since thi
le doesn't provide "metaread", it is considerably
    simplified
he token list format has been changed somewhat, see
    th






















































































































































































































































x






















y, [t
,



















































































































































































































































































































































































, Term, Leftover), all_read(Leftover)
	    |   syntax_error(Tokens)
	    ),
	!,
	Answer = Term.


%   all_read(+Tokens)
%   checks that there are no unparsed tokens left over.

all_read([]) :- !.
all_read(S) :-
	syntax_error([operator,expected,after,expression], S).


%   expect(Token, TokensIn, TokensOut)
%   reads the next token, checking that it is the one expected, and
%   giving an error message if it is not.  It is used to look for
%   right brackets of various sorts, as they're all we



















































































































































































































































































































































































rg1, 










































































































Arg1, S2),
	read_args(S2, RestArgs, S3),
	Term =.. [Functor,Arg1|RestArgs], !,
	exprtl0(S3, Ter
recedence, Answer, S).

read(atom






















































































































































































rg1, 





































0, Term, S2),
	expect(')', S2, S3), !,
	exprtl0(S3, Term, Precedence, Answer, S).

read(' (', S1, Precedence, Answer, S) :- !,
	read(S1, 1
 Term, S2),
	expect(')', S2, S3), !,
	exprtl0(S3, Term, Precedence, Answer, S).

read('{', ['}'|S1], Precedence, Answer, S) :- !,
	exprtl0(S1, '{}', Precedence, Answer, S).

read('{', S1, Preceden
Answer, S) :- !,
	read(S1, 1200, Term, S2),
	expect('}', S2, S3), !,
	exprtl0(S3, '{}'(Term), Precedence, Answer, S).

read(string(List), S0, Precedence, Answer, S) :- !,
	exprtl0(S0, List, Pr
ence, Answer, S).

read(Token, S0, _, _, _) :-
	syntax_error([Token,cannot,start,an,expression], S0).


%   read















')' a
e



















 Term, S2), !,
	read_args(S2, Rest, S).
read_args([')'|S], [], S) :- !.
read_args(S, _, _) :-
	syntax_error([', or )',expected,in,arguments], S).


%   read_list(+Tokens, -TermList, -LeftOver)
%   parses {',' expr(999)} ['|' expr(999)] ']' and returns a list of terms.

read_list([','|S1], [Term|Rest], S) :- !,
	read(S1, 999, Term, S2), !,
	read_list(S2, Re













, Rest, S2), !,
	expect(']', S2, S).
read_list([']'|S], [], S) :- !.
read_list(S, _, _) :-
	syntax_error([', | or ]',expected,in,list], S).


%   after_prefix_op(+Op, +Prec, +ArgPrec, +Rest, +Precedence, -Ans, -LeftOver)

after_prefix_op(Op, Oprec, _, S0, Precedence, _, _) :-
	Precedence < Oprec, !,
	syntax_error([prefix,operator,Op,in,context,
		with,precedence,Precedence], S0).

after_prefix_op(Op, Oprec, _, S0, Precedence, Answer, S) :-
	peepop(S0, 



















































































































































































































































































>= P.
prefix_is_atom(',', P) :- 1000 >= P.
prefix_is_atom([],  _).


%   exprtl0(+Tokens, +Term,
ec, -Answer, -LeftOver)
%   is called by read/4 after it has read a primary (the Term).
%   
hecks for following postfix or infix operators.

exprtl0([atom(F)|S1], Term, Precedence,
wer, S) :-
	ambigop(F, L1, O1, R1, L2, O2), !,
	(   exprtl([infixop(F,L1,O1,R1)|S1],





















































































































0, !,
	read(S1, 1000, Next, S2), !,
	exprtl(S2, 1000, (Term,Next), Precedence, Answer, S).

exprtl0(














0, !,
	read(S1, 1100, Next, S2), !,
	exprtl(S2, 1100, (Term;Next), Precedence, Answer, S).

exprtl0([Thing|S1], _, _, _, _) :-
	cant_follow_expr(Thing, Culprit), !,
	syntax_error([Culprit,follows,expression], [Thing|S1]).

exprtl0(S, Term, _, Term, S).


cant_follow_expr(atom(_),	atom).
cant_follow_expr(var(_,_),	variable).
cant_follow_expr(integer(_),	integer).
cant_follow_expr(string(_),	string).
cant_follow_expr(' (',		bracket).
cant_follow_expr







































































































































































































0, C < 1000, !,
	read(S1, 1000, Next, S2), /*!,*/
	exprtl(S2, 1000, (Term,Next), Precedence, Answer, S).

exprtl(['|'|S1], C, Term, Precedence, Answer, S) :-
	Precedence >= 1100, C < 1100, !,
	read(S1, 1100, Next, S2), /*!,*































































































































































































































































































































	display_token(Head), !,
	d
ay_list(Tail).
display_l
[]) :-
	ttynl.

synt
rror(List) :-
	r
ded(syntax_e
, length
erEr
















































99).
display_list([Head|Tail], BeforeError) :-
	display_token(Head),
	ttyput(32),
	Left is BeforeError-1, !,
	display_list(Tail, Left).
display_list([], _) :-
	ttynl.

display_token(atom(X))	  :- !,	display(X).
display_token(var(_,X))	  :- !,	display(X).
display_token(integer(X)) :- !,	display(X).
display_token(string(X))  :- !,	display(X).
display_token(X)	  :-	display(X).

%  From here down is new stuff to handle distfix operators.

dÿ
ÿ


























	atom(Type),
	(   (   Type = fx,	Right is Priority-1
	    ;   Type = fy,	Right = Priority
	    ),
	    distfix_keys(Pattern, [Atom|Keys], RestPattern),
	    distfix_pattern(RestPattern, Right, P_
),
	    !,
	    assert(is_distprefix_op(Atom, Priority, Keys, P_form, Template))
	;   (	Type = xfx,	Right is Priority-1
	    ;	Type = xfy,	Right = Priority
	    ;	Type = yfx,	Right is Priority


























































































































































).
  
s




















































































































































































































 Variable, T),
	T = [],
	!,	%  not sure if I want this cut or not
	distfix_r



























































































































































































































































































































































