2
(** Parser: Grammar Specification for Parsing S-expressions *)
3
(* compare to parser.mly *)
4
(* *) (* C inside Ocaml comment to satisfy cr *)
8
let parse_failure what =
9
let pos = Parsing.symbol_start_pos () in
11
Printf.sprintf "Sexplib.Parser: failed to parse line %d char %d: %s"
12
pos.pos_lnum (pos.pos_cnum - pos.pos_bol) what in
15
module With_pos = struct
17
open Type_with_layout.Parsed
19
let coerce = Src_pos.Absolute.of_lexing
21
let start_pos () = coerce (Parsing.symbol_start_pos ())
24
let p = Parsing.symbol_end_pos () in
25
coerce { p with Lexing.pos_cnum = p.Lexing.pos_cnum - 1 }
30
| None -> (start_pos (), None)
31
| Some (pos, x) -> (coerce pos, Some x)
35
let list ts = List (start_pos (), ts, end_pos ())
38
let comment x = Comment x
40
let sexp_comment cs t = Sexp_comment (start_pos (), cs, t)
42
let plain_comment (x, pos_opt) =
45
| None -> start_pos ()
46
| Some pos -> coerce pos
48
Plain_comment (pos, x)
54
%token <string * (Lexing.position * string) option> STRING
55
%token <string * Lexing.position option> COMMENT
56
%token LPAREN RPAREN EOF HASH_SEMI
59
%type <Type_with_layout.t_or_comment> sexp
62
%type <Type_with_layout.t_or_comment option> sexp_opt
65
%type <Type_with_layout.t_or_comment list> sexps
68
%type <Type_with_layout.Parsed.t_or_comment list> sexps_abs
71
%type <Type_with_layout.t_or_comment list> rev_sexps
75
sexp_but_no_comment_abs
76
: STRING { With_pos.atom $1 }
77
| LPAREN rev_sexps_abs RPAREN { With_pos.list (List.rev $2) }
78
| error { parse_failure "sexp" }
81
: COMMENT { With_pos.plain_comment $1 }
82
| HASH_SEMI rev_comments_abs sexp_but_no_comment_abs { With_pos.sexp_comment (List.rev $2) $3 }
85
: /* nothing */ { [] }
86
| rev_comments_abs comment_abs { $2 :: $1 }
89
: sexp_but_no_comment_abs { With_pos.sexp $1 }
90
| comment_abs { With_pos.comment $1 }
94
| rev_sexps_abs sexp_abs { $2 :: $1 }
97
: sexp_abs { Type_with_layout.relativize $1 }
105
| rev_sexps_aux sexp { $2 :: $1 }
108
: rev_sexps_aux EOF { $1 }
112
: rev_sexps_aux EOF { List.rev $1 }
115
/* for debugging positions */
117
: rev_sexps_abs EOF { List.rev $1 }