OCaml parser combinator that compiles to direct recursive descent
5

Configure Feed

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

add source location spans to errors instead of just position int

+23 -12
+18 -10
lib/combin.ml
··· 7 7 val show_token : token -> string 8 8 end 9 9 10 + type span = { start_pos : int; end_pos : int } 11 + 10 12 type error = { 11 - pos : int; 13 + span : span; 12 14 expected : string list; 13 15 } 14 16 15 17 let 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 } 18 + if e1.span.end_pos > e2.span.end_pos then e1 19 + else if e2.span.end_pos > e1.span.end_pos then e2 20 + else { span = { start_pos = min e1.span.start_pos e2.span.start_pos; end_pos = e1.span.end_pos }; expected = e1.expected @ e2.expected } 19 21 20 22 let pure x _input = Ok (x, _input) 21 23 22 - let fail msg _input = Error { pos = 0; expected = [msg] } 24 + let fail msg _input = Error { span = { start_pos = 0; end_pos = 0 }; expected = [msg] } 23 25 24 26 module Char_input : sig 25 27 include INPUT with type token = char ··· 45 47 46 48 let format_error ?(input = "") e = 47 49 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 50 + if String.length input > 0 && e.span.end_pos < String.length input then 51 + let start = max 0 (e.span.start_pos - 5) in 52 + let len = min 30 (String.length input - start) in 51 53 Printf.sprintf " near '%s'" (String.sub input start len) 52 54 else "" 53 55 in 54 - Printf.sprintf "parse error at position %d%s: expected %s" 55 - e.pos context (String.concat " or " e.expected) 56 + let pos_str = 57 + if e.span.start_pos = e.span.end_pos then 58 + Printf.sprintf "position %d" e.span.start_pos 59 + else 60 + Printf.sprintf "positions %d-%d" e.span.start_pos e.span.end_pos 61 + in 62 + Printf.sprintf "parse error at %s%s: expected %s" 63 + pos_str context (String.concat " or " e.expected)
+5 -2
src/codegen.ml
··· 9 9 Printf.sprintf "%s_%d" prefix !counter 10 10 11 11 let error_expr ~loc expected = 12 - [%expr Error { Combin.pos = I.position input; expected = [%e expected] }] 12 + [%expr Error { Combin.span = { Combin.start_pos = I.position input; end_pos = I.position input }; expected = [%e expected] }] 13 + 14 + let error_expr_span ~loc start_var expected = 15 + [%expr Error { Combin.span = { Combin.start_pos = [%e start_var]; end_pos = I.position input }; expected = [%e expected] }] 13 16 14 17 let expected_list ~loc strs = 15 18 elist ~loc (List.map (estring ~loc) strs) ··· 154 157 let saved = input in 155 158 match [%e p_code] with 156 159 | Ok _ as r -> r 157 - | Error e -> Error { e with Combin.pos = I.position saved }] 160 + | Error e -> Error { e with Combin.span = { e.Combin.span with Combin.start_pos = I.position saved } }] 158 161 159 162 | Cut { loc } -> 160 163 [%expr Ok ((), input)]