))
}
}
+
+ pub fn parse_suffix(&mut self) -> Option<TextRange> {
+ let start = self.get_pos();
+ let _ = self.peek()?;
+ while let Some(_) = self.peek() {
+ self.advance();
+ }
+ let end = self.get_pos();
+ Some(TextRange::from_to(start, end))
+ }
}
#[derive(Debug, Eq, PartialEq, Clone)]
-use crate::string_lexing::{
+use crate::{
+ TextRange,
+ string_lexing::{
parser::Parser,
StringComponent,
-};
+}};
pub fn parse_string_literal(src: &str) -> StringComponentIterator {
StringComponentIterator {
parser: Parser::new(src, b'"'),
has_closing_quote: false,
+ suffix: None,
prefix: None,
quote: b'"',
}
StringComponentIterator {
parser: Parser::new(src, b'"'),
has_closing_quote: false,
+ suffix: None,
prefix: Some(b'b'),
quote: b'"',
}
StringComponentIterator {
parser: Parser::new(src, b'\''),
has_closing_quote: false,
+ suffix: None,
prefix: None,
quote: b'\'',
}
StringComponentIterator {
parser: Parser::new(src, b'\''),
has_closing_quote: false,
+ suffix: None,
prefix: Some(b'b'),
quote: b'\'',
}
pub struct StringComponentIterator<'a> {
parser: Parser<'a>,
pub has_closing_quote: bool,
+ pub suffix: Option<TextRange>,
prefix: Option<u8>,
quote: u8,
}
if self.parser.peek() == Some(self.quote as char) {
self.parser.advance();
self.has_closing_quote = true;
+ if let Some(range) = self.parser.parse_suffix() {
+ self.suffix = Some(range);
+ }
}
assert!(
errors.push(SyntaxError::new(UnclosedByte, literal_range));
}
+ if let Some(range) = components.suffix {
+ errors.push(SyntaxError::new(InvalidSuffix, range));
+ }
+
if len == 0 {
errors.push(SyntaxError::new(EmptyByte, literal_range));
}
if !components.has_closing_quote {
errors.push(SyntaxError::new(UnclosedString, literal_range));
}
+
+ if let Some(range) = components.suffix {
+ errors.push(SyntaxError::new(InvalidSuffix, range));
+ }
}
#[cfg(test)]
errors.push(SyntaxError::new(UnclosedChar, literal_range));
}
+ if let Some(range) = components.suffix {
+ errors.push(SyntaxError::new(InvalidSuffix, range));
+ }
+
if len == 0 {
errors.push(SyntaxError::new(EmptyChar, literal_range));
}
if !components.has_closing_quote {
errors.push(SyntaxError::new(UnclosedString, literal_range));
}
+
+ if let Some(range) = components.suffix {
+ errors.push(SyntaxError::new(InvalidSuffix, range));
+ }
}
#[cfg(test)]
OverlongUnicodeEscape,
UnicodeEscapeOutOfRange,
UnclosedString,
+ InvalidSuffix,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
}
UnicodeEscapeOutOfRange => write!(f, "Unicode escape code should be at most 0x10FFFF"),
UnclosedString => write!(f, "Unclosed string literal"),
+ InvalidSuffix => write!(f, "Invalid literal suffix"),
ParseError(msg) => write!(f, "{}", msg.0),
}
}