From de22a9e01a280e871d0b315e8a200fc49a803044 Mon Sep 17 00:00:00 2001 From: Janis Date: Fri, 13 Sep 2024 22:47:04 +0200 Subject: [PATCH] helper function for parsing text within () or {} --- src/ast2/mod.rs | 168 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 136 insertions(+), 32 deletions(-) diff --git a/src/ast2/mod.rs b/src/ast2/mod.rs index e2f4bac..cba20f3 100644 --- a/src/ast2/mod.rs +++ b/src/ast2/mod.rs @@ -1036,6 +1036,8 @@ enum ParseError { ExpectedEndOfBlock, #[error("Dummy Message.")] UnmatchedBrace(u32), + #[error("Dummy Message.")] + UnmatchedDelimiter(u32), #[error("Error in child node {0:?}.")] ErrorNode(Index), } @@ -2324,39 +2326,13 @@ pub mod ast_gen { let ident = self.parse_ident(tokens)?; - let Some(open_parens) = tokens.eat_token(Token::OpenParens) else { - return Err(ErrorInfo { - error: ParseError::ExpectedArgumentList, - loc, - }); - }; - - let parameters = if tokens.is_next_token(Token::CloseParens) { - self.ast.push_parameter_list([], loc) - } else { - match self.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 parameters = self.parse_parenthesised(tokens, |this, tokens| { + if tokens.is_next_token(Token::CloseParens) { + Ok(this.ast.push_parameter_list([], loc)) + } else { + this.parse_parameter_list(tokens) } - }; + })?; let return_type = if let Some(_) = tokens.eat_token(Token::MinusGreater) { self.parse_type(tokens)? @@ -3197,6 +3173,134 @@ pub mod ast_gen { } } + fn parse_with_trailing_semi( + &mut self, + tokens: &mut TokenIterator, + parse: F, + ) -> ParseResult + where + F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, + { + 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( + &mut self, + tokens: &mut TokenIterator, + open: Token, + close: Token, + parse: F, + on_err: E, + ) -> ParseResult + where + F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, + E: FnOnce(&mut Self, &mut TokenIterator, ErrorInfo, TokenItem) -> ParseResult, + { + 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( + &mut self, + tokens: &mut TokenIterator, + open: Token, + close: Token, + parse: F, + ) -> ParseResult + where + F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, + { + 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(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult + where + F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, + { + self.parse_inner2(tokens, Token::OpenBrace, Token::CloseBrace, parse) + } + + fn parse_parenthesised( + &mut self, + tokens: &mut TokenIterator, + parse: F, + ) -> ParseResult + where + F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, + { + self.parse_inner2(tokens, Token::OpenParens, Token::CloseParens, parse) + } + fn parse_struct_fields( &mut self, tokens: &mut TokenIterator,