(* balanced-main.ml *) (* turn Balanced.balanced into a standalone executable invoke executable with no options to read list of integers from standard input; invoke with -file FILE to read it from file FILE. Output is sent to standard ouput, one list per line *) (* val readIntList : in_channel -> int list read a list of integers from an input channel; each line of file should consist of single OCaml integer numeral *) let readIntList chan = let readInt() = try Some(int_of_string(input_line chan)) with _ -> None in let rec read xs = match readInt() with None -> List.rev xs | Some n -> read(n :: xs) in read[] (* val outputIntList : int list -> unit output a list of integers to the standard output, all one one line, separated by blanks *) let outputIntList xs = let rec out xs = match xs with [] -> () | [x] -> print_int x | (x :: xs) -> (print_int x; print_string " "; out xs) in out xs (* val outputIntLists : int list list -> unit output a list of integer lists to the standard output, one list per line (with its integers separated by blanks *) let outputIntLists xss = let rec out xss = match xss with [] -> () | [xs] -> outputIntList xs | (xs :: xss) -> (outputIntList xs; print_string "\n"; out xss) in out xss (* processing command line arguments *) let fileNameOpt : string option ref = ref None let options = [("-file", Arg.String(function x -> fileNameOpt := Some x), "FILENAME")] let usage = "usage: balanced ..." let badArgument arg = (raise(Arg.Bad("bad argument: `" ^ arg ^ "'"))) let _ = Arg.parse options badArgument "balanced ..." (* invoke Balanced.balanced on list of integers obtained from source selected by user, and output the result on the standard output *) let _ = let chan = match !fileNameOpt with None -> stdin | Some file -> try open_in file with _ -> (print_string "unable to open file: \""; print_string file; print_string "\"\n"; exit 1) in (outputIntLists(Balanced.balanced(readIntList chan)); print_string "\n"; exit 0)