summaryrefslogtreecommitdiff
path: root/2025/ocaml/lib/application/parser.ml
blob: 099900be2f720de9710981ae22580c07ee54360b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
(** [rows_of_string s] is a list of strings where each element is a row of [s]. *)
let rows_of_string s =
  s |> String.split_on_char '\n'
  |> List.filter_map (fun l ->
      let trimmed = String.trim l in
      if trimmed <> "" then Some trimmed else None )

(** [columns_of_string ?sep s] is a list of strings where each element is
    a column of [s] where each column is separated by [sep]. *)
let rec columns_of_string ?(sep = ' ') s =
  rows_of_string s
  |> List.map (fun l ->
      l |> String.split_on_char sep |> List.filter (fun l -> l <> "") )
  |> transpose

(** [group_columns lst] is a list where the first element of each
    sublist of [lst] is grouped in [acc] and so on for the rest of the elements.
    Example: [group_columns [] \[\["abc"; "def"\]; \["ghi"; "jkl"\]\]] is the list [\[\["abc";"ghi"\];\["def";"jkl"\]\]]. *)
and transpose lst =
  assert (lst <> []) ;
  if List.mem [] lst then []
  else List.map List.hd lst :: transpose (List.map List.tl lst)

let%expect_test "rows correctly parsed" =
  let have = {| abc def
    ghi jkl |} in
  let rows = rows_of_string have in
  List.iter (fun c -> print_string (c ^ " ")) rows ;
  [%expect {| abc def ghi jkl |}]

let%expect_test "columns correctly parsed" =
  let have = {| abc def
    ghi jkl |} in
  let cols = columns_of_string have in
  List.iter (fun row -> List.iter (fun c -> print_string (c ^ " ")) row) cols ;
  [%expect {| abc ghi def jkl |}]