@@ -124,13 +124,11 @@ fn parse_if_else_statement(input: &str) -> IResult<&str, Statement> {
124124 tuple ( (
125125 keyword ( IF_KEYWORD ) ,
126126 preceded ( multispace0, parse_expression) ,
127- parse_block,
128- opt ( preceded (
129- tuple ( ( multispace0, keyword ( ELSE_KEYWORD ) ) ) ,
130- parse_block,
131- ) ) ,
127+ parse_inner_block,
128+ opt ( preceded ( keyword ( ELSE_KEYWORD ) , parse_inner_block) ) ,
129+ preceded ( multispace0, keyword ( END_KEYWORD ) ) ,
132130 ) ) ,
133- |( _, cond, then_block, else_block) | {
131+ |( _, cond, then_block, else_block, _ ) | {
134132 Statement :: IfThenElse (
135133 Box :: new ( cond) ,
136134 Box :: new ( then_block) ,
@@ -143,13 +141,14 @@ fn parse_if_else_statement(input: &str) -> IResult<&str, Statement> {
143141pub fn parse_if_chain_statement ( input : & str ) -> IResult < & str , Statement > {
144142 let ( input_after_if, _) = keyword ( IF_KEYWORD ) ( input) ?;
145143 let ( input_after_expr, cond_if) = parse_expression ( input_after_if) ?;
146- let ( input_after_block, block_if) = parse_block ( input_after_expr) ?;
144+ let ( input_after_block, block_if) = parse_inner_block ( input_after_expr) ?;
147145
148146 let mut branches = vec ! [ ( Box :: new( cond_if) , Box :: new( block_if) ) ] ;
149147 let mut current_input = input_after_block;
150148
151149 loop {
152- let result = tuple ( ( keyword ( ELIF_KEYWORD ) , parse_expression, parse_block) ) ( current_input) ;
150+ let result =
151+ tuple ( ( keyword ( ELIF_KEYWORD ) , parse_expression, parse_inner_block) ) ( current_input) ;
153152 match result {
154153 Ok ( ( next_input, ( _, cond_elif, block_elif) ) ) => {
155154 branches. push ( ( Box :: new ( cond_elif) , Box :: new ( block_elif) ) ) ;
@@ -158,9 +157,11 @@ pub fn parse_if_chain_statement(input: &str) -> IResult<&str, Statement> {
158157 Err ( _) => break ,
159158 }
160159 }
161- let ( input, else_branch) = opt ( preceded ( keyword ( ELSE_KEYWORD ) , parse_block) ) ( current_input) ?;
160+ let ( input_after_else, else_branch) =
161+ opt ( preceded ( keyword ( ELSE_KEYWORD ) , parse_inner_block) ) ( current_input) ?;
162+ let ( input_final, _) = preceded ( multispace0, keyword ( END_KEYWORD ) ) ( input_after_else) ?;
162163 Ok ( (
163- input ,
164+ input_final ,
164165 Statement :: IfChain {
165166 branches,
166167 else_branch : else_branch. map ( Box :: new) ,
@@ -412,6 +413,31 @@ pub fn parse_block(input: &str) -> IResult<&str, Statement> {
412413 ) ( input)
413414}
414415
416+ /// Parses a block without consuming `end`. Used for if/elif/else branches
417+ /// where only the final `end` closes the entire construct.
418+ pub fn parse_inner_block ( input : & str ) -> IResult < & str , Statement > {
419+ map (
420+ tuple ( (
421+ char:: <& str, Error <& str>>( COLON_CHAR ) ,
422+ multispace0,
423+ separated_list0 (
424+ delimited (
425+ multispace0,
426+ char:: <& str, Error <& str>>( SEMICOLON_CHAR ) ,
427+ multispace0,
428+ ) ,
429+ parse_statement,
430+ ) ,
431+ opt ( preceded (
432+ multispace0,
433+ char:: <& str, Error <& str>>( SEMICOLON_CHAR ) ,
434+ ) ) ,
435+ multispace0,
436+ ) ) ,
437+ |( _, _, stmts, _, _) | Statement :: Block ( stmts) ,
438+ ) ( input)
439+ }
440+
415441pub fn parse_formal_argument ( input : & str ) -> IResult < & str , FormalArgument > {
416442 map (
417443 tuple ( (
@@ -552,7 +578,8 @@ mod tests {
552578 assert_eq ! ( parsed_if_only, expected_if_only) ;
553579
554580 // Cenário 2: Um "if" com "else", mas sem "elif".
555- let input_if_else = "if False: x = 1; end else: y = 2; end" ;
581+ // New syntax: only one `end` at the very end
582+ let input_if_else = "if False: x = 1; else: y = 2; end" ;
556583 let expected_if_else = Statement :: IfChain {
557584 branches : vec ! [ (
558585 Box :: new( Expression :: CFalse ) ,
@@ -570,7 +597,8 @@ mod tests {
570597 assert_eq ! ( parsed_if_else, expected_if_else) ;
571598
572599 // Cenário 3: "if", um "elif", e um "else".
573- let input_if_elif_else = "if a: x = 1; end elif b: y = 2; end else: z = 3; end" ;
600+ // New syntax: only one `end` at the very end
601+ let input_if_elif_else = "if a: x = 1; elif b: y = 2; else: z = 3; end" ;
574602 let expected_if_elif_else = Statement :: IfChain {
575603 branches : vec ! [
576604 (
@@ -597,7 +625,8 @@ mod tests {
597625 assert_eq ! ( parsed_if_elif_else, expected_if_elif_else) ;
598626
599627 // Cenário 4: "if" com múltiplos "elif" e sem "else".
600- let input_multi_elif = "if a: x=1; end elif b: y=2; end elif c: z=3; end" ;
628+ // New syntax: only one `end` at the very end
629+ let input_multi_elif = "if a: x=1; elif b: y=2; elif c: z=3; end" ;
601630 let expected_multi_elif = Statement :: IfChain {
602631 branches : vec ! [
603632 (
0 commit comments