(* lowercase-word.sig *) (* Copyright (C) 2008 Alley Stoughton This file is part of crypto, a cryptogram encoder/decoder. See the file COPYING.txt for copying and usage restrictions *) (* processing streams/files/strings of lowercase words *) signature LOWERCASE_WORD = sig exception Abort exception UnableToOpenFile (* processStream (inter, initNormal, wordNormal, newlineNormal, eofNormal, initError, wordError, newlineError, eofError) stm processes the contents of stm, as follows, using a loop involving the variables a : 'a and c : 'c, initialized to initNormal and initError, respectively if end-of-file is reached on stm, then (eofNormal a, eofNormal c) is returned otherwise processStream reads a line y from stm if inter (for "interactive") is true, and y = ".\n", then (eofNormal a, eofNormal c) is returned if inter is true and y = "!\n", then Abort is raised otherwise a and c are replaced by newlineNormal a and newlineError c, respectively let x1, ..., xm be the nonempty sequences of non-whitespace characters that are formed from y by ignoring initial and trailing whitespace characters and using non-empty sequences of whitespace characters as separators; if m = 0, then we repeat if x1 is a sequence of lowercase characters, when we replace a by wordNormal(x1, a); otherwise, we replace c by wordError(x1, c); we continue like this, processing the rest of x2, ..., xm then, we repeat *) val processStream : bool * 'a * (string * 'a -> 'a) * ('a -> 'a) * ('a -> 'b) * 'c * (string * 'c -> 'c) * ('c -> 'c) * ('c -> 'd) -> TextIO.instream -> 'b * 'd (* processFile is like processStream except that inter is implicitly false and stm is obtained by opening the supplied file (UnableToOpenFile is raised if the file can't be opened) *) val processFile : 'a * (string * 'a -> 'a) * ('a -> 'a) * ('a -> 'b) * 'c * (string * 'c -> 'c) * ('c -> 'c) * ('c -> 'd) -> string -> 'b * 'd (* processString is like processStream except that inter is implicitly false and stm is obtained by opening the supplied string (so reading from stm accesses the characters of the string) *) val processString : 'a * (string * 'a -> 'a) * ('a -> 'a) * ('a -> 'b) * 'c * (string * 'c -> 'c) * ('c -> 'c) * ('c -> 'd) -> string -> 'b * 'd (* normal and char list list list are typical special cases of 'a and 'b, respectively, in the above functions initNormal, wordNormal, newlineNormal and eofNormal can be supplied as arguments to those functions a value of type normal represents a value of type char list list list, where the char's are all lowercase letters a value of type normal should be thought-of as representing a list of lines of words *) type normal exception Normal (* represents nil *) val initNormal : normal (* if x only has lowercase letters, and norm represents ysss @ [zss], then wordNormal(x, norm) represents ysss @ [zss @ [explode x]]; if norm represents nil, then wordNormal raises Normal *) val wordNormal : string * normal -> normal (* if norm represents xsss, then newlineNormal norm represents xsss @ [nil] *) val newlineNormal : normal -> normal (* eofNormal returns what its argument represents *) val eofNormal : normal -> char list list list (* error and (int * string)list are typical special cases of 'c and 'd, respectively, in the above functions initError, wordError, newlineError and eofError can be supplied as arguments to those functions a value of type error represents a value of type int * (int * string)list, where, in a value (n, ps), n and all the left-sides of ps are >= 0, all the right-sides of ps have no whitespace characters, but have at least one non-lowercase letter, n >= all of the left-sides of ps, and ps is sorted in ascending order according to its left-sides the ints should be thought-of as line numbers, the strings as non-words; non-words are paired with their line numbers *) type error (* represents (0, nil) *) val initError : error (* if x has no whitespace characters and has at least one non-lowercase letter, and err represents (n, ps), then wordError(x, err) represents (n, ps @ [(n, x)]) *) val wordError : string * error -> error (* if err represents (n, ps), then newlineError err represents (n + 1, ps) *) val newlineError : error -> error (* if err represents (n, ps), then eofError err = ps *) val eofError : error -> (int * string)list end;