diff options
| author | Georges Dubus <georges.dubus@compiletoi.net> | 2013-10-18 22:51:57 +0200 |
|---|---|---|
| committer | Georges Dubus <georges.dubus@compiletoi.net> | 2013-10-21 21:58:34 +0200 |
| commit | 1dc3d0bf86c7e3db3e9b1cb9cfb1f344f9420f0f (patch) | |
| tree | 32542a3752890539ccd9982df86ee153e079b335 /src/libsyntax/parse | |
| parent | 69e46f3aa922fa651fe53b36a295011c590f09e4 (diff) | |
| download | rust-1dc3d0bf86c7e3db3e9b1cb9cfb1f344f9420f0f.tar.gz rust-1dc3d0bf86c7e3db3e9b1cb9cfb1f344f9420f0f.zip | |
Add support for nested comments
Fixes #9468.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/lexer.rs | 74 |
1 files changed, 41 insertions, 33 deletions
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index a43e018cf49..8edc171fcac 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -373,49 +373,49 @@ pub fn is_block_non_doc_comment(s: &str) -> bool { fn consume_block_comment(rdr: @mut StringReader) -> Option<TokenAndSpan> { // block comments starting with "/**" or "/*!" are doc-comments - let res = if rdr.curr == '*' || rdr.curr == '!' { - let start_bpos = rdr.pos - BytePos(3u); - while !(rdr.curr == '*' && nextch(rdr) == '/') && !is_eof(rdr) { - bump(rdr); - } + let is_doc_comment = rdr.curr == '*' || rdr.curr == '!'; + let start_bpos = rdr.pos - BytePos(if is_doc_comment {3u} else {2u}); + + let mut level: int = 1; + while level > 0 { if is_eof(rdr) { - fatal_span(rdr, start_bpos, rdr.last_pos, - ~"unterminated block doc-comment"); - } else { + let msg = if is_doc_comment { + ~"unterminated block doc-comment" + } else { + ~"unterminated block comment" + }; + fatal_span(rdr, start_bpos, rdr.last_pos, msg); + } else if rdr.curr == '/' && nextch(rdr) == '*' { + level += 1; bump(rdr); bump(rdr); - do with_str_from(rdr, start_bpos) |string| { - // but comments with only "*"s between two "/"s are not - if !is_block_non_doc_comment(string) { - Some(TokenAndSpan{ - tok: token::DOC_COMMENT(str_to_ident(string)), - sp: codemap::mk_sp(start_bpos, rdr.pos) - }) - } else { - None - } - } + } else if rdr.curr == '*' && nextch(rdr) == '/' { + level -= 1; + bump(rdr); + bump(rdr); + } else { + bump(rdr); } - } else { - let start_bpos = rdr.last_pos - BytePos(2u); - loop { - if is_eof(rdr) { - fatal_span(rdr, start_bpos, rdr.last_pos, - ~"unterminated block comment"); - } - if rdr.curr == '*' && nextch(rdr) == '/' { - bump(rdr); - bump(rdr); - break; + } + + let res = if is_doc_comment { + do with_str_from(rdr, start_bpos) |string| { + // but comments with only "*"s between two "/"s are not + if !is_block_non_doc_comment(string) { + Some(TokenAndSpan{ + tok: token::DOC_COMMENT(str_to_ident(string)), + sp: codemap::mk_sp(start_bpos, rdr.pos) + }) } else { - bump(rdr); + None } } + } else { None }; - // restart whitespace munch. - if res.is_some() { res } else { consume_whitespace_and_comments(rdr) } + // restart whitespace munch. + if res.is_some() { res } else { consume_whitespace_and_comments(rdr) } } fn scan_exponent(rdr: @mut StringReader, start_bpos: BytePos) -> Option<~str> { @@ -1056,4 +1056,12 @@ mod test { assert!(!is_line_non_doc_comment("/// blah")); assert!(is_line_non_doc_comment("////")); } + + #[test] fn nested_block_comments() { + let env = setup(@"/* /* */ */'a'"); + let TokenAndSpan {tok, sp: _} = + env.string_reader.next_token(); + assert_eq!(tok,token::LIT_CHAR('a' as u32)); + } + } |
