improve error for '&' not followed by '&'

This commit is contained in:
Mazdak Farrokhzad 2022-05-31 16:23:25 +02:00
parent c623165742
commit 6399f873f5
5 changed files with 23 additions and 32 deletions

View File

@ -173,13 +173,12 @@ impl Token {
pub(crate) fn eat(input_tendril: &str) -> Result<(usize, Token)> {
let mut input = input_tendril.chars().peekable();
// Error if empty or get the character.
let c = input.peek().ok_or_else(|| ParserError::lexer_empty_input_tendril())?;
// Consumes a single character token.
let single = |input: &mut Peekable<_>, token| {
input.next();
Ok((1, token))
};
// Consumes a character followed by `on` with `then` if found or `els` otherwise.
let followed_by = |input: &mut Peekable<_>, on, then, els| {
input.next();
Ok(if input.next_if_eq(&on).is_some() {
@ -188,11 +187,20 @@ impl Token {
(1, els)
})
};
match *c {
x if x.is_ascii_whitespace() => {
return single(&mut input, Token::WhiteSpace);
// Consumes `on` again and produces `token` if found.
let twice = |input: &mut Peekable<_>, on, token| {
input.next();
if input.next_if_eq(&on).is_some() {
Ok((2, token))
} else if let Some(found) = input.next() {
Err(ParserError::lexer_expected_but_found(found, on).into())
} else {
Err(ParserError::lexer_empty_input_tendril().into())
}
};
match *input.peek().ok_or_else(ParserError::lexer_empty_input_tendril)? {
x if x.is_ascii_whitespace() => return single(&mut input, Token::WhiteSpace),
'"' => {
let mut string: Vec<leo_ast::Char> = Vec::new();
input.next();
@ -216,18 +224,10 @@ impl Token {
return Err(ParserError::lexer_string_not_closed(leo_ast::Chars(string)).into());
}
x if x.is_ascii_digit() => {
return Self::eat_integer(&mut input);
}
x if x.is_ascii_digit() => return Self::eat_integer(&mut input),
'!' => return followed_by(&mut input, '=', Token::NotEq, Token::Not),
'?' => return single(&mut input, Token::Question),
'&' => {
input.next();
if input.next_if_eq(&'&').is_some() {
return Ok((2, Token::And));
}
return Err(ParserError::lexer_empty_input_tendril().into());
}
'&' => return twice(&mut input, '&', Token::And),
'(' => return single(&mut input, Token::LeftParen),
')' => return single(&mut input, Token::RightParen),
'_' => return single(&mut input, Token::Underscore),
@ -290,16 +290,7 @@ impl Token {
']' => return single(&mut input, Token::RightSquare),
'{' => return single(&mut input, Token::LeftCurly),
'}' => return single(&mut input, Token::RightCurly),
'|' => {
input.next();
return if input.next_if_eq(&'|').is_some() {
Ok((2, Token::Or))
} else if let Some(found) = input.next() {
Err(ParserError::lexer_expected_but_found(found, '|').into())
} else {
Err(ParserError::lexer_empty_input_tendril().into())
};
}
'|' => return twice(&mut input, '|', Token::Or),
_ => (),
}
if let Some(ident) = eat_identifier(&mut input) {

View File

@ -41,7 +41,7 @@ outputs:
- "Error [EPAR0370005]: expected ; -- got 'x'\n --> test:1:5\n |\n 1 | u32 x = 10u8;\n | ^"
- "Error [EPAR0370005]: expected ; -- got 'x'\n --> test:1:5\n |\n 1 | u64 x = 10u8;\n | ^"
- "Error [EPAR0370005]: expected ; -- got 'x'\n --> test:1:6\n |\n 1 | u128 x = 10u8;\n | ^"
- "Error [EPAR0370021]: Expected more characters to lex but found none."
- "Error [EPAR0370037]: Found the char ` `, but expected `&`"
- "Error [EPAR0370005]: expected ; -- got '='\n --> test:1:10\n |\n 1 | return x = 10u8;\n | ^"
- "Error [EPAR0370005]: expected ; -- got 'x'\n --> test:1:6\n |\n 1 | self x = 10u8;\n | ^"
- "Error [EPAR0370005]: expected ; -- got 'x'\n --> test:1:6\n |\n 1 | Self x = 10u8;\n | ^"

View File

@ -2,4 +2,4 @@
namespace: Parse
expectation: Fail
outputs:
- "Error [EPAR0370021]: Expected more characters to lex but found none."
- "Error [EPAR0370037]: Found the char `\n`, but expected `&`"

View File

@ -47,7 +47,7 @@ outputs:
- "Error [EPAR0370009]: unexpected string: expected 'expression', got 'if'\n --> test:1:1\n |\n 1 | if 10 u32 {}\n | ^^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', got 'if'\n --> test:1:1\n |\n 1 | if 10 u64 {}\n | ^^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', got 'if'\n --> test:1:1\n |\n 1 | if 10 u128 {}\n | ^^"
- "Error [EPAR0370021]: Expected more characters to lex but found none."
- "Error [EPAR0370037]: Found the char ` `, but expected `&`"
- "Error [EPAR0370009]: unexpected string: expected 'expression', got 'if'\n --> test:1:1\n |\n 1 | if 10 return {}\n | ^^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', got 'if'\n --> test:1:1\n |\n 1 | if 10 self {}\n | ^^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', got 'if'\n --> test:1:1\n |\n 1 | if 10 Self {}\n | ^^"

View File

@ -33,7 +33,7 @@ outputs:
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = a u32 b;\n | ^"
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = a u64 b;\n | ^"
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = a u128 b;\n | ^"
- "Error [EPAR0370021]: Expected more characters to lex but found none."
- "Error [EPAR0370037]: Found the char ` `, but expected `&`"
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = a return b;\n | ^"
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = a self b;\n | ^"
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = a Self b;\n | ^"
@ -56,7 +56,7 @@ outputs:
- "Error [EPAR0370009]: unexpected string: expected 'expression', got '='\n --> test:1:4\n |\n 1 | x>==b;\n | ^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', got '='\n --> test:1:4\n |\n 1 | x<==b;\n | ^"
- "Error [EPAR0370005]: expected ; -- got '..'\n --> test:1:2\n |\n 1 | x..=b;\n | ^^"
- "Error [EPAR0370021]: Expected more characters to lex but found none."
- "Error [EPAR0370037]: Found the char `=`, but expected `&`"
- "Error [EPAR0370041]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x==b;\n | ^^^^^"
- "Error [EPAR0370041]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x!=b;\n | ^^^^^"
- "Error [EPAR0370041]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x>=b;\n | ^^^^^"