diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs index 0a90f93b2..ddaaa5aac 100644 --- a/parser/src/lexer.rs +++ b/parser/src/lexer.rs @@ -139,6 +139,16 @@ impl<'input> Lexer<'input> { let mut string_content = String::new(); let start_pos = self.location; + // If the next two characters are also the quote character, then we have a triple-quoted + // string; consume those two characters and ensure that we require a triple-quote to close + let triple_quoted = if self.chr0 == Some(quote_char) && self.chr1 == Some(quote_char) { + self.next_char(); + self.next_char(); + true + } else { + false + }; + loop { match self.next_char() { Some('\\') => { @@ -198,7 +208,19 @@ impl<'input> Lexer<'input> { } Some(c) => { if c == quote_char { - break; + if triple_quoted { + // Look ahead at the next two characters; if we have two more + // quote_chars, it's the end of the string; consume the remaining + // closing quotes and break the loop + if self.chr0 == Some(quote_char) && self.chr1 == Some(quote_char) { + self.next_char(); + self.next_char(); + break; + } + string_content.push(c); + } else { + break; + } } else { string_content.push(c); } diff --git a/tests/snippets/strings.py b/tests/snippets/strings.py new file mode 100644 index 000000000..b95e5edc0 --- /dev/null +++ b/tests/snippets/strings.py @@ -0,0 +1,10 @@ +assert "a" == 'a' +assert """a""" == "a" +assert len(""" " "" " "" """) == 11 +assert "\"" == '"' +assert "\"" == """\"""" + +assert "\n" == """ +""" + +assert len(""" " \" """) == 5