Archive for 9월, 2009

Beautiful Code Programming Praxis

9월 14th, 2009

Beautiful Code Programming Praxis.

  1. let match_re re text =
  2.  let len = String.length in
  3.  let get = String.get in
  4.  let remain str o = String.sub str o ((len str)-o) in
  5.  let next_ch ch o_re =
  6.   if len re > (o_re+1) then
  7.    if get re (o_re+1) = ch then true
  8.    else false
  9.   else false
  10.  in
  11.  let curr_ch ch o_re =
  12.   if len re > o_re then
  13.    if get re o_re = ch then true
  14.    else false
  15.   else false
  16.  in
  17.  let rec match_re_star c o_re o_text =
  18.   (* Printf.printf "match_re_star c:%c re:%s text:%s\n" c (remain re o_re) (remain text o_text); *)
  19.   if match_re_here o_re o_text then true
  20.   else if len text != o_text && ((get text o_text) = c || c = '.') then
  21.    match_re_star c o_re (o_text+1)
  22.   else
  23.    false
  24.  and match_re_here o_re o_text =
  25.   (* Printf.printf "match_re_here re:%s text:%s\n" (remain re o_re) (remain text o_text); *)
  26.   if len re = o_re then true
  27.   else if next_ch '*' o_re then
  28.    match_re_star (get re o_re) (o_re+2) o_text
  29.   else if get re o_re = '$' && len re = o_re+1 then
  30.    len text = o_text
  31.   else if len text != o_text && (get re o_re = '.' || get re o_re = get text o_text) then
  32.    match_re_here (o_re+1) (o_text+1)
  33.   else
  34.    false
  35.  and match_re_main o_re o_text =
  36.   (* Printf.printf "match_re_main re:%s text:%s\n" (remain re o_re) (remain text o_text); *)
  37.   if match_re_here o_re o_text then true
  38.   else if len text = o_text then false
  39.   else match_re_main o_re (o_text+1)
  40.  in
  41.  if curr_ch '^' 0 then
  42.   match_re_here 1 0
  43.  else match_re_main 0 0
  44.  
  45. let match_re_test () =
  46.   assert ((match_re "a" "a")=true);
  47.   assert ((match_re "a" "b")=false);
  48.   assert ((match_re "a" "ab")=true);
  49.   assert ((match_re "a" "ba")=true);
  50.   assert ((match_re "ab" "ab")=true);
  51.   assert ((match_re "ab" "ba")=false);
  52.   assert ((match_re "ab" "xab")=true);
  53.   assert ((match_re "ab" "aab")=true);
  54.   assert ((match_re "a.c" "ac")=false);
  55.   assert ((match_re "a.c" "abc")=true);
  56.   assert ((match_re "a.c" "xac")=false);
  57.   assert ((match_re "a.c" "xabcx")=true);
  58.   assert ((match_re "^ab" "ab")=true);
  59.   assert ((match_re "^ab" "ba")=false);
  60.   assert ((match_re "^ab" "aab")=false);
  61.   assert ((match_re "^ab" "abc")=true);
  62.   assert ((match_re "ab$" "ab")=true);
  63.   assert ((match_re "ab$" "ba")=false);
  64.   assert ((match_re "ab$" "aab")=true);
  65.   assert ((match_re "ab$" "abc")=false);
  66.   assert ((match_re "^ab$" "ab")=true);
  67.   assert ((match_re "^ab$" "ba")=false);
  68.   assert ((match_re "^ab$" "abc")=false);
  69.   assert ((match_re "^ab$" "aba")=false);
  70.   assert ((match_re "a.*c" "ac")=true);
  71.   assert ((match_re "a.*c" "abc")=true);
  72.   assert ((match_re "a.*c" "abbc")=true);
  73.   assert ((match_re "a.*c" "cbba")=false);
  74.   assert ((match_re "aa*" "x")=false);
  75.   assert ((match_re "aa*" "a")=true);
  76.   assert ((match_re "aa*" "aa")=true);
  77.   assert ((match_re "aa*" "ba")=true);
  78.   assert ((match_re "a*a*a" "a")=true);
  79.   assert ((match_re "a*a*a" "aaa")=true);
  80.   assert ((match_re "a*a*a" "xxxxx")=false)
  81.  
  82. let _ = match_re_test () (* no news is good news *)

OCaml translation of the regex match code in C.
I tried to beautify the code but it looks quite dirty due to the string operations. It will become more beautiful if we use a list of characters instead of native string as Scheme does in the suggested solution.