Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,10 @@ impl<'a, R: CharRead> Parser<'a, R> {
for (i, desc) in self.stack.iter().rev().enumerate() {
if i % 2 == 0 {
// expect a term or non-comma operator.
// HeadTailSeparator is NEVER valid as a term, even if its spec suggests otherwise
if let TokenType::HeadTailSeparator = desc.tt {
return None;
}
if let TokenType::Comma = desc.tt {
return None;
} else if is_term!(desc.spec) || is_op!(desc.spec) || is_negate!(desc.spec) {
Expand Down
68 changes: 68 additions & 0 deletions tests/scryer/cli/issues/issue_3161_malformed_list_syntax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Issue 3161: Malformed List Syntax in Curly Braces

Tests for the parser bug where malformed list syntax like `[|]` was incorrectly
accepted inside curly braces when preceded by specific operator patterns.

## Test that {!*[|]*} throws syntax error

Before the fix, this incorrectly evaluated to `T = {*}`.
After the fix, it should throw a syntax error.

```trycmd
$ scryer-prolog -f --no-add-history
?- use_module(library(dcgs)).
true.
?- {!*[|]*}=T.
error(syntax_error(incomplete_reduction),read_term/3:1).
?- halt.
```

## Test that {!+[|]+} throws syntax error

```trycmd
$ scryer-prolog -f --no-add-history
?- use_module(library(dcgs)).
true.
?- {!+[|]+}=T.
error(syntax_error(incomplete_reduction),read_term/3:1).
?- halt.
```

## Test that {[|]} throws syntax error

```trycmd
$ scryer-prolog -f --no-add-history
?- {[|]}=T.
error(syntax_error(incomplete_reduction),read_term/3:1).
?- halt.
```

## Test that valid list syntax still works

```trycmd
$ scryer-prolog -f --no-add-history
?- {[a,b,c]}=T, write(T), nl.
{[a,b,c]}
T = {"abc"}.
?- halt.
```

## Test that empty list in curly braces works

```trycmd
$ scryer-prolog -f --no-add-history
?- {[]}=T, write(T), nl.
{[]}
T = {[]}.
?- halt.
```

## Test that cut in curly braces works

```trycmd
$ scryer-prolog -f --no-add-history
?- {!}=T, write(T), nl.
{!}
T = {!}.
?- halt.
```