yash_syntax/parser/lex/
misc.rs1use super::core::Lexer;
20use super::core::is_blank;
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 futures_util::FutureExt;
71
72 #[test]
73 fn lexer_skip_blanks() {
74 let mut lexer = Lexer::with_code(" \t w");
75
76 let c = async {
77 lexer.skip_blanks().await?;
78 lexer.peek_char().await
79 }
80 .now_or_never()
81 .unwrap();
82 assert_eq!(c, Ok(Some('w')));
83
84 let c = async {
86 lexer.skip_blanks().await?;
87 lexer.peek_char().await
88 }
89 .now_or_never()
90 .unwrap();
91 assert_eq!(c, Ok(Some('w')));
92 }
93
94 #[test]
95 fn lexer_skip_blanks_does_not_skip_newline() {
96 let mut lexer = Lexer::with_code("\n");
97 lexer.skip_blanks().now_or_never().unwrap().unwrap();
98 assert_eq!(lexer.peek_char().now_or_never().unwrap(), Ok(Some('\n')));
99 }
100
101 #[test]
102 fn lexer_skip_blanks_skips_line_continuations() {
103 let mut lexer = Lexer::with_code("\\\n \\\n\\\n\\\n \\\nX");
104 let c = async {
105 lexer.skip_blanks().await?;
106 lexer.peek_char().await
107 }
108 .now_or_never()
109 .unwrap();
110 assert_eq!(c, Ok(Some('X')));
111
112 let mut lexer = Lexer::with_code(" \\\n\\\n \\\n Y");
113 let c = async {
114 lexer.skip_blanks().await?;
115 lexer.peek_char().await
116 }
117 .now_or_never()
118 .unwrap();
119 assert_eq!(c, Ok(Some('Y')));
120 }
121
122 #[test]
123 fn lexer_skip_comment_no_comment() {
124 let mut lexer = Lexer::with_code("\n");
125 lexer.skip_comment().now_or_never().unwrap().unwrap();
126 assert_eq!(lexer.peek_char().now_or_never().unwrap(), Ok(Some('\n')));
127 }
128
129 #[test]
130 fn lexer_skip_comment_empty_comment() {
131 let mut lexer = Lexer::with_code("#\n");
132
133 let c = async {
134 lexer.skip_comment().await?;
135 lexer.peek_char().await
136 }
137 .now_or_never()
138 .unwrap();
139 assert_eq!(c, Ok(Some('\n')));
140
141 let c = async {
143 lexer.skip_comment().await?;
144 lexer.peek_char().await
145 }
146 .now_or_never()
147 .unwrap();
148 assert_eq!(c, Ok(Some('\n')));
149 }
150
151 #[test]
152 fn lexer_skip_comment_non_empty_comment() {
153 let mut lexer = Lexer::with_code("\\\n### foo bar\\\n");
154
155 let c = async {
156 lexer.skip_comment().await?;
157 lexer.peek_char().await
158 }
159 .now_or_never()
160 .unwrap();
161 assert_eq!(c, Ok(Some('\n')));
162 assert_eq!(lexer.index(), 14);
163
164 let c = async {
166 lexer.skip_comment().await?;
167 lexer.peek_char().await
168 }
169 .now_or_never()
170 .unwrap();
171 assert_eq!(c, Ok(Some('\n')));
172 assert_eq!(lexer.index(), 14);
173 }
174
175 #[test]
176 fn lexer_skip_comment_not_ending_with_newline() {
177 let mut lexer = Lexer::with_code("#comment");
178
179 let c = async {
180 lexer.skip_comment().await?;
181 lexer.peek_char().await
182 }
183 .now_or_never()
184 .unwrap();
185 assert_eq!(c, Ok(None));
186
187 let c = async {
189 lexer.skip_comment().await?;
190 lexer.peek_char().await
191 }
192 .now_or_never()
193 .unwrap();
194 assert_eq!(c, Ok(None));
195 }
196}