From 01efa0c5f7718428d4e303cf007c3f2bea1d4831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Gir=C3=A1ldez?= Date: Tue, 2 Jul 2024 19:46:08 -0400 Subject: [PATCH] Fail to parse a sequence consisting of a single anchor --- crates/metaslang/cst/src/query/parser.rs | 10 +++++++--- .../outputs/cargo/tests/src/query/parser_tests.rs | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/crates/metaslang/cst/src/query/parser.rs b/crates/metaslang/cst/src/query/parser.rs index fa55c0136..32afe8b2d 100644 --- a/crates/metaslang/cst/src/query/parser.rs +++ b/crates/metaslang/cst/src/query/parser.rs @@ -67,9 +67,12 @@ pub(super) fn parse_matcher_alternatives( pub(super) fn parse_matcher_sequence( i: &str, ) -> IResult<&str, ASTNode, VerboseError<&str>> { - many1(parse_sequence_item::) - .map(|children| ASTNode::Sequence(Rc::new(SequenceASTNode { children }))) - .parse(i) + verify(many1(parse_sequence_item::), |children: &[ASTNode]| { + // It doesn't make sense for a sequence to be a single anchor + children.len() > 1 || !matches!(children[0], ASTNode::Anchor) + }) + .map(|children| ASTNode::Sequence(Rc::new(SequenceASTNode { children }))) + .parse(i) } pub(super) fn parse_sequence_item( @@ -79,6 +82,7 @@ pub(super) fn parse_sequence_item( } pub(super) fn parse_anchor(i: &str) -> IResult<&str, ASTNode, VerboseError<&str>> { + // An anchor is a single '.' character, and cannot be followed by another anchor pair(token('.'), cut(peek(none_of(". \t\r\n")))) .map(|_| ASTNode::Anchor) .parse(i) diff --git a/crates/testlang/outputs/cargo/tests/src/query/parser_tests.rs b/crates/testlang/outputs/cargo/tests/src/query/parser_tests.rs index 923bde751..636a12366 100644 --- a/crates/testlang/outputs/cargo/tests/src/query/parser_tests.rs +++ b/crates/testlang/outputs/cargo/tests/src/query/parser_tests.rs @@ -54,7 +54,7 @@ fn test_zero_or_more_canonicalisation() { fn test_parsing_error() { let result = Query::parse(r#"@root [_"#); match result { - Ok(_) => panic!("Expected error"), + Ok(_) => panic!("Expected parse failure"), Err(e) => assert_eq!(e.message, "Parse error:\nexpected ']' at: \nAlt at: [_\n"), } } @@ -63,7 +63,7 @@ fn test_parsing_error() { fn test_fails_parsing_ellipsis() { let result = Query::parse(r#"[_ ...]"#); match result { - Ok(_) => panic!("Expected error"), + Ok(_) => panic!("Expected parse failure"), Err(e) => assert_eq!(e.message, "Parse error:\nNoneOf at: ..]\n"), } } @@ -72,7 +72,16 @@ fn test_fails_parsing_ellipsis() { fn test_fails_consecutive_anchors() { let result = Query::parse(r#"[_ . .]"#); match result { - Ok(_) => panic!("Expected error"), + Ok(_) => panic!("Expected parse failure"), Err(e) => assert_eq!(e.message, "Parse error:\nNoneOf at: .]\n"), } } + +#[test] +fn test_fails_sole_anchor() { + let result = Query::parse(r#"[_ .]"#); + match result { + Ok(_) => panic!("Expected parse failure"), + Err(e) => assert_eq!(e.message, "Parse error:\nexpected ']' at: .]\nAlt at: [_ .]\n"), + } +}