CONST (********************************************************************) (* STRING IMPLEMENTATION CODE *) (* Constants for String ADT *) (*******************************************************************) (* Maximum number of characters in a string. *) MaxString = 256; TYPE (********************************************************************) (* STRING IMPLEMENTATION CODE *) (* Data Types for String ADT *) (*******************************************************************) StringRangeType = 0 .. MaxString; StrIndexT = 1 .. MaxString; StringType = RECORD Length : StringRangeType; Chars : ARRAY [StrIndexT] OF Char END; (* StringType *) Relation = (Less, Greater, Equal); (* This provides us a way of expressing which characters we want to go into strings. The compliment of the Black-Space set will be considered "White-Space" *) blackSpSetType = set of char ; (********************************************************************) (* STRING IMPLEMENTATION CODE *) (* Operations for String ADT *) (*******************************************************************) FUNCTION Length (Strng : StringType) : StringRangeType; BEGIN (* Length *) Length := Strng.Length END; (* Length *) (**********************************************************) PROCEDURE EmptyString (VAR Strng : StringType); (* Set Strng to empty. *) BEGIN (* EmptyString *) Strng.Length := 0 END; (* EmptyString *) (*************************************************************) (* PRECONDITIONS: This procedure assumes that FileToRead is open for reading and that there is black-space in the file window at start of execution. POSTCONDITIONS: ReadString reads the next contiguous segment of black-space. As much as will fit is put into Strng. ReadString stops when 1) white-space or 2) eoln is ENCOUNTERED on the current line. It does NOT read the white space or eoln. *) PROCEDURE ReadString (VAR FileToRead : Text; VAR Strng : StringType ; blackSpSet : blackSpSetType ; VAR foundWhtSp : boolean); VAR (* The number of contiguous black-space characters read so far. *) chrCount : integer ; ch : char ; BEGIN (* ReadString *) (* Make the string empty. *) EmptyString (Strng) ; foundWhtSp := false ; chrCount := 0 ; while not (eoln(FileToRead) or foundWhtSp) do if not (FileToRead^ in blackSpSet) then foundWhtSp := true else begin read (FileToRead, ch) ; chrCount := chrCount + 1 ; if (Length(Strng) < MaxString) then begin Strng.Chars[Length(Strng) + 1] := ch ; Strng.Length := Strng.Length + 1 ; end ; if chrCount = MaxString + 1 then begin write ('Found a string that is too long to') ; writeln ('fit into a string variable...') ; writeln ('Will skip to the end of the string.') ; end end ; END; (* ReadString *) (***************************************************************) FUNCTION Compare (String1, String2 : StringType) : Relation; (* Perform a lexical comparison between String1 and *) (* String2, returning their relation (less than, *) (* equal to, or greater than). *) VAR Pos : StrIndexT; (* index within strings *) StillMatch : Boolean; (* True while characters match *) MinLength : StringRangeType; (* length of shorter Strng *) BEGIN (* Compare *) (* MinLength := length of the shorter Strng *) IF String1.Length < String2.Length THEN MinLength := String1.Length ELSE MinLength := String2.Length; Pos := 1; StillMatch := True; (* Loop Invariant: 1 <= Pos <= MinLength + 1 AND *) (* String1.Chars[1] .. String1.Chars[Pos - 1] = *) (* String2.Chars[1] .. String2.Chars[Pos - 1]. *) WHILE (Pos <= MinLength) AND StillMatch DO BEGIN (* Search for characters that do not match. *) IF String1.Chars[Pos] = String2.Chars[Pos] THEN (* keep comparing *) Pos := Pos + 1 ELSE (* they don't match *) BEGIN StillMatch := False; IF String1.Chars[Pos] < String2.Chars[Pos] THEN Compare := Less ELSE Compare := Greater END (* ELSE they don't match *) END; (* WHILE loop *) (* If the shorter Strng ran out of characters, use *) (* the lengths to determine ordering. *) IF StillMatch THEN IF String1.Length = String2.Length THEN Compare := Equal ELSE IF String1.Length < String2.Length THEN Compare := Less ELSE Compare := Greater END; (* Compare *) (******************************************************************) (* Utility File-Reading Procedure *) (******************************************************************) (* PRECONDITIONS: It is assumed that FileToRead is open for reading. POSTCONDITIONS: Skips over all white-space in FileToRead from the file window forward until the first black-space character, or until eof becomes true. *) PROCEDURE SkipWhiteSp (VAR FileToRead : Text ; blackSpSet : blackSpSetType ; Var foundBlkSp : boolean ); Var ch : char ; BEGIN (* PROCEDURE SkipWhiteSp *) foundBlkSp := false ; while not (eof(FileToRead) or foundBlkSp) do begin while not (eoln(FileToRead) or foundBlkSp) do if ( FileToRead^ in blackSpSet ) then foundBlkSp := true else read (FileToRead, ch) ; if eoln(FileToRead) then readln(FileToRead) end END ; (* PROCEDURE SkipWhiteSp *)