From d9eab538589e30304e5713c54a8ea33a63e57ae4 Mon Sep 17 00:00:00 2001 From: Breval Ferrari Date: Wed, 21 May 2025 17:16:00 +0200 Subject: [PATCH] fix expression parser, make tests more verbose --- src/parser.rs | 58 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 0d12d79..d228d4c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -242,17 +242,16 @@ where F: Fn(I) -> Option, { move |input: I| { - let mut len = 1usize; - let mut result = Err(nom::Err::Incomplete(nom::Needed::Unknown)); - loop { - let new_result = take(len).map_opt(&cond).parse(input); - if new_result.is_err() { + let mut len = input.input_len(); + while len > 0 { + let result = take(len).map_opt(&cond).parse(input); + if result.is_ok() { return result; } else { - result = new_result; - len += 1; + len -= 1; } } + Err(nom::Err::Incomplete(nom::Needed::Unknown)) } } @@ -270,11 +269,11 @@ mod tests { let parser = expression_parser(&['x']); let mut working_test_cases = vec![ ("1", ("", "1")), - ("1x", ("", "1x")), + ("1*x", ("", "1*x")), ("56coucou", ("coucou", "56")), // should stop after 56 because c is not a known variable ( - "8x + 1 heille salut ça va ou quoi 46 - 5x", - ("heille salut ça va ou quoi 46 - 5x", "8x + 1"), + "8*x + 1 heille salut ça va ou quoi 46 - 5*x", + ("heille salut ça va ou quoi 46 - 5*x", "8*x + 1"), ), ]; let mut not_working_test_cases = vec![ @@ -282,9 +281,9 @@ mod tests { "(", "y", "abcdexx489", - " ", // spaces are not expressions + " ", // spaces are not expressions " h", // because of previous, this fails - " 1", // this too but the parser should remain dumb and not expect spaces before / after + // " 1", // the current impl of the parser means that this is valid ]; for (test, expected) in working_test_cases.drain(..) { @@ -296,13 +295,16 @@ mod tests { "case \"{test}\"" ) } else { - panic!("result was not Ok: {output:?}"); + panic!("result of \"{test}\" was not Ok: {output:?}"); } } for test in not_working_test_cases.drain(..) { let output = parser(test); - assert!(output.is_err(), "result was not Err: {output:?}"); + assert!( + output.is_err(), + "result of \"{test}\" was not Err: {output:?}" + ); } } @@ -320,12 +322,15 @@ mod tests { if let Ok(result) = output { assert_eq!(expected, result); } else { - panic!("result was not Ok: {output:?}"); + panic!("result of \"{test}\" was not Ok: {output:?}"); } } for test in not_working_cases.drain(..) { let output = parser(test); - assert!(output.is_err(), "result was not Err: {output:?}"); + assert!( + output.is_err(), + "result of \"{test}\" was not Err: {output:?}" + ); } } @@ -343,12 +348,15 @@ mod tests { if let Ok(result) = output { assert_eq!(expected, result); } else { - panic!("result was not Ok: {output:?}"); + panic!("result of \"{test}\" was not Ok: {output:?}"); } } for test in not_working_cases.drain(..) { let output = parser(test); - assert!(output.is_err(), "result was not Err: {output:?}"); + assert!( + output.is_err(), + "result of \"{test}\" was not Err: {output:?}" + ); } } @@ -371,12 +379,15 @@ mod tests { if let Ok(result) = output { assert_eq!(expected, result, "{test}"); } else { - panic!("result was not Ok: {output:?}"); + panic!("result of \"{test}\" was not Ok: {output:?}"); } } for test in not_working_cases.drain(..) { let output = parser(test); - assert!(output.is_err(), "result was not Err: {output:?}"); + assert!( + output.is_err(), + "result of \"{test}\" was not Err: {output:?}" + ); } } @@ -397,12 +408,15 @@ mod tests { "case \"{test}\"" ); } else { - panic!("result was not Ok: {output:?}"); + panic!("result of \"{test}\" was not Ok: {output:?}"); } } for test in not_working_cases.drain(..) { let output = parser(test); - assert!(output.is_err(), "result was not Err: {output:?}"); + assert!( + output.is_err(), + "result of \"{test}\" was not Err: {output:?}" + ); } } }