Skip to content

Commit

Permalink
cleanup !single_line_comment, fix unmatched nested comment edge case
Browse files Browse the repository at this point in the history
  • Loading branch information
dxu committed May 25, 2016
1 parent 35f1604 commit b235362
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 68 deletions.
76 changes: 33 additions & 43 deletions src/reason_lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,7 @@ let get_stored_string () =
(* To store the position of the beginning of a string and comment *)
let string_start_loc = ref Location.none;;
let comment_start_loc = ref [];;
let line_comment_start_loc = ref [];;
let single_line_comment = ref false;;
let line_comment_start_loc = ref None;;
let in_comment () = !comment_start_loc <> [];;
let is_in_string = ref false
let in_string () = !is_in_string
Expand Down Expand Up @@ -425,8 +424,7 @@ rule token = parse
}
| "//"
{ let start_loc = Location.curr lexbuf in
single_line_comment := true;
line_comment_start_loc := [start_loc];
line_comment_start_loc := Some start_loc;
reset_string_buffer ();
let end_loc = comment lexbuf in
let s = get_stored_string () in
Expand Down Expand Up @@ -570,20 +568,21 @@ and comment = parse
}
| "*/"
{
match (!comment_start_loc, !single_line_comment) with
| ([], false) ->
match (!comment_start_loc, !line_comment_start_loc) with
| ([], None) ->
assert false
| ([], true) ->
let loc = Location.curr lexbuf in
let start = List.hd (List.rev !line_comment_start_loc) in
raise (Error (Unmatched_nested_comment loc, start))
| ([_], true) ->
comment_start_loc := [];
| ([_], None) ->
comment_start_loc := []; Location.curr lexbuf
| (_ :: l, None) ->
comment_start_loc := l;
store_lexeme lexbuf;
comment lexbuf;
| ([_], false) ->
comment_start_loc := []; Location.curr lexbuf
| (_ :: l, _) ->
(* line comment *)
| ([], Some start_loc) ->
let loc = Location.curr lexbuf in
raise (Error (Unmatched_nested_comment loc, start_loc))
(* a multiline comment nested within a line comment *)
| (_ :: l, Some _) ->
comment_start_loc := l;
store_lexeme lexbuf;
comment lexbuf;
Expand Down Expand Up @@ -645,48 +644,39 @@ and comment = parse
| "'\\" 'x' ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] "'"
{ store_lexeme lexbuf; comment lexbuf }
| eof
{ match !comment_start_loc with
| [] ->
(* if the file ends with a single line comment then *)
if !single_line_comment then (
single_line_comment := false;
match (!comment_start_loc, !line_comment_start_loc) with
| ([], []) ->
assert false
| ([], _) ->
line_comment_start_loc := []; Location.curr lexbuf
| (_, _) ->
let start = List.hd (List.rev !comment_start_loc) in
comment_start_loc := [];
raise (Error (Unmatched_nested_comment start, Location.curr lexbuf))
) else assert false
| loc :: _ ->
{ match (!comment_start_loc, !line_comment_start_loc) with
| ([], None) -> assert false
| (loc :: _, None) ->
let start = List.hd (List.rev !comment_start_loc) in
comment_start_loc := [];
raise (Error (Unterminated_comment start, loc))
(* line comment ended with no nested multilines *)
| ([], Some _) ->
line_comment_start_loc := None; Location.curr lexbuf
(* line comment ends with an unfinished multiline *)
| (_, Some _) ->
let start = List.hd (List.rev !comment_start_loc) in
comment_start_loc := [];
raise (Error (Unmatched_nested_comment start, Location.curr lexbuf))
}
| newline
{
if not !single_line_comment then (
update_loc lexbuf None 1 false 0;
store_lexeme lexbuf;
comment lexbuf
)
else (
update_loc lexbuf None 1 false 0;
(* check if there are any unmatched nested comments *)

single_line_comment := false;
match (!comment_start_loc, !line_comment_start_loc) with
| ([], []) ->
| ([], None) ->
assert false
| ([], _) ->
line_comment_start_loc := []; Location.curr lexbuf
| (_, _) ->
| (_, None) ->
update_loc lexbuf None 1 false 0;
store_lexeme lexbuf;
comment lexbuf
| ([], Some _) ->
line_comment_start_loc := None; Location.curr lexbuf
| (_, Some _) ->
let start = List.hd (List.rev !comment_start_loc) in
comment_start_loc := [];
raise (Error (Unmatched_nested_comment start, Location.curr lexbuf))
)
}
| _
{ store_lexeme lexbuf; comment lexbuf }
Expand Down
53 changes: 28 additions & 25 deletions src/reason_toolchain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -188,31 +188,34 @@ module Create_parse_entrypoint (Toolchain_impl: Toolchain_spec) :Toolchain = str
| _ ->
let modified_and_attached_comments =
List.map (fun (str, is_line_comment, physical_loc) ->
(* When searching for "^" regexp, returns location of newline + 1 *)
let first_char_of_line = Str.search_backward new_line !chan_input physical_loc.loc_start.pos_cnum in
let end_pos_plus_one = physical_loc.loc_end.pos_cnum in
let comment_length = (end_pos_plus_one - physical_loc.loc_start.pos_cnum - 4) in
(* Also, the string contents originally reported are incorrect! *)
let original_comment_contents = String.sub !chan_input (physical_loc.loc_start.pos_cnum + 2) comment_length in
let (com, is_line_comment, attachment_location) =
match Str.search_forward line_content !chan_input first_char_of_line
with
| n ->
(* Recall that all end positions are actually the position of end + 1. *)
let one_greater_than_comment_end = end_pos_plus_one in
(* Str.string_match lets you specify a position one greater than last position *)
let comment_is_last_thing_on_line =
Str.string_match space_before_newline !chan_input one_greater_than_comment_end in
if n < physical_loc.loc_start.pos_cnum && comment_is_last_thing_on_line then (
original_comment_contents,
is_line_comment,
{physical_loc with loc_start = {physical_loc.loc_start with pos_cnum = n}}
)
else
(original_comment_contents, is_line_comment, physical_loc)
| exception Not_found -> (original_comment_contents, is_line_comment, physical_loc)
in
(com, is_line_comment, attachment_location, physical_loc)
if not is_line_comment then
(* When searching for "^" regexp, returns location of newline + 1 *)
let first_char_of_line = Str.search_backward new_line !chan_input physical_loc.loc_start.pos_cnum in
let end_pos_plus_one = physical_loc.loc_end.pos_cnum in
let comment_length = (end_pos_plus_one - physical_loc.loc_start.pos_cnum - 4) in
(* Also, the string contents originally reported are incorrect! *)
let original_comment_contents = String.sub !chan_input (physical_loc.loc_start.pos_cnum + 2) comment_length in
let (com, is_line_comment, attachment_location) =
match Str.search_forward line_content !chan_input first_char_of_line
with
| n ->
(* Recall that all end positions are actually the position of end + 1. *)
let one_greater_than_comment_end = end_pos_plus_one in
(* Str.string_match lets you specify a position one greater than last position *)
let comment_is_last_thing_on_line =
Str.string_match space_before_newline !chan_input one_greater_than_comment_end in
if n < physical_loc.loc_start.pos_cnum && comment_is_last_thing_on_line then (
original_comment_contents,
is_line_comment,
{physical_loc with loc_start = {physical_loc.loc_start with pos_cnum = n}}
)
else
(original_comment_contents, is_line_comment, physical_loc)
| exception Not_found -> (original_comment_contents, is_line_comment, physical_loc)
in
(com, is_line_comment, attachment_location, physical_loc)
else
(str, is_line_comment, physical_loc, physical_loc)
)
unmodified_comments
in
Expand Down

0 comments on commit b235362

Please sign in to comment.