Skip to content

Commit 45b18c5

Browse files
committed
Fix parser to reject incomplete reductions like ([, ({, ((
Fixes #3138 The parser was incorrectly accepting expressions like ([, ({, and (( as valid syntax, parsing them as atoms instead of rejecting them as incomplete reductions. This fix adds checks in reduce_brackets() to reject when an opening parenthesis is followed by: - Another opening parenthesis ( - Opening bracket [ - Opening curly brace { - Comma , This brings the behavior in line with how curly braces already work, where {[ and {( correctly produce syntax errors. Added comprehensive tests in src/tests/syntax_errors.pl to verify the fix and prevent regressions.
1 parent e4d9692 commit 45b18c5

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

src/parser/parser.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,16 @@ impl<'a, R: CharRead> Parser<'a, R> {
829829

830830
match td.tt {
831831
TokenType::Open | TokenType::OpenCT => {
832-
if self.stack[idx].tt == TokenType::Comma {
833-
return false;
832+
// Reject incomplete reductions: (, ([ ({ ((
833+
match self.stack[idx].tt {
834+
TokenType::Comma
835+
| TokenType::OpenList
836+
| TokenType::OpenCurly
837+
| TokenType::Open
838+
| TokenType::OpenCT => {
839+
return false;
840+
}
841+
_ => {}
834842
}
835843

836844
if let Some(atom) = self.stack[idx].tt.sep_to_atom() {

src/tests/syntax_errors.pl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
:- module(syntax_errors_tests, []).
2+
:- use_module(test_framework).
3+
:- use_module(library(charsio)).
4+
5+
% Test for issue #3138 - ([) should be a syntax error when reading
6+
test("read of ([). should produce syntax_error", (
7+
catch(
8+
(read_from_chars("([).", _), false),
9+
error(syntax_error(_), _),
10+
true
11+
)
12+
)).
13+
14+
% Test that writeq(([)) produces syntax error when reading
15+
test("read of writeq(([)). should produce syntax_error", (
16+
catch(
17+
(read_from_chars("writeq(([)).", _), false),
18+
error(syntax_error(_), _),
19+
true
20+
)
21+
)).
22+
23+
% Test that {[ produces syntax error (already tested in ISO conformity)
24+
test("{[ should produce syntax_error", (
25+
catch(
26+
(read_from_chars("{[}.", _), false),
27+
error(syntax_error(_), _),
28+
true
29+
)
30+
)).
31+
32+
% Test that {( produces syntax error (already tested in ISO conformity)
33+
test("{( should produce syntax_error", (
34+
catch(
35+
(read_from_chars("{(}.", _), false),
36+
error(syntax_error(_), _),
37+
true
38+
)
39+
)).
40+
41+
% Test that (( produces syntax error
42+
test("(( should produce syntax_error", (
43+
catch(
44+
(read_from_chars("((}.", _), false),
45+
error(syntax_error(_), _),
46+
true
47+
)
48+
)).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
args = ["-f", "--no-add-history", "src/tests/syntax_errors.pl", "-f", "-g", "use_module(library(syntax_errors_tests)), syntax_errors_tests:main_quiet(syntax_errors_tests)"]

0 commit comments

Comments
 (0)