Skip to content

Commit

Permalink
Fail to parse a sequence consisting of a single anchor
Browse files Browse the repository at this point in the history
  • Loading branch information
ggiraldez committed Jul 3, 2024
1 parent 908e1a8 commit 50a20a5
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
13 changes: 10 additions & 3 deletions crates/metaslang/cst/src/query/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,15 @@ pub(super) fn parse_matcher_alternatives<T: KindTypes>(
pub(super) fn parse_matcher_sequence<T: KindTypes>(
i: &str,
) -> IResult<&str, ASTNode<T>, VerboseError<&str>> {
many1(parse_sequence_item::<T>)
.map(|children| ASTNode::Sequence(Rc::new(SequenceASTNode { children })))
.parse(i)
verify(
many1(parse_sequence_item::<T>),
|children: &[ASTNode<T>]| {
// 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<T: KindTypes>(
Expand All @@ -79,6 +85,7 @@ pub(super) fn parse_sequence_item<T: KindTypes>(
}

pub(super) fn parse_anchor<T: KindTypes>(i: &str) -> IResult<&str, ASTNode<T>, 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)
Expand Down
15 changes: 12 additions & 3 deletions crates/testlang/outputs/cargo/tests/src/query/parser_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
}
}
Expand All @@ -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"),
}
}
Expand All @@ -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_single_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"),
}
}

0 comments on commit 50a20a5

Please sign in to comment.