mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-05 19:00:31 -05:00
80 lines
1.9 KiB
OCaml
80 lines
1.9 KiB
OCaml
(* parse IRC logs *)
|
|
|
|
type datetime = {
|
|
year: int;
|
|
month: int;
|
|
day: int;
|
|
hour: int;
|
|
min: int;
|
|
sec: int;
|
|
}
|
|
|
|
let pp_datetime out d =
|
|
let { year; month; day; hour; min; sec } = d in
|
|
CCFormat.(
|
|
fprintf out "{y=%d;M=%d;d=%d;h=%d;m=%d;s=%d}" year month day hour min sec)
|
|
|
|
type msg = {
|
|
timestamp: datetime;
|
|
user: string;
|
|
msg: string;
|
|
}
|
|
|
|
let pp_msg out m =
|
|
CCFormat.fprintf out "{@[time=%a;@ user=%S;@ msg=%S@]}" pp_datetime
|
|
m.timestamp m.user m.msg
|
|
|
|
open CCParse
|
|
|
|
let p_datetime : datetime t =
|
|
let int = U.int in
|
|
let* date, time = split_2 ~on_char:' ' in
|
|
let* y, m, d = recurse date (split_3 ~on_char:'-') in
|
|
let* year = recurse y int in
|
|
let* month = recurse m int in
|
|
let* day = recurse d int in
|
|
let* hour, min, sec =
|
|
recurse time
|
|
(let* hour = int in
|
|
char ':'
|
|
*> let* min = int in
|
|
char ':'
|
|
*> let+ sec = int in
|
|
hour, min, sec)
|
|
in
|
|
let dt = { year; month; day; hour; min; sec } in
|
|
return dt
|
|
|
|
let p_line =
|
|
let* line = lookahead all in
|
|
|
|
if Slice.is_empty line then
|
|
return None
|
|
else
|
|
let* fields = split_list ~on_char:'\t' in
|
|
match fields with
|
|
| [ date; user; rest ] ->
|
|
let+ timestamp = recurse date p_datetime
|
|
and+ user =
|
|
recurse user
|
|
(chars_if (function
|
|
| '>' -> false
|
|
| _ -> true))
|
|
and+ msg = recurse rest (all_str >|= String.trim) in
|
|
Some { timestamp; user; msg }
|
|
| _ ->
|
|
failf "expected 3 fields, got [%s]"
|
|
(String.concat ";" @@ List.map String.escaped
|
|
@@ List.map Slice.to_string fields)
|
|
|
|
let p_file = each_line (parsing "line" p_line) >|= CCList.keep_some
|
|
|
|
let () =
|
|
let s = CCIO.File.read_exn Sys.argv.(1) in
|
|
match parse_string p_file s with
|
|
| Ok l ->
|
|
Format.printf "parsed:@.";
|
|
List.iter (Format.printf "%a@." pp_msg) l
|
|
| Error e ->
|
|
Format.printf "parse error: %s@." e;
|
|
exit 1
|