164 lines
4.8 KiB
OCaml
164 lines
4.8 KiB
OCaml
let __prefixes__ = [|"let"; "rec"; "and"; "for"; "mutable"|] ;;
|
|
let __keywords__ = [|"let"; "while"; "do"; "done"; "for"; "to"; "begin"; "end"; "try"; "with"; "raise"; "in"|] ;;
|
|
let fbd = [|' '; '\n'; '('; ')'; '['; ']'; '{'; '}'; ';'; ','; '.'; ':'; '*'; '|'; '-'; '+'; '*'; '/'; '='; '<'; '>'; '!'|] ;;
|
|
|
|
let concat_str (str : string ref) nstr =
|
|
let n = String.length nstr in
|
|
let i = ref 0 in
|
|
while !i < n && nstr.[!i] = ' ' do
|
|
incr i
|
|
done;
|
|
if !i <> n then begin
|
|
let cct = String.init (n - !i) (fun k -> nstr.[k + !i]) in
|
|
str := (!str)^cct^"\n"
|
|
end;;
|
|
|
|
let parse_the_whole_thing filename =
|
|
let ptr = open_in filename in
|
|
let res = ref "" in
|
|
try
|
|
while true do
|
|
let line = input_line ptr in
|
|
concat_str res line
|
|
(*res := (!res)^line^"\n"*)
|
|
done;
|
|
"0 factorielle"
|
|
with
|
|
| End_of_file ->
|
|
close_in ptr;
|
|
!res ;;
|
|
|
|
let is_an_integer ch =
|
|
Char.code ch >= 48 && Char.code ch <= 57 ;;
|
|
|
|
let to_list str =
|
|
let n = String.length str in
|
|
let rec aux acc i = match i with
|
|
| k when k >= n -> acc
|
|
| k ->
|
|
let k1 = ref k
|
|
and k2 = ref k in
|
|
while !k2 < String.length str && (Array.mem str.[!k2] fbd || is_an_integer str.[!k2]) do
|
|
incr k2;
|
|
incr k1
|
|
done;
|
|
while !k2 < String.length str && not (Array.mem str.[!k2] fbd) do
|
|
incr k2
|
|
done;
|
|
aux (((0, String.init (!k2 - !k1) (fun i -> str.[!k1 + i])), (!k1, !k2))::acc) (!k2+1)
|
|
in
|
|
List.rev (aux [] 0) ;;
|
|
|
|
let print_to_list (res : ((int * string) * (int * int)) list) =
|
|
let rec aux = function
|
|
| [] -> ()
|
|
| ((b, str), (i, j))::t ->
|
|
Printf.printf "[%d] %s --> (%d <-> %d)\n" b str i j ;
|
|
aux t
|
|
in
|
|
aux res ;;
|
|
|
|
let random_string nmin nmax =
|
|
String.init (Random.int (nmax - nmin) + nmin) (fun i -> Char.chr (97 + Random.int 25)) ;;
|
|
|
|
let detect_names (res : ((int * string) * (int * int)) list) =
|
|
let rec aux isname = function
|
|
| [] -> []
|
|
| ((status, str), (i, j))::t when isname ->
|
|
if Array.mem str __prefixes__ then
|
|
((status, str), (i, j))::(aux true t)
|
|
else
|
|
((1, str), (i, j))::(aux false t)
|
|
| ((status, str), (i, j))::t ->
|
|
((status, str), (i, j))::(aux (Array.mem str __prefixes__) t)
|
|
in
|
|
aux false res ;;
|
|
|
|
let str_equal s1 s2 =
|
|
if (String.length s1) <> (String.length s2) then
|
|
false
|
|
else
|
|
Array.fold_left (fun acc v -> acc && fst v = snd v) true (Array.init (String.length s1) (fun i -> (s1.[i], s2.[i]))) ;;
|
|
|
|
let generate_conversion_hash (res : ((int * string) * (int * int)) list) =
|
|
let hash = Hashtbl.create (List.length res +2) in
|
|
let rec aux = function
|
|
| [] -> ()
|
|
|((isname, str), (i, j))::t ->
|
|
if Hashtbl.find_opt hash str = None then begin
|
|
if isname = 1 then
|
|
Hashtbl.add hash str (random_string 10 11)
|
|
else
|
|
Hashtbl.add hash str str ;
|
|
end;
|
|
(*if Hashtbl.find_opt hash str = None then begin
|
|
if not (Array.mem str __prefixes__) then
|
|
Hashtbl.add hash str (random_string 10 11)
|
|
else
|
|
Hashtbl.add hash str str ;
|
|
end;*)
|
|
aux t
|
|
in
|
|
aux res ;
|
|
hash ;;
|
|
|
|
let list_to_array (l : 'a list) =
|
|
let hd = List.hd l in
|
|
let n = List.length l in
|
|
let res = Array.make n hd in
|
|
let rec aux i = function
|
|
| [] -> ()
|
|
| h::t ->
|
|
res.(i) <- h ;
|
|
aux (i+1) t
|
|
in
|
|
aux 0 l;
|
|
res ;;
|
|
|
|
let write_out (filename : string) str (ext : string) (words : ((int * string) * (int * int)) list) (hash : (string, string) Hashtbl.t) =
|
|
let ptr = open_out ("tests/"^filename^"_improved."^ext) in
|
|
|
|
let n = String.length str in
|
|
let i = ref 0 in
|
|
|
|
let cwords = list_to_array words in
|
|
let cindex = ref 0 in
|
|
try
|
|
while true do
|
|
while !i < fst (snd cwords.(!cindex)) do (* write normally *)
|
|
Printf.fprintf ptr "%c" str.[!i] ;
|
|
incr i;
|
|
done;
|
|
Printf.fprintf ptr "%s" (Hashtbl.find hash (snd (fst cwords.(!cindex)))) ;
|
|
i := (snd (snd cwords.(!cindex))) ;
|
|
incr cindex ;
|
|
done;
|
|
close_out ptr ;
|
|
with
|
|
| Invalid_argument _ ->
|
|
while !i < n do
|
|
Printf.fprintf ptr "%c" str.[!i] ;
|
|
incr i;
|
|
done;
|
|
close_out ptr ;;
|
|
|
|
let convert filename ext =
|
|
let whole = parse_the_whole_thing (filename^"."^ext) in
|
|
(*Printf.printf "%s" whole ;*)
|
|
let words = to_list whole in
|
|
print_to_list words ;
|
|
let fnames = detect_names words in
|
|
(*print_to_list fnames ;*)
|
|
let conversion_hash = generate_conversion_hash fnames in
|
|
(*Hashtbl.iter (fun k v -> Printf.printf "%s ----> %s\n" k v) conversion_hash ;*)
|
|
write_out filename whole ext fnames conversion_hash ;;
|
|
|
|
|
|
let main () =
|
|
if Array.length Sys.argv <> 3 then begin
|
|
Printf.fprintf stderr "Usage : ./a.out <filename> <extension>\nNote : filename should not include the <.extension> (e.g. enter 'main' and not 'main.c' or 'main.ml')\n" ;
|
|
assert false ;
|
|
end else
|
|
convert Sys.argv.(1) Sys.argv.(2) ;;
|
|
|
|
main () ;; |