Fix more inappropriate use of tabs.

This commit is contained in:
Ethiraric 2023-12-20 23:14:22 +01:00
parent 15e02cf53d
commit e69953bf80
2 changed files with 31 additions and 9 deletions

View file

@ -193,6 +193,8 @@ pub struct Scanner<T> {
flow_level: u8, flow_level: u8,
tokens_parsed: usize, tokens_parsed: usize,
token_available: bool, token_available: bool,
/// Whether all characters encountered since the last newline were whitespace.
leading_whitespace: bool,
} }
impl<T: Iterator<Item = char>> Iterator for Scanner<T> { impl<T: Iterator<Item = char>> Iterator for Scanner<T> {
@ -298,6 +300,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
flow_level: 0, flow_level: 0,
tokens_parsed: 0, tokens_parsed: 0,
token_available: false, token_available: false,
leading_whitespace: true,
} }
} }
@ -319,19 +322,26 @@ impl<T: Iterator<Item = char>> Scanner<T> {
} }
} }
/// Consume the next character. Remove from buffer and update mark.
#[inline] #[inline]
fn skip(&mut self) { fn skip(&mut self) {
let c = self.buffer.pop_front().unwrap(); let c = self.buffer.pop_front().unwrap();
self.mark.index += 1; self.mark.index += 1;
if c == '\n' { if c == '\n' {
self.leading_whitespace = true;
self.mark.line += 1; self.mark.line += 1;
self.mark.col = 0; self.mark.col = 0;
} else { } else {
// TODO(ethiraric, 20/12/2023): change to `self.leading_whitespace &= is_blank(c)`?
if self.leading_whitespace && !is_blank(c) {
self.leading_whitespace = false;
}
self.mark.col += 1; self.mark.col += 1;
} }
} }
/// Consume a linebreak (either CR, LF or CRLF), if any. Do nothing if there's none.
#[inline] #[inline]
fn skip_line(&mut self) { fn skip_line(&mut self) {
if self.buffer[0] == '\r' && self.buffer[1] == '\n' { if self.buffer[0] == '\r' && self.buffer[1] == '\n' {
@ -442,7 +452,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
self.fetch_stream_start(); self.fetch_stream_start();
return Ok(()); return Ok(());
} }
self.skip_to_next_token(); self.skip_to_next_token()?;
self.stale_simple_keys()?; self.stale_simple_keys()?;
@ -577,12 +587,21 @@ impl<T: Iterator<Item = char>> Scanner<T> {
Ok(()) Ok(())
} }
fn skip_to_next_token(&mut self) { fn skip_to_next_token(&mut self) -> ScanResult {
loop { loop {
self.lookahead(1);
// TODO(chenyh) BOM // TODO(chenyh) BOM
match self.ch() { match self.look_ch() {
' ' => self.skip(), ' ' => self.skip(),
// Tabs may not be used as indentation.
// "Indentation" only exists as long as a block is started, but does not exist
// inside of flow-style constructs. Tabs are allowed as part of leaading
// whitespaces outside of indentation.
'\t' if self.is_within_block() && self.leading_whitespace => {
return Err(ScanError::new(
self.mark,
"tabs disallowed within this context (block indentation)",
))
}
'\t' if self.flow_level > 0 || !self.simple_key_allowed => self.skip(), '\t' if self.flow_level > 0 || !self.simple_key_allowed => self.skip(),
'\n' | '\r' => { '\n' | '\r' => {
self.lookahead(2); self.lookahead(2);
@ -600,6 +619,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
_ => break, _ => break,
} }
} }
Ok(())
} }
fn fetch_stream_start(&mut self) { fn fetch_stream_start(&mut self) {
@ -1638,12 +1658,10 @@ impl<T: Iterator<Item = char>> Scanner<T> {
)); ));
} }
if leading_blanks { if !leading_blanks {
self.skip();
} else {
whitespaces.push(self.ch()); whitespaces.push(self.ch());
self.skip();
} }
self.skip();
} else { } else {
self.lookahead(2); self.lookahead(2);
// Check if it is a first line break // Check if it is a first line break
@ -1805,4 +1823,9 @@ impl<T: Iterator<Item = char>> Scanner<T> {
last.possible = false; last.possible = false;
Ok(()) Ok(())
} }
/// Return whether the scanner is inside a block but outside of a flow sequence.
fn is_within_block(&self) -> bool {
!self.indents.is_empty() && self.flow_level == 0
}
} }

View file

@ -305,7 +305,6 @@ static EXPECTED_FAILURES: &[&str] = &[
"DK95-00", "DK95-00",
"Q5MG", "Q5MG",
"Y79Y-06", "Y79Y-06",
"4EJS", // unexpected pass
"Y79Y-03", // unexpected pass "Y79Y-03", // unexpected pass
"Y79Y-04", // unexpected pass "Y79Y-04", // unexpected pass
"Y79Y-05", // unexpected pass "Y79Y-05", // unexpected pass