let is_valid x =
  x <> "" && String.uppercase x = x && x.[String.length x - 1] <> '"' && x.[0] <> '"'
    && x.[0] <> '.' && (try string_of_int (int_of_string x) <> x with _ -> true) &&
  x <> "EOF" && x <> "_" && x <> "STRING" && x <> "SOUND" && x <> "INLINED_FILE" && x <> "TRANS_REF"
    && x <> "STRING_REF" && x <> "FORCED_STRING_REF" && x <> "START_FROM_TP" && x <> "START_FROM_TPP"
    && x <> "START_FROM_TPA" && x <> "TOKEN" && x <> "LIST"
;;

let load_tparser tparser_in =
  let i = open_in tparser_in in
  let tokens = Hashtbl.create 600 in
  begin
    try
      while true do
	let line = input_line i in
	let parts = Str.split (Str.regexp "[^A-Za-z0-9\"._]") line in
	List.iter (fun x ->
	  if is_valid x
	  then
	    Hashtbl.replace tokens x ()
		  ) parts;
      done
    with End_of_file -> close_in i
  end;
  Hashtbl.fold (fun line _ all ->
    line :: all
	       ) tokens []
;;

let load_aliases aliases_in tokens =
  let i = open_in aliases_in in
  let aliases = Hashtbl.create 20 in
  begin
    try
      List.iter (fun x ->
	if is_valid x then Hashtbl.add aliases x []
		) tokens;
      while true do
	let line = input_line i in
	let parts = Str.split (Str.regexp "[ \t]") line in
	match parts with
	|	a :: b ->
	    if is_valid a then Hashtbl.replace aliases a b
	| [] -> ()
      done
    with End_of_file -> close_in i
  end;
  aliases
;;

let output_tokens o aliases =
  let i = ref 10 in
  Hashtbl.iter (fun tok al ->
    Printf.fprintf o "%-6d : %s;" !i tok;
    incr i;
    if al <> [] then begin
      output_string o " //";
      List.iter (fun x -> Printf.fprintf o " %s" x) al;
    end;
    output_char o '\n';
	       ) aliases
;;

let output_parser tparser_in tparser_out aliases =
  let i = open_in tparser_in in
  let o = open_out tparser_out in
  output_string o
    "/* This file is automatically generated from src/{tparser.in,aliases.in,make_gr.ml}.
    DO NOT EDIT THIS BY HAND. */\n\n";
    begin
      try
	while true do
	  let line = input_line i in
	  let line =
	    if String.length line = 0 || line.[(String.length line) - 1] != '\r' then line
	    else String.sub line 0 ((String.length line) - 1)
	  in
	  output_string o line;
	  output_char o '\n';
	  if line = "// BEGIN TOKEN LIST" then output_tokens o aliases;
	done
      with End_of_file -> (close_in i; close_out o)
    end;
;;

let main () =
  let tokens = load_tparser "src/trealparserin.in" in
  let aliases = load_aliases "src/aliases.in" tokens in
  output_parser "src/trealparserin.in" "src/trealparserin.gr" aliases
;;

main ()
