OCaml parser combinator that compiles to direct recursive descent
5

Configure Feed

Select the types of activity you want to include in your feed.

ppx_combin / lib / combin.ml
1.5 kB 55 lines
1module type INPUT = sig 2 type t 3 type token 4 val peek : t -> token option 5 val advance : t -> t 6 val position : t -> int 7 val show_token : token -> string 8end 9 10type error = { 11 pos : int; 12 expected : string list; 13} 14 15let merge_errors e1 e2 = 16 if e1.pos > e2.pos then e1 17 else if e2.pos > e1.pos then e2 18 else { pos = e1.pos; expected = e1.expected @ e2.expected } 19 20let pure x _input = Ok (x, _input) 21 22let fail msg _input = Error { pos = 0; expected = [msg] } 23 24module Char_input : sig 25 include INPUT with type token = char 26 val of_string : string -> t 27end = struct 28 type token = char 29 type t = { data : string; pos : int } 30 31 let of_string s = { data = s; pos = 0 } 32 33 let peek { data; pos } = 34 if pos >= String.length data then None 35 else Some (String.get data pos) 36 37 let advance t = { t with pos = t.pos + 1 } 38 let position t = t.pos 39 let show_token c = Printf.sprintf "'%c'" c 40end 41 42let parse_string parser s = 43 let input = Char_input.of_string s in 44 parser (module Char_input : INPUT with type t = Char_input.t and type token = char) input 45 46let format_error ?(input = "") e = 47 let context = 48 if String.length input > 0 && e.pos < String.length input then 49 let start = max 0 (e.pos - 10) in 50 let len = min 20 (String.length input - start) in 51 Printf.sprintf " near '%s'" (String.sub input start len) 52 else "" 53 in 54 Printf.sprintf "parse error at position %d%s: expected %s" 55 e.pos context (String.concat " or " e.expected)