@@ -6,14 +6,15 @@ use crate::core::statement::statement_p;
66use crate :: core:: statement_separator:: { comment_separator, common_separator} ;
77use crate :: input:: StringView ;
88use crate :: pc_specific:: * ;
9+ use crate :: tokens:: { TokenMatcher , peek_token} ;
910use crate :: * ;
1011
1112macro_rules! zero_or_more_statements {
1213 ( $exit: expr, ParserError :: $err: ident) => {
13- $crate:: core:: statements:: zero_or_more_statements_p( [ $exit] , Some ( ParserError :: $err) )
14+ $crate:: core:: statements:: zero_or_more_statements_p( & [ $exit] , Some ( ParserError :: $err) )
1415 } ;
1516 ( $( $exit: expr) ,+) => {
16- $crate:: core:: statements:: zero_or_more_statements_p( [ $( $exit) ,+] , None )
17+ $crate:: core:: statements:: zero_or_more_statements_p( & [ $( $exit) ,+] , None )
1718 } ;
1819}
1920
@@ -27,7 +28,7 @@ pub(crate) use zero_or_more_statements;
2728///
2829/// The custom error can be used to specify a custom error when the exit keyword is not found.
2930pub fn zero_or_more_statements_p (
30- exit_keywords : impl IntoIterator < Item = Keyword > + ' static ,
31+ exit_keywords : & [ Keyword ] ,
3132 custom_err : Option < ParserError > ,
3233) -> impl Parser < StringView , Output = Statements , Error = ParserError > {
3334 one_statement_p ( exit_keywords, custom_err)
@@ -39,15 +40,15 @@ pub fn zero_or_more_statements_p(
3940
4041/// Either parses one statement or detects the exit keyword and stops parsing.
4142fn one_statement_p (
42- exit_keywords : impl IntoIterator < Item = Keyword > + ' static ,
43+ exit_keywords : & [ Keyword ] ,
4344 custom_err : Option < ParserError > ,
4445) -> impl Parser < StringView , bool , Output = StatementPos , Error = ParserError > + SetContext < bool > {
4546 one_statement_or_exit_keyword_p ( exit_keywords, custom_err) . and_then (
4647 |statement_or_exit_keyword| match statement_or_exit_keyword {
4748 // we parsed a statement, return it
4849 StatementOrExitKeyword :: Statement ( s) => Ok ( s) ,
4950 // we detected an exit keyword, stop parsing
50- StatementOrExitKeyword :: ExitKeyword ( _keyword ) => default_parse_error ( ) ,
51+ StatementOrExitKeyword :: ExitKeyword => default_parse_error ( ) ,
5152 } ,
5253 )
5354}
@@ -57,7 +58,7 @@ fn one_statement_p(
5758/// which depending on the context (previously parsed statement)
5859/// is either the comment separator (EOL) or the regular separator (EOL or colon).
5960fn one_statement_or_exit_keyword_p (
60- exit_keywords : impl IntoIterator < Item = Keyword > + ' static ,
61+ exit_keywords : & [ Keyword ] ,
6162 custom_err : Option < ParserError > ,
6263) -> impl Parser < StringView , bool , Output = StatementOrExitKeyword , Error = ParserError > + SetContext < bool >
6364{
@@ -101,29 +102,43 @@ fn ctx_demand_separator_p()
101102}
102103
103104fn find_exit_keyword_or_demand_statement_p (
104- exit_keywords : impl IntoIterator < Item = Keyword > + ' static ,
105+ exit_keywords : & [ Keyword ] ,
105106 custom_err : Option < ParserError > ,
106107) -> impl Parser < StringView , Output = StatementOrExitKeyword , Error = ParserError > {
107108 find_exit_keyword_p ( exit_keywords, custom_err) . or ( demand_statement_p ( ) )
108109}
109110
110111fn find_exit_keyword_p (
111- exit_keywords : impl IntoIterator < Item = Keyword > + ' static ,
112+ exit_keywords : & [ Keyword ] ,
112113 custom_err : Option < ParserError > ,
113114) -> impl Parser < StringView , Output = StatementOrExitKeyword , Error = ParserError > {
114- // the first parser will return:
115+ // the parser will return:
115116 // Ok if it finds the keyword (peeking)
116- // Err(false) if it finds something else
117- // Err(true) if it finds EOF
118- let p = keyword_p ( exit_keywords, true )
119- . peek ( )
120- // Ok(None) if it finds the keyword
121- . map ( StatementOrExitKeyword :: ExitKeyword ) ;
117+ // Soft error if it finds something else
118+ // Fatal error if it finds EOF
119+ peek_token ( ) . to_option ( ) . and_then ( move |opt_token| {
120+ match opt_token {
121+ Some ( token) => {
122+ for exit_keyword in exit_keywords {
123+ if exit_keyword. matches_token ( & token) {
124+ return Ok ( StatementOrExitKeyword :: ExitKeyword ) ;
125+ }
126+ }
122127
123- match custom_err {
124- Some ( err) => p. with_fatal_err ( err) . boxed ( ) ,
125- None => p. boxed ( ) ,
126- }
128+ Err ( ParserError :: expected ( & to_syntax_err ( exit_keywords. iter ( ) ) ) )
129+ }
130+ None => {
131+ // eof is fatal
132+ match & custom_err {
133+ Some ( err) => Err ( err. clone ( ) ) ,
134+ None => {
135+ let s = to_syntax_err ( exit_keywords. iter ( ) ) ;
136+ Err ( ParserError :: expected ( & s) . to_fatal ( ) )
137+ }
138+ }
139+ }
140+ }
141+ } )
127142}
128143
129144fn demand_statement_p ( )
@@ -137,5 +152,5 @@ fn demand_statement_p()
137152
138153enum StatementOrExitKeyword {
139154 Statement ( StatementPos ) ,
140- ExitKeyword ( Keyword ) ,
155+ ExitKeyword ,
141156}
0 commit comments