Find escaped characters in strings

This commit is contained in:
Eryn Wells 2016-12-28 08:35:02 -07:00
parent 575ebceb7c
commit 5d5ddf30d0
2 changed files with 32 additions and 0 deletions

View file

@ -10,6 +10,8 @@ pub trait Lexable {
fn is_hash(&self) -> bool;
fn is_dot(&self) -> bool;
fn is_string_quote(&self) -> bool;
fn is_string_escape_leader(&self) -> bool;
fn is_string_escaped(&self) -> bool;
fn is_newline(&self) -> bool;
fn is_eof(&self) -> bool;
@ -44,6 +46,14 @@ impl Lexable for char {
*self == '"'
}
fn is_string_escape_leader(&self) -> bool {
*self == '\\'
}
fn is_string_escaped(&self) -> bool {
*self == '"' || *self == '\\'
}
fn is_boolean_true(&self) -> bool {
*self == 't'
}

View file

@ -38,6 +38,7 @@ enum State {
NumberSign,
Sign,
String,
StringEscape,
}
pub struct Lexer {
@ -357,6 +358,20 @@ impl Lexer {
if c.is_string_quote() {
return self.token_result(Token::String(self.value()));
}
else if c.is_string_escape_leader() {
self.state = State::StringEscape;
}
Ok(None)
}
fn state_string_escape(&mut self, c: char) -> StateResult {
if c.is_string_escaped() {
self.state = State::String;
self.advance();
}
else {
return Err(self.error_string(format!("Invalid string escape character: {}", c)));
}
Ok(None)
}
@ -402,6 +417,7 @@ impl Iterator for Lexer {
State::NumberSign => self.state_number_sign(c),
State::Sign => self.state_sign(c),
State::String => self.state_string(c),
State::StringEscape => self.state_string_escape(c),
State::Comment => self.state_comment(c),
};
assert!(result.has_token() || self.forward != previous_forward, "No lexing progress made!");
@ -488,6 +504,12 @@ mod tests {
check_single_token("\"abc\"", Token::String(String::from("\"abc\"")));
}
#[test]
fn finds_escaped_characters_in_strings() {
check_single_token("\"\\\\\"", Token::String(String::from("\"\\\\\"")));
check_single_token("\"\\\"\"", Token::String(String::from("\"\\\"\"")));
}
#[test]
fn finds_numbers() {
check_single_token(".34", Token::Number(Number::new(0.34)));