Execute a Markov algorithm: Difference between revisions

Content added Content deleted
(Updated D entry)
m (On seeing this again, the use of a module hinders clarity, so I removed it)
Line 2,076: Line 2,076:
Str.replace_first a b s
Str.replace_first a b s


let parse_rules cin =
(* At their simplest, modules can function like namespaces... though they're much more. *)
let open Str in
module Markov = struct
let rule = regexp "\\(.+\\)[ \t]+->[ \t]+\\(.*\\)" in
let parse_rules cin =
let leader s c = String.length s > 0 && s.[0] = c in
let open Str in
let parse_b s = if leader s '.' then (string_after s 1,true) else (s,false) in
let rule = regexp "\\(.+\\)[ \t]+->[ \t]+\\(.*\\)" in
let rec parse_line rules =
let leader s c = String.length s > 0 && s.[0] = c in
try
let parse_b s = if leader s '.' then (string_after s 1,true) else (s,false) in
let s = input_line cin in
let rec parse_line rules =
if leader s '#' then parse_line rules
try
let s = input_line cin in
else if string_match rule s 0 then
if leader s '#' then parse_line rules
let a = regexp_string (matched_group 1 s) in
let b,terminate = parse_b (matched_group 2 s) in
else if string_match rule s 0 then
parse_line ((a,b,terminate)::rules)
let a = regexp_string (matched_group 1 s) in
else failwith ("parse error: "^s)
let b,terminate = parse_b (matched_group 2 s) in
with End_of_file -> rules
parse_line ((a,b,terminate)::rules)
in List.rev (parse_line [])
else failwith ("parse error: "^s)
with End_of_file -> rules
in List.rev (parse_line [])


let rec run rules text =
let rec run rules text =
let rec apply s = function
let rec apply s = function
| [] -> s
| [] -> s
| (a,b,term)::next ->
| (a,b,term)::next ->
try
try
let s' = subst a b s in
let s' = subst a b s in
if term then s' else run rules s'
if term then s' else run rules s'
with Not_found -> apply s next
with Not_found -> apply s next
in apply text rules
in apply text rules
end


let _ =
let _ =
Line 2,110: Line 2,107:
print_endline "Expecting one argument: a filename where rules can be found."
print_endline "Expecting one argument: a filename where rules can be found."
else
else
let rules = try_finally (open_in Sys.argv.(1)) Markov.parse_rules close_in in
let rules = try_finally (open_in Sys.argv.(1)) parse_rules close_in in
(* Translate lines read from stdin, until EOF *)
(* Translate lines read from stdin, until EOF *)
let rec translate () =
let rec translate () =
print_endline (Markov.run rules (input_line stdin));
print_endline (run rules (input_line stdin));
translate ()
translate ()
in try translate () with End_of_file -> ()</lang>
in try translate () with End_of_file -> ()</lang>