%   File   : READIN.PL
%   Author : Lawrence Byrd
%   Updated: 15 November 1983, 14-8-87
%   Purpose: Read in a sentence as a list of words.

:- public
	read_in/1.

:- mode
	read_in(?),
	ri_rest(+, -),
	ri_word(-, ?, ?),
	ri_words(-, ?, ?),
	ri_letdig(-, ?, ?),
	ri_space(?, ?),
	ri_digits(-, ?, ?),
	ri_digit(+),
	ri_lcase(+, -).



%   read_in(Words)
%   reads characters until it finds a period (. ? or !) at the end of a
%   line, that is, followed by any number of spaces but nothing else.
%   It then parses this list of characters using grammar rules.  Words
%   are sequences of letters (in either case, forced to lower case),
%   or strings of digits, or punctuation marks.  Other characters act
%   as word separators, and are otherwise ignored.  The subroutines in
%   this file all start with ri_, to avoid a collision with a user's
%   predicates.


read_in(Words) :-
	get(C1),
	get0(C2),
	ri_rest(C2, Chars), !,
	ri_words(Found, [C1,C2|Chars], []), !,
	Words = Found.

ri_rest(C, Chars) :-				%  check for period NL
	(C=33 ; C=46 ; C=63),			%  ! . ?
	repeat,
		get0(C1),
		C1 =\= 32,			%  next non-blank
		!,
		(	C1 = 10,
			!,
			Chars = []		%  was end of line
		;
			Chars = [C1|Chars1],
			ri_rest(C1, Chars1)
		).				%  false alarm

ri_rest(C, [C1|Chars]) :-			%  all control chars
	C =< 32, !,				%  act as spaces.
	get(C1),				%  skip other spaces
	ri_rest(C1, Chars).
ri_rest(_, [C1|Chars]) :-
	get0(C1),
	ri_rest(C1, Chars).


ri_words([Word|Words]) -->
	ri_word(Word), !,
	ri_space, ri_words(Words).
ri_words([]) --> [].

ri_word(Word) -->
	[C], {ri_letter(C, D)}, !,		%  either case letter
	ri_letdig(Chars),			%  parse rest of word
	{name(Word, [D|Chars])}.
ri_word(Word) -->
	[C], {ri_digit(C)}, !,			%  digit
	ri_digits(Chars),			%  parse rest of number
	{name(Word, [C|Chars])}.
ri_word(Word) -->
	[C],					%  can't a space, so it
	{name(Word, [C])}.			%  is punctuation

ri_letdig([D|Chars]) -->
	[C], {ri_letter(C, D)}, !,
	ri_letdig(Chars).
ri_letdig([C|Chars]) -->
	[C], {ri_digit(C)}, !,
	ri_letdig(Chars).
ri_letdig([]) --> [].

ri_digits([C|Chars]) -->
	[C], {ri_digit(C)}, !,
	ri_digits(Chars).
ri_digits([]) --> [].

ri_space -->
	[C], {C=<32}, !,
	ri_space.
ri_space --> [].

ri_digit(C) :-
	C >= 48, C =< 57.	%  0..9

ri_letter(C, C) :-
	C >= 97, C =< 122, !.	%  a..z
ri_letter(C, D) :-
	C >= 65, C =< 90,	%  A..Z
	D is C+32.		%  32 is "a"-"A"

