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
(** Module providing functions to parse a config from various kind of inputs. *)
(** Pretty print a token *)
let pp_token fmt = function
| Menhir_parser.WORD s -> Fmt.pf fmt "WORD %s" s
| LBRACE -> Fmt.string fmt "LBRACE"
| RBRACE -> Fmt.string fmt "RBRACE"
| NEWLINE -> Fmt.string fmt "NEWLINE"
| EOF -> Fmt.string fmt "EOF"
(** Parse a config from a lexing buffer. *)
let from_lexbuf =
let parser =
MenhirLib.Convert.Simplified.traditional2revised Menhir_parser.config
in
fun buf ->
let last_token = ref None in
let provider () =
let tok = Lexer.token buf in
let start, stop = Sedlexing.lexing_positions buf in
last_token := Some tok;
(tok, start, stop)
in
try Ok (parser provider) with
| Menhir_parser.Error ->
let start, _stop = Sedlexing.lexing_positions buf in
Fmt.error_msg "File %s, line %i, character %i: unexpected token %a"
start.pos_fname start.pos_lnum
(start.pos_cnum - start.pos_bol)
(Fmt.option pp_token) !last_token
| Lexer.Error msg -> Error (`Msg msg)
(** Parse a config from a string. *)
let from_string s = from_lexbuf (Sedlexing.Utf8.from_string s)
(** Parse a config from a channel. *)
let from_channel c = from_lexbuf (Sedlexing.Utf8.from_channel c)
(** Parse a config from a file. *)
let from_file f =
match
Bos.OS.File.with_ic f
(fun chan () ->
let lexbuf = Sedlexing.Utf8.from_channel chan in
Sedlexing.set_filename lexbuf (Fpath.to_string f);
from_lexbuf lexbuf )
()
with
| Error _ as e -> e
| Ok (Error _ as e) -> e
| Ok (Ok _ as ok) -> ok