|
1 |
| -module Make (M : sig |
| 1 | +exception Syntax = Script.Syntax |
| 2 | + |
| 3 | +module type S = |
| 4 | +sig |
2 | 5 | type t
|
| 6 | + val from_lexbuf : Lexing.lexbuf -> t |
| 7 | + val from_file : string -> t |
| 8 | + val from_string : string -> t |
| 9 | + val from_channel : in_channel -> t |
| 10 | +end |
3 | 11 |
|
| 12 | +module type Rule = |
| 13 | +sig |
| 14 | + type t |
4 | 15 | val rule : (Lexing.lexbuf -> Parser.token) -> Lexing.lexbuf -> t
|
| 16 | +end |
5 | 17 |
|
6 |
| -end) = struct |
7 |
| - |
8 |
| - type nonrec t = M.t |
9 |
| - |
10 |
| - let from_lexbuf = |
11 |
| - let parser = MenhirLib.Convert.Simplified.traditional2revised M.rule in |
12 |
| - fun buf -> |
13 |
| - let provider () = |
14 |
| - let tok = Lexer.token buf in |
15 |
| - let start = Lexing.lexeme_start_p buf in |
16 |
| - let stop = Lexing.lexeme_end_p buf in |
17 |
| - tok, start, stop |
18 |
| - in |
19 |
| - try parser provider with |
20 |
| - | Parser.Error -> |
21 |
| - let left = Lexer.convert_pos buf.Lexing.lex_start_p in |
22 |
| - let right = Lexer.convert_pos buf.Lexing.lex_curr_p in |
23 |
| - let region = { Source.left; right } in |
24 |
| - raise (Script.Syntax (region, "unexpected token")) |
25 |
| - | Script.Syntax (region, s) as exn -> |
26 |
| - if region <> Source.no_region then raise exn |
27 |
| - else |
28 |
| - let region' = { |
29 |
| - Source.left = Lexer.convert_pos buf.Lexing.lex_start_p; |
30 |
| - Source.right = Lexer.convert_pos buf.Lexing.lex_curr_p } |
31 |
| - in |
32 |
| - raise (Script.Syntax (region', s)) |
33 |
| - |
34 |
| - let from_file filename = |
35 |
| - let chan = open_in filename in |
36 |
| - Fun.protect ~finally:(fun () -> close_in chan) |
37 |
| - (fun () -> |
38 |
| - let lb = Lexing.from_channel ~with_positions:true chan in |
39 |
| - Lexing.set_filename lb filename; |
40 |
| - from_lexbuf lb) |
| 18 | +module Make (M : Rule) : S with type t = M.t = |
| 19 | +struct |
| 20 | + type t = M.t |
41 | 21 |
|
42 |
| - let from_string s = from_lexbuf (Lexing.from_string ~with_positions:true s) |
| 22 | + let provider buf () = |
| 23 | + let tok = Lexer.token buf in |
| 24 | + let start = Lexing.lexeme_start_p buf in |
| 25 | + let stop = Lexing.lexeme_end_p buf in |
| 26 | + tok, start, stop |
| 27 | + |
| 28 | + let convert_pos buf = |
| 29 | + { Source.left = Lexer.convert_pos buf.Lexing.lex_start_p; |
| 30 | + Source.right = Lexer.convert_pos buf.Lexing.lex_curr_p |
| 31 | + } |
43 | 32 |
|
| 33 | + let from_lexbuf buf = |
| 34 | + try |
| 35 | + MenhirLib.Convert.Simplified.traditional2revised M.rule (provider buf) |
| 36 | + with |
| 37 | + | Parser.Error -> |
| 38 | + raise (Syntax (convert_pos buf, "unexpected token")) |
| 39 | + | Syntax (region, s) when region <> Source.no_region -> |
| 40 | + raise (Syntax (convert_pos buf, s)) |
| 41 | + |
| 42 | + let from_string s = from_lexbuf (Lexing.from_string ~with_positions:true s) |
44 | 43 | let from_channel c = from_lexbuf (Lexing.from_channel ~with_positions:true c)
|
| 44 | + let from_file name = |
| 45 | + let chan = open_in name in |
| 46 | + Fun.protect ~finally:(fun () -> close_in chan) (fun () -> |
| 47 | + let buf = Lexing.from_channel ~with_positions:true chan in |
| 48 | + Lexing.set_filename buf name; |
| 49 | + from_lexbuf buf |
| 50 | + ) |
45 | 51 | end
|
46 | 52 |
|
47 | 53 | module Module = Make (struct
|
|
0 commit comments