diff --git a/src/reason_lexer.mll b/src/reason_lexer.mll index 31fd11845..1ef332ce7 100644 --- a/src/reason_lexer.mll +++ b/src/reason_lexer.mll @@ -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 @@ -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 @@ -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; @@ -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 } diff --git a/src/reason_toolchain.ml b/src/reason_toolchain.ml index 24ad83007..e68d8b154 100644 --- a/src/reason_toolchain.ml +++ b/src/reason_toolchain.ml @@ -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