{ Author: Douglas Jones Date: April 27, 1993 Purpose: To do a word substitution encoding on standard input. Warning: This solution uses linear search, and would therefore be forbidden by the terms of the assignment! } PROGRAM mp6( input, output ); CONST wordlen = 16; { the maximum length of a word in the dictionary } maxwords = 1000; { the maximum number of dictionary entries } TYPE word = PACKED ARRAY [1..wordlen] OF char; wordrec = RECORD w: word; { the original word } r: word; { the replacement } END; index = 0..maxwords; VAR dictionary: ARRAY [1..maxwords] OF wordrec; topword: index; { the top word currently in the dictionary } { dictionary organization: dictionary[1..topword] has words in it. dictionary[topword+1..maxwords] has unused space for more words } { utility routines for text processing } FUNCTION isupper( c: char ): boolean; BEGIN isupper := (c >= 'A') AND (c <= 'Z'); END; { isupper } FUNCTION islower( c: char ): boolean; BEGIN islower := (c >= 'a') AND (c <= 'z'); END; { islower } FUNCTION isalpha( c: char ): boolean; BEGIN isalpha := isupper( c ) OR islower( c ); END; { isalpha } { core routines of the program } PROCEDURE readword( var f: text; var w: word ); { read a word from f into w, padding w with blanks; must be called with f^ pointing to a letter returns with f^ pointing to a non-letter. } VAR i: 0..wordlen; { index of a character in w } ch: char; BEGIN i := 0; WHILE isalpha(f^) DO BEGIN read(f, ch); IF i < wordlen THEN BEGIN i := i + 1; w[i] := ch; END; END; WHILE i < wordlen DO BEGIN i := i + 1; w[i] := ' '; END; END; { readword } PROCEDURE writeword( var f: text; var w: word ); { write the word w to the file f } VAR i: 0..wordlen; { index of a character in w } BEGIN i := 0; REPEAT i := i + 1; IF w[i] = ' ' THEN i := wordlen ELSE write( f, w[i] ); UNTIL i = wordlen; END; { writeword } PROCEDURE builddictionary; { read all words from the input and put them in the dictionary } VAR c: text; { the codebook } w: word; { the word to enter in the dictionary } r: word; { the word to substitute for w } PROCEDURE putword( VAR w, r: word ); { put the words w and r in the dictionary } BEGIN IF topword < maxwords THEN BEGIN { put w in the dictionary } topword := topword + 1; dictionary[topword].w := w; dictionary[topword].r := r; END; END; { putword } PROCEDURE skipstuff; { skip over blanks } BEGIN WHILE not(isalpha(c^)) DO get(c); END; BEGIN { builddictionary } reset( c, 'codebook' ); WHILE not(eof(c)) DO BEGIN skipstuff; readword(c, w); skipstuff; readword(c, r); readln(c); putword(w,r); END; END; { builddictionary } PROCEDURE printdictionary; { print out the dictionary } VAR w: 1..maxwords; i: 1..wordlen; BEGIN FOR w := 1 TO topword DO BEGIN FOR i := 1 TO wordlen DO write( dictionary[w].r[i] ); writeword( output, dictionary[w].w ); writeln; END; END; { printdictionary } FUNCTION lookup( VAR w: word ): index; VAR i: index; BEGIN i := topword; lookup := 0; REPEAT IF dictionary[i].w = w THEN BEGIN lookup := i; i := 0; END ELSE BEGIN i := i - 1; END; UNTIL i = 0; END; { lookup } PROCEDURE copytext; VAR ch: char; w: word; i: index; BEGIN WHILE not(eof) DO BEGIN IF isalpha(input^) THEN BEGIN readword( input, w ); i := lookup( w ); IF i = 0 THEN writeword( output, w ) ELSE writeword( output, dictionary[i].r ); END ELSE IF not(eoln) THEN BEGIN read(ch); write(ch); END ELSE BEGIN readln; writeln; END; END; END; { copytext } BEGIN { mp6 } { initialize dictionary to empty and all entries invalid } FOR topword := 1 TO maxwords DO dictionary[topword].w[1] := ' '; topword := 0; builddictionary; { printdictionary; } { this line is useful for debugging } copytext; END. { mp6 }