|
| 1 | +use error::{err_tolerable_seplist0, match_paired_until}; |
1 | 2 | use nom::{ |
2 | 3 | branch::alt, |
3 | | - combinator::{map_res, opt}, |
| 4 | + combinator::{map, map_res, opt, peek}, |
4 | 5 | multi::{many0, separated_list0}, |
5 | | - sequence::{preceded, tuple}, |
| 6 | + sequence::{preceded, terminated, tuple}, |
6 | 7 | IResult, |
7 | 8 | }; |
8 | 9 |
|
9 | | -use crate::{ast::node::function::FuncDefNode, ast::tokens::TokenType}; |
| 10 | +use crate::ast::{diag::ErrorCode, node::function::FuncDefNode, tokens::TokenType}; |
10 | 11 | use crate::{ast::node::function::GeneratorType, nomparser::Span}; |
11 | 12 |
|
12 | 13 | use internal_macro::{test_parser, test_parser_error}; |
13 | 14 |
|
14 | 15 | use super::*; |
15 | 16 |
|
| 17 | +#[test_parser("fn f(a,) int;")] |
16 | 18 | #[test_parser( |
17 | 19 | " |
18 | 20 | /// this is a comment |
@@ -90,21 +92,36 @@ pub fn function_def(input: Span) -> IResult<Span, Box<TopLevel>> { |
90 | 92 | identifier, |
91 | 93 | opt(generic_type_def), |
92 | 94 | tag_token_symbol(TokenType::LPAREN), |
93 | | - del_newline_or_space!(separated_list0( |
94 | | - tag_token_symbol(TokenType::COMMA), |
95 | | - del_newline_or_space!(typed_identifier), |
| 95 | + alt(( |
| 96 | + terminated( |
| 97 | + del_newline_or_space!(err_tolerable_seplist0( |
| 98 | + del_newline_or_space!(typed_identifier), |
| 99 | + del_newline_or_space!(typed_identifier), |
| 100 | + TokenType::COMMA, |
| 101 | + )), |
| 102 | + peek(tag_token_symbol(TokenType::RPAREN)), |
| 103 | + ), |
| 104 | + map( |
| 105 | + match_paired_until( |
| 106 | + ")", |
| 107 | + ErrorCode::SYNTAX_ERROR_FUNC_PARAM, |
| 108 | + "cannot recognize function parameters", |
| 109 | + ), |
| 110 | + |_| vec![], |
| 111 | + ), |
96 | 112 | )), |
97 | 113 | tag_token_symbol(TokenType::RPAREN), |
98 | 114 | type_name, |
99 | 115 | opt(del_newline_or_space!(preceded( |
100 | 116 | tag_token_symbol(TokenType::WHERE), |
101 | | - separated_list0( |
102 | | - tag_token_symbol(TokenType::COMMA), |
| 117 | + err_tolerable_seplist0( |
103 | 118 | del_newline_or_space!(trait_bound), |
104 | | - ), |
| 119 | + del_newline_or_space!(trait_bound), |
| 120 | + TokenType::COMMA |
| 121 | + ) |
105 | 122 | ))), |
106 | 123 | alt(( |
107 | | - map_res(statement_block, |b| Ok::<_, ()>((Some(b.clone()), b.range))), |
| 124 | + map(statement_block, |b| (Some(b.clone()), b.range)), |
108 | 125 | map_res(tag_token_symbol(TokenType::SEMI), |(_, range)| { |
109 | 126 | Ok::<_, ()>((None, range)) |
110 | 127 | }), |
|
0 commit comments