Combinator library for extracting data for s-exps?

I just wrote a parser for my input data using Decoders_sexplib, and the result works. It’s the only library recommended in the thread that solves my specific problem, so far.

  open Decoders_sexplib.Decode

  let module_deps_decoder =
    let+ for_intf = field "for_intf" (list string)
    and+ for_impl = field "for_impl" (list string)
    in for_intf @ for_impl

  let module_decoder entry_name =
    let+ name = field "name" string
    and+ impl = field "impl" (list string) |> map List.hd
    and+ deps = field "module_deps" module_deps_decoder
    in (entry_name, name, impl, deps)

  let exec_decoder =
    let* entry_name = field "names" (list string) |> map List.hd in
    field "modules" (list (module_decoder entry_name))

  let lib_decoder =
    let* entry_name = field "name" string in
    field "modules" (list (module_decoder entry_name))
    
  let entry_decoder =
    list_filter (
      string |> uncons @@ fun kind ->
      match kind with
      | "executables" -> let+ v = list exec_decoder in Some v
      | "library" -> let+ v = list lib_decoder in Some v
      | _ -> succeed None
    )
    |> map List.flatten
    |> map List.flatten

Note that entry_decoder is an example of a decoder working on a sum type / variant as you mention:

  1. in this example I use list_filter to only handle the variants executable and library and ignore the others
  2. there is an extra level of list wrapping (and List.flatten in the result), due to I think the inner working of the Decoders library which was designed with JSON rather than s-exprs in mind. I’m not sure but I think that it normalizes (polyline foo bar) into something like (polyline (foo bar)).
1 Like