diff options
| author | bors <bors@rust-lang.org> | 2013-10-21 14:21:54 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-10-21 14:21:54 -0700 |
| commit | 6dd6623b71ccee5b24117fa14df2bf3e5533e0c7 (patch) | |
| tree | bdf4d3761cc767115812ec8aa2bb3f59e7b54437 /src/libsyntax/parse | |
| parent | ece5028a8be4183ccb203dac59e734f1ca753714 (diff) | |
| parent | 1dc3d0bf86c7e3db3e9b1cb9cfb1f344f9420f0f (diff) | |
| download | rust-6dd6623b71ccee5b24117fa14df2bf3e5533e0c7.tar.gz rust-6dd6623b71ccee5b24117fa14df2bf3e5533e0c7.zip | |
auto merge of #9936 : madjar/rust/master, r=alexcrichton
This should close #9468. I removed the test stating that nested comments should not be implemented. I had a little chicken-and-egg problem because a comment of the std contains "/*", and adding support for nested comment creates a backward incompatibility in that case, so I had to use a dirty hack to get stage1 and stage2 to compile. This part should be revert when this commit lands in a snapshot. This is my first non-typo contribution, so I'm open to any comment.
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)); + } + } |
