diff --git a/layout/src/gv/parser/lexer.rs b/layout/src/gv/parser/lexer.rs index ac7b572..1a823be 100644 --- a/layout/src/gv/parser/lexer.rs +++ b/layout/src/gv/parser/lexer.rs @@ -160,7 +160,7 @@ impl Lexer { result } - pub fn read_string(&mut self) -> String { + pub fn read_string(&mut self) -> Token { let mut result = String::new(); self.read_char(); while self.ch != '"' { @@ -173,11 +173,14 @@ impl Lexer { 'l' => '\n', _ => self.ch, } + } else if self.ch == '\0' { + // Reached EOF without completing the string + return Token::Error(self.pos); } result.push(self.ch); self.read_char(); } - result + Token::Identifier(result) } pub fn next_token(&mut self) -> Token { @@ -209,8 +212,7 @@ impl Lexer { tok = Token::Comma; } '"' => { - let value = self.read_string(); - tok = Token::Identifier(value); + tok = self.read_string(); } '-' => { self.read_char(); diff --git a/tests/test.rs b/tests/test.rs index 03959b9..f97da99 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -108,6 +108,18 @@ mod tests { assert!(matches!(lexer.next_token(), Token::EOF)); } + #[test] + fn catch_unterminated_str() { + let mut lexer = Lexer::from_string("digraph { a -> b; \" } "); + assert!(matches!(lexer.next_token(), Token::DigraphKW)); + assert!(matches!(lexer.next_token(), Token::OpenBrace)); + assert!(matches!(lexer.next_token(), Token::Identifier(_))); + assert!(matches!(lexer.next_token(), Token::ArrowRight)); + assert!(matches!(lexer.next_token(), Token::Identifier(_))); + assert!(matches!(lexer.next_token(), Token::Semicolon)); + assert!(matches!(lexer.next_token(), Token::Error(_))); + } + #[test] fn lex_program() { let program = get_sample_program2();