helper function for parsing text within () or {}

This commit is contained in:
Janis 2024-09-13 22:47:04 +02:00
parent 4432cf198e
commit de22a9e01a

View file

@ -1036,6 +1036,8 @@ enum ParseError {
ExpectedEndOfBlock, ExpectedEndOfBlock,
#[error("Dummy Message.")] #[error("Dummy Message.")]
UnmatchedBrace(u32), UnmatchedBrace(u32),
#[error("Dummy Message.")]
UnmatchedDelimiter(u32),
#[error("Error in child node {0:?}.")] #[error("Error in child node {0:?}.")]
ErrorNode(Index), ErrorNode(Index),
} }
@ -2324,40 +2326,14 @@ pub mod ast_gen {
let ident = self.parse_ident(tokens)?; let ident = self.parse_ident(tokens)?;
let Some(open_parens) = tokens.eat_token(Token::OpenParens) else { let parameters = self.parse_parenthesised(tokens, |this, tokens| {
return Err(ErrorInfo { if tokens.is_next_token(Token::CloseParens) {
error: ParseError::ExpectedArgumentList, Ok(this.ast.push_parameter_list([], loc))
loc,
});
};
let parameters = if tokens.is_next_token(Token::CloseParens) {
self.ast.push_parameter_list([], loc)
} else { } else {
match self.parse_parameter_list(tokens) { this.parse_parameter_list(tokens)
Ok(i) => {
_ = tokens.eat_token(Token::Comma);
let Some(_) = tokens.eat_token(Token::CloseParens) else {
return Err(ErrorInfo {
error: ParseError::UnmatchedParens(open_parens.token_pos().start),
loc: tokens.current_source_location(),
});
};
i
} }
Err(err) => {
tokens.advance_past_end_of_parens().ok_or(ErrorInfo {
error: ParseError::UnmatchedParens(open_parens.token_pos().start),
loc: tokens.current_source_location(),
})?; })?;
self.push_error(err.error, err.loc)
}
}
};
let return_type = if let Some(_) = tokens.eat_token(Token::MinusGreater) { let return_type = if let Some(_) = tokens.eat_token(Token::MinusGreater) {
self.parse_type(tokens)? self.parse_type(tokens)?
} else { } else {
@ -3197,6 +3173,134 @@ pub mod ast_gen {
} }
} }
fn parse_with_trailing_semi<F>(
&mut self,
tokens: &mut TokenIterator,
parse: F,
) -> ParseResult<Index>
where
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
{
match parse(self, tokens) {
Ok(i) => {
_ = tokens.eat_token(Token::Semi).ok_or(ErrorInfo {
error: ParseError::ExpectedToken(Token::Semi),
loc: tokens.current_source_location(),
})?;
Ok(i)
}
Err(err) => {
tokens.advance_past_semi().ok_or(ErrorInfo {
error: ParseError::ExpectedToken(Token::Semi),
loc: tokens.current_source_location(),
})?;
Ok(self.push_error(err.error, err.loc))
}
}
}
fn parse_inner<F, E>(
&mut self,
tokens: &mut TokenIterator,
open: Token,
close: Token,
parse: F,
on_err: E,
) -> ParseResult<Index>
where
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
E: FnOnce(&mut Self, &mut TokenIterator, ErrorInfo, TokenItem) -> ParseResult<Index>,
{
let Some(start) = tokens.eat_token(open) else {
return Err(ErrorInfo {
error: ParseError::ExpectedToken(open),
loc: tokens.current_source_location(),
});
};
match parse(self, tokens) {
Ok(i) => {
_ = tokens.eat_token(close).ok_or(ErrorInfo {
error: match open {
Token::OpenBrace => ParseError::UnmatchedBrace(start.token_pos().start),
Token::OpenParens => {
ParseError::UnmatchedParens(start.token_pos().start)
}
Token::OpenSquareBracket => {
ParseError::UnmatchedSquareBracket(start.token_pos().start)
}
_ => ParseError::UnmatchedDelimiter(start.token_pos().start),
},
loc: tokens.current_source_location(),
})?;
Ok(i)
}
Err(e) => on_err(self, tokens, e, start),
}
}
fn parse_inner2<F>(
&mut self,
tokens: &mut TokenIterator,
open: Token,
close: Token,
parse: F,
) -> ParseResult<Index>
where
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
{
self.parse_inner(tokens, open, close, parse, |this, tokens, err, start| {
match close {
Token::CloseBrace => {
tokens.advance_past_end_of_braced().ok_or(ErrorInfo {
error: ParseError::UnmatchedBrace(start.token_pos().start),
loc: tokens.current_source_location(),
})?;
}
Token::CloseParens => {
tokens.advance_past_end_of_parens().ok_or(ErrorInfo {
error: ParseError::UnmatchedParens(start.token_pos().start),
loc: tokens.current_source_location(),
})?;
}
Token::CloseSquareBracket => {
tokens.advance_past_end_of_bracketed().ok_or(ErrorInfo {
error: ParseError::UnmatchedSquareBracket(start.token_pos().start),
loc: tokens.current_source_location(),
})?;
}
Token::Semi => {
tokens.advance_past_semi().ok_or(ErrorInfo {
error: ParseError::ExpectedToken(Token::Semi),
loc: tokens.current_source_location(),
})?;
}
_ => unimplemented!(),
}
Ok(this.push_error(err.error, err.loc))
})
}
fn parse_braced<F>(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult<Index>
where
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
{
self.parse_inner2(tokens, Token::OpenBrace, Token::CloseBrace, parse)
}
fn parse_parenthesised<F>(
&mut self,
tokens: &mut TokenIterator,
parse: F,
) -> ParseResult<Index>
where
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
{
self.parse_inner2(tokens, Token::OpenParens, Token::CloseParens, parse)
}
fn parse_struct_fields( fn parse_struct_fields(
&mut self, &mut self,
tokens: &mut TokenIterator, tokens: &mut TokenIterator,