From 33979516a692d78017de6b34cc524d9f845585fa Mon Sep 17 00:00:00 2001 From: m Date: Sun, 4 Aug 2024 17:24:00 -0700 Subject: [PATCH] add comments --- src/frontend/parser.rs | 2 +- src/frontend/scanner.rs | 49 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/frontend/parser.rs b/src/frontend/parser.rs index e6ba962..d223989 100644 --- a/src/frontend/parser.rs +++ b/src/frontend/parser.rs @@ -192,7 +192,7 @@ impl<'a> Parser<'a> { } fn parse_selector_list(&mut self) -> Result>>> { - let mut item = self.scanner.peek_token(); + let mut item = self.scanner.peek_non_comment(); if item.1.token == Token::Whitespace { self.scanner.eat_token(); let next = self.scanner.peek_non_whitespace(); diff --git a/src/frontend/scanner.rs b/src/frontend/scanner.rs index 7ee95e9..fc2842b 100644 --- a/src/frontend/scanner.rs +++ b/src/frontend/scanner.rs @@ -44,6 +44,9 @@ pub enum Token { Semi, /// a less than sign `<` to indicate the start of an inline expansion Less, + /// A single-line comment that begins with two forward slashes '//' and + /// spans the rest of the line + Comment, /// special token to indicate the end of the file Eof, /// special token to indicate unknown token @@ -100,6 +103,7 @@ mod statics { Colon <- ":" Semi <- ";" Less <- "<" + Comment <- r"//[^\n]*" }; } } @@ -189,6 +193,24 @@ impl<'a> Scanner<'a> { (span, lexeme) } + /// Looks ahead for the next non-`Comment` [`Lexeme`] + /// and returns it without [eating](Self::eat_token) it. + pub fn peek_non_comment(&mut self) -> (Span, Lexeme<'a>) { + while let ( + _, + Lexeme { + token: Token::Comment, + .. + }, + ) = self.peek_token() + { + self.eat_token(); + } + self.peek_token() + } + + /// Looks ahead for the first non-whitespace, non-comment [`Lexeme`] + /// and returns it without [eating](Self::eat_token) it. pub fn peek_non_whitespace(&mut self) -> (Span, Lexeme<'a>) { while let ( _, @@ -196,7 +218,7 @@ impl<'a> Scanner<'a> { token: Token::Whitespace, .. }, - ) = self.peek_token() + ) = self.peek_non_comment() { self.eat_token(); } @@ -312,6 +334,31 @@ mod tests { assert_eq!(sc.eat_token().1, lx!(BraceClose, "}")); } + #[test] + fn test_comments() { + let mut sc = Scanner::new( + r"// Hello! This is a comment! + b: a // and another! { + { + // } don't be fooled! + }", + ); + + assert_eq!(sc.peek_non_whitespace().1, lx!(Id, "b")); + sc.eat_token(); + assert_eq!(sc.peek_non_whitespace().1, lx!(Colon, ":")); + sc.eat_token(); + assert_eq!(sc.peek_non_whitespace().1, lx!(Id, "a")); + sc.eat_token(); + assert_eq!(sc.peek_non_whitespace().1, lx!(BraceOpen, "{")); + sc.eat_token(); + assert_eq!(sc.eat_token().1.token, Token::Whitespace); + assert_eq!(sc.eat_token().1, lx!(Comment, "// } don't be fooled!")); + assert_eq!(sc.peek_non_whitespace().1, lx!(BraceClose, "}")); + sc.eat_token(); + assert_eq!(sc.eat_token().1.token, Token::Eof); + } + #[test] fn all_regex_is_valid() { let _ = &*REGEX_SET;