Skip to content

Commit 4f179e0

Browse files
committed
test: implementação dos testes da função parse_if_chain e correção de erros.
1 parent b4629af commit 4f179e0

3 files changed

Lines changed: 114 additions & 28 deletions

File tree

src/ir/ast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ pub enum Statement {
120120
Assignment(Name, Box<Expression>),
121121
IfThenElse(Box<Expression>, Box<Statement>, Option<Box<Statement>>),
122122
IfChain {
123-
branches: Vec<(Box<Expr>, Box<Block>)>,
124-
else_branch: Option<Box<Block>>,
123+
branches: Vec<(Box<Expression>, Box<Statement>)>,
124+
else_branch: Option<Box<Statement>>,
125125
},
126126
While(Box<Expression>, Box<Statement>),
127127
For(Name, Box<Expression>, Box<Statement>),

src/parser/parser_common.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use nom::{
22
branch::alt,
33
bytes::complete::tag,
4-
character::complete::{alpha1, multispace0},
4+
character::complete::{alpha1, multispace0, alphanumeric1},
55
combinator::{not, peek, recognize},
66
multi::many0,
77
sequence::{delimited, terminated},
@@ -28,6 +28,7 @@ pub const END_KEYWORD: &str = "end";
2828

2929
// Statement keyword constants
3030
pub const IF_KEYWORD: &str = "if";
31+
pub const ELIF_KEYWORD: &str = "elif";
3132
pub const ELSE_KEYWORD: &str = "else";
3233
pub const WHILE_KEYWORD: &str = "while";
3334
pub const FOR_KEYWORD: &str = "for";
@@ -67,11 +68,15 @@ pub fn separator<'a>(sep: &'static str) -> impl FnMut(&'a str) -> IResult<&'a st
6768
}
6869

6970
/// Parses a reserved keyword (e.g., "if") surrounded by optional spaces
70-
/// Fails if followed by an identifier character
71+
/// A implementação da função keyword foi alterada para que seja garantida que a keyword seja uma palavra completa e seja separada por um espaço
7172
pub fn keyword<'a>(kw: &'static str) -> impl FnMut(&'a str) -> IResult<&'a str, &'a str> {
72-
terminated(
73-
delimited(multispace0, tag(kw), multispace0),
74-
not(peek(identifier_start_or_continue)),
73+
delimited(
74+
multispace0,
75+
terminated(
76+
tag(kw),
77+
peek(not(alphanumeric1)),
78+
),
79+
multispace0,
7580
)
7681
}
7782

src/parser/parser_stmt.rs

Lines changed: 102 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::ir::ast::{FormalArgument, Function, Statement};
1313
use crate::parser::parser_common::{
1414
identifier, keyword, ASSERT_KEYWORD, COLON_CHAR, COMMA_CHAR, DEF_KEYWORD, ELSE_KEYWORD,
1515
END_KEYWORD, EQUALS_CHAR, FOR_KEYWORD, FUNCTION_ARROW, IF_KEYWORD, IN_KEYWORD, LEFT_PAREN,
16-
RIGHT_PAREN, SEMICOLON_CHAR, VAL_KEYWORD, VAR_KEYWORD, WHILE_KEYWORD,
16+
RIGHT_PAREN, SEMICOLON_CHAR, VAL_KEYWORD, VAR_KEYWORD, WHILE_KEYWORD, ELIF_KEYWORD
1717
};
1818
use crate::parser::parser_expr::parse_expression;
1919
use crate::parser::parser_type::parse_type;
@@ -100,34 +100,25 @@ fn parse_if_else_statement(input: &str) -> IResult<&str, Statement> {
100100
}
101101

102102
pub fn parse_if_chain_statement(input: &str) -> IResult<&str, Statement> {
103-
let (input, _) = keyword(IF_KEYWORD)(input)?;
104-
let (input, cond_if) = preceded(multispace1, parse_expression)(input)?;
105-
let (input, block_if) = parse_block(input)?;
106-
103+
104+
let (input_after_if, _) = keyword(IF_KEYWORD)(input)?;
105+
let (input_after_expr, cond_if) = parse_expression(input_after_if)?;
106+
let (input_after_block, block_if) = parse_block(input_after_expr)?;
107+
107108
let mut branches = vec![(Box::new(cond_if), Box::new(block_if))];
108-
let mut current_input = input;
109+
let mut current_input = input_after_block;
109110

110111
loop {
111-
let result = tuple((
112-
multispace0,
113-
keyword(ELIF_KEYWORD),
114-
preceded(multispace1, parse_expression),
115-
parse_block,
116-
))(current_input);
117-
112+
let result = tuple((keyword(ELIF_KEYWORD), parse_expression, parse_block))(current_input);
118113
match result {
119-
Ok((next_input, (_, _, cond_elif, block_elif))) => {
114+
Ok((next_input, (_, cond_elif, block_elif))) => {
120115
branches.push((Box::new(cond_elif), Box::new(block_elif)));
121116
current_input = next_input;
122117
}
123118
Err(_) => break,
124119
}
125120
}
126-
let (input, else_branch) = opt(preceded(
127-
tuple((multispace0, keyword(ELSE_KEYWORD))),
128-
parse_block,
129-
))(current_input)?;
130-
121+
let (input, else_branch) = opt(preceded(keyword(ELSE_KEYWORD), parse_block))(current_input)?;
131122
Ok((
132123
input,
133124
Statement::IfChain {
@@ -193,7 +184,8 @@ fn parse_function_definition_statement(input: &str) -> IResult<&str, Statement>
193184
keyword(DEF_KEYWORD),
194185
preceded(multispace1, identifier),
195186
delimited(
196-
char:// Tenta parsear um else opcional:<&str, Error<&str>>(LEFT_PAREN),
187+
// Corrigido: Removido o comentário que quebrava a sintaxe
188+
char::<&str, Error<&str>>(LEFT_PAREN),
197189
separated_list0(
198190
tuple((
199191
multispace0,
@@ -208,7 +200,8 @@ fn parse_function_definition_statement(input: &str) -> IResult<&str, Statement>
208200
preceded(multispace0, parse_type),
209201
parse_block,
210202
)),
211-
|(_, name, ar// Tenta parsear um else opcionalgs, _, t, block)| {
203+
// Corrigido: O nome da variável 'args' agora está correto
204+
|(_, name, args, _, t, block)| {
212205
Statement::FuncDef(Function {
213206
name: name.to_string(),
214207
kind: t,
@@ -381,4 +374,92 @@ mod tests {
381374
let parsed = parse_formal_argument(input).unwrap().1;
382375
assert_eq!(parsed, expected);
383376
}
377+
378+
#[test]
379+
fn test_parse_if_chain_statement() {
380+
381+
// Cenário 1: Apenas um "if", sem "elif" ou "else".
382+
let input_if_only = "if True: x = 1; end";
383+
let expected_if_only = Statement::IfChain {
384+
branches: vec![(
385+
Box::new(Expression::CTrue),
386+
Box::new(Statement::Block(vec![Statement::Assignment(
387+
"x".to_string(),
388+
Box::new(Expression::CInt(1)),
389+
)])),
390+
)],
391+
else_branch: None,
392+
};
393+
let (_, parsed_if_only) = parse_if_chain_statement(input_if_only).unwrap();
394+
assert_eq!(parsed_if_only, expected_if_only);
395+
396+
// Cenário 2: Um "if" com "else", mas sem "elif".
397+
let input_if_else = "if False: x = 1; end else: y = 2; end";
398+
let expected_if_else = Statement::IfChain {
399+
branches: vec![(
400+
Box::new(Expression::CFalse),
401+
Box::new(Statement::Block(vec![Statement::Assignment(
402+
"x".to_string(),
403+
Box::new(Expression::CInt(1)),
404+
)])),
405+
)],
406+
else_branch: Some(Box::new(Statement::Block(vec![Statement::Assignment(
407+
"y".to_string(),
408+
Box::new(Expression::CInt(2)),
409+
)]))),
410+
};
411+
let (_, parsed_if_else) = parse_if_chain_statement(input_if_else).unwrap();
412+
assert_eq!(parsed_if_else, expected_if_else);
413+
414+
// Cenário 3: "if", um "elif", e um "else".
415+
let input_if_elif_else = "if a: x = 1; end elif b: y = 2; end else: z = 3; end";
416+
let expected_if_elif_else = Statement::IfChain {
417+
branches: vec![
418+
(
419+
Box::new(Expression::Var("a".to_string())),
420+
Box::new(Statement::Block(vec![Statement::Assignment(
421+
"x".to_string(),
422+
Box::new(Expression::CInt(1)),
423+
)])),
424+
),
425+
(
426+
Box::new(Expression::Var("b".to_string())),
427+
Box::new(Statement::Block(vec![Statement::Assignment(
428+
"y".to_string(),
429+
Box::new(Expression::CInt(2)),
430+
)])),
431+
),
432+
],
433+
else_branch: Some(Box::new(Statement::Block(vec![Statement::Assignment(
434+
"z".to_string(),
435+
Box::new(Expression::CInt(3)),
436+
)]))),
437+
};
438+
let (_, parsed_if_elif_else) = parse_if_chain_statement(input_if_elif_else).unwrap();
439+
assert_eq!(parsed_if_elif_else, expected_if_elif_else);
440+
441+
// Cenário 4: "if" com múltiplos "elif" e sem "else".
442+
let input_multi_elif = "if a: x=1; end elif b: y=2; end elif c: z=3; end";
443+
let expected_multi_elif = Statement::IfChain {
444+
branches: vec![
445+
(
446+
Box::new(Expression::Var("a".to_string())),
447+
Box::new(Statement::Block(vec![Statement::Assignment("x".to_string(), Box::new(Expression::CInt(1)))])),
448+
),
449+
(
450+
Box::new(Expression::Var("b".to_string())),
451+
Box::new(Statement::Block(vec![Statement::Assignment("y".to_string(), Box::new(Expression::CInt(2)))])),
452+
),
453+
(
454+
Box::new(Expression::Var("c".to_string())),
455+
Box::new(Statement::Block(vec![Statement::Assignment("z".to_string(), Box::new(Expression::CInt(3)))])),
456+
),
457+
],
458+
else_branch: None,
459+
};
460+
let (_, parsed_multi_elif) = parse_if_chain_statement(input_multi_elif).unwrap();
461+
assert_eq!(parsed_multi_elif, expected_multi_elif);
462+
}
384463
}
464+
465+

0 commit comments

Comments
 (0)