Source file ocaml_parsing.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
open! Core
open Ocaml_common
let string_lexbuf string = Lexing.from_string string ~with_positions:true
let rec fold_on_tokens lexbuf acc ~f =
match (Lexer.token_with_comments lexbuf : Parser.token) with
| EOF as tok ->
let loc = Location.curr lexbuf in
let acc = f acc (tok, loc) in
acc
| tok ->
let loc =
match tok with
| COMMENT (_, loc) -> loc
| DOCSTRING ds -> Docstrings.docstring_loc ds
| _ -> Location.curr lexbuf
in
let acc = f acc (tok, loc) in
fold_on_tokens lexbuf acc ~f
;;
let tokens_of string =
fold_on_tokens (string_lexbuf string) [] ~f:(fun acc x -> x :: acc) |> List.rev
;;
let string_tokens_exn string =
tokens_of string
|> List.map ~f:fst
|> List.filter ~f:(function
| EOF -> false
| _ -> true)
;;
let try_with_syntax_error f =
match Ocaml_common.Warnings.without_warnings f with
| x -> Ok x
| exception
(( Lexer.Error _
| Syntaxerr.Error _
| Stdlib.Parsing.Parse_error
| Language_extension.Error.Error _ ) as exn) -> Error (Base.Error.of_exn exn)
;;
let string_tokens : string -> Parser.token list Base.Or_error.t =
fun string -> try_with_syntax_error (fun () -> string_tokens_exn string)
;;
type rsplit_acc = { last_seen_hash_index : int option }
let rsplit_on_hash : string -> (string * string) option =
fun string ->
Option.try_with_join
@@ fun () ->
let { last_seen_hash_index } =
fold_on_tokens
(Lexing.from_string string)
{ last_seen_hash_index = None }
~f:
(fun
acc
( token
, { loc_start = { pos_fname = _; pos_lnum = _; pos_bol = _; pos_cnum }
; loc_end = _
; loc_ghost = _
} )
->
match token with
| HASH | HASH_SUFFIX -> { last_seen_hash_index = Some pos_cnum }
| _ -> acc)
in
Option.map last_seen_hash_index ~f:(fun index ->
let left = String.sub string ~pos:0 ~len:index in
let right =
String.sub
string
~pos:(index + 1)
~len:(String.length string - 1 - String.length left)
in
left, right)
;;