yash_syntax/parser/lex/
misc.rs1use super::core::is_blank;
20use super::core::Lexer;
21use crate::parser::core::Result;
22
23impl Lexer<'_> {
24 pub async fn skip_if<F>(&mut self, f: F) -> Result<bool>
31 where
32 F: FnMut(char) -> bool,
33 {
34 Ok(self.consume_char_if(f).await?.is_some())
35 }
36
37 pub async fn skip_blanks(&mut self) -> Result<()> {
39 while self.skip_if(is_blank).await? {}
40 Ok(())
41 }
42
43 pub async fn skip_comment(&mut self) -> Result<()> {
49 if self.skip_if(|c| c == '#').await? {
50 let mut lexer = self.disable_line_continuation();
51 while lexer.skip_if(|c| c != '\n').await? {}
52 Lexer::enable_line_continuation(lexer);
53 }
54 Ok(())
55 }
56
57 pub async fn skip_blanks_and_comment(&mut self) -> Result<()> {
62 self.skip_blanks().await?;
63 self.skip_comment().await
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use crate::source::Source;
71 use futures_util::FutureExt;
72
73 #[test]
74 fn lexer_skip_blanks() {
75 let mut lexer = Lexer::from_memory(" \t w", Source::Unknown);
76
77 let c = async {
78 lexer.skip_blanks().await?;
79 lexer.peek_char().await
80 }
81 .now_or_never()
82 .unwrap();
83 assert_eq!(c, Ok(Some('w')));
84
85 let c = async {
87 lexer.skip_blanks().await?;
88 lexer.peek_char().await
89 }
90 .now_or_never()
91 .unwrap();
92 assert_eq!(c, Ok(Some('w')));
93 }
94
95 #[test]
96 fn lexer_skip_blanks_does_not_skip_newline() {
97 let mut lexer = Lexer::from_memory("\n", Source::Unknown);
98 lexer.skip_blanks().now_or_never().unwrap().unwrap();
99 assert_eq!(lexer.peek_char().now_or_never().unwrap(), Ok(Some('\n')));
100 }
101
102 #[test]
103 fn lexer_skip_blanks_skips_line_continuations() {
104 let mut lexer = Lexer::from_memory("\\\n \\\n\\\n\\\n \\\nX", Source::Unknown);
105 let c = async {
106 lexer.skip_blanks().await?;
107 lexer.peek_char().await
108 }
109 .now_or_never()
110 .unwrap();
111 assert_eq!(c, Ok(Some('X')));
112
113 let mut lexer = Lexer::from_memory(" \\\n\\\n \\\n Y", Source::Unknown);
114 let c = async {
115 lexer.skip_blanks().await?;
116 lexer.peek_char().await
117 }
118 .now_or_never()
119 .unwrap();
120 assert_eq!(c, Ok(Some('Y')));
121 }
122
123 #[test]
124 fn lexer_skip_comment_no_comment() {
125 let mut lexer = Lexer::from_memory("\n", Source::Unknown);
126 lexer.skip_comment().now_or_never().unwrap().unwrap();
127 assert_eq!(lexer.peek_char().now_or_never().unwrap(), Ok(Some('\n')));
128 }
129
130 #[test]
131 fn lexer_skip_comment_empty_comment() {
132 let mut lexer = Lexer::from_memory("#\n", Source::Unknown);
133
134 let c = async {
135 lexer.skip_comment().await?;
136 lexer.peek_char().await
137 }
138 .now_or_never()
139 .unwrap();
140 assert_eq!(c, Ok(Some('\n')));
141
142 let c = async {
144 lexer.skip_comment().await?;
145 lexer.peek_char().await
146 }
147 .now_or_never()
148 .unwrap();
149 assert_eq!(c, Ok(Some('\n')));
150 }
151
152 #[test]
153 fn lexer_skip_comment_non_empty_comment() {
154 let mut lexer = Lexer::from_memory("\\\n### foo bar\\\n", Source::Unknown);
155
156 let c = async {
157 lexer.skip_comment().await?;
158 lexer.peek_char().await
159 }
160 .now_or_never()
161 .unwrap();
162 assert_eq!(c, Ok(Some('\n')));
163 assert_eq!(lexer.index(), 14);
164
165 let c = async {
167 lexer.skip_comment().await?;
168 lexer.peek_char().await
169 }
170 .now_or_never()
171 .unwrap();
172 assert_eq!(c, Ok(Some('\n')));
173 assert_eq!(lexer.index(), 14);
174 }
175
176 #[test]
177 fn lexer_skip_comment_not_ending_with_newline() {
178 let mut lexer = Lexer::from_memory("#comment", Source::Unknown);
179
180 let c = async {
181 lexer.skip_comment().await?;
182 lexer.peek_char().await
183 }
184 .now_or_never()
185 .unwrap();
186 assert_eq!(c, Ok(None));
187
188 let c = async {
190 lexer.skip_comment().await?;
191 lexer.peek_char().await
192 }
193 .now_or_never()
194 .unwrap();
195 assert_eq!(c, Ok(None));
196 }
197}