Source file sexp_provider.ml
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
let error_to_string = function
| Sexp.Nonterminated_node x -> Format.asprintf "non-terminated node on [%d]" x
| Nonterminated_atom x -> Format.asprintf "non-terminated atom on [%d]" x
| Unexepected_character (c, x) ->
Format.asprintf "unexpected character [%c] on [%d]" c x
| Expected_number_or_colon (c, x) ->
Format.asprintf "expected number or colon on [%d], given: [%c]" x c
| Expected_number (c, x) ->
Format.asprintf "expected number on [%d], given: [%c]" x c
| Premature_end_of_atom (len, x) ->
Format.asprintf "premature end of atom, expected length [%d] on [%d]" len
x
module Data_provider = struct
type t = Sexp.t
let from_string str =
str
|> Sexp.from_string
|> Result.map_error (fun error ->
let given = str in
let message = error_to_string error in
Required.Parsing_error { given; message })
let ( <|> ) a b =
match (a, b) with Some x, _ -> Some x | None, Some y -> Some y | _ -> None
let normalize_atom x =
bool_of_string_opt x
|> Option.map Data.bool
<|> (int_of_string_opt x |> Option.map Data.int)
<|> (float_of_string_opt x |> Option.map Data.float)
|> Option.value ~default:(Data.string x)
let is_record =
List.for_all (function Sexp.Node [ Atom _; _ ] -> true | _ -> false)
let rec normalize = function
| Sexp.Atom "null" -> Data.null
| Sexp.Atom x -> normalize_atom x
| Node [] -> Data.list []
| Node node when is_record node ->
Data.record
(List.concat_map
(function
| Sexp.Node [ Atom k; value ] -> [ (k, normalize value) ]
| _ -> [])
node)
| Node node -> Data.list_of normalize node
end
include Make.Data_reader (Data_provider)
module Canonical = struct
module Data_provider = struct
type t = Sexp.t
let from_string str =
str
|> Sexp.Canonical.from_string
|> Result.map_error (fun error ->
let given = str in
let message = error_to_string error in
Required.Parsing_error { given; message })
let normalize = Data_provider.normalize
end
include Make.Data_reader (Data_provider)
end