Skip to content

Commit db48e33

Browse files
committed
Fix (|) to ALWAYS error per ISO conformity test s#360
Per clarification on Issue #4 and conformity test s#360: - (|) must be a syntax error regardless of operator status - Even with op(1105,xfy,'|'), writeq((|)) must error - The only valid way to write bar as atom is '|' (quoted) Changes: - Simplify reduce_brackets() to always reject HeadTailSeparator - Remove op_dir parameter (no longer needed) - Update lr_artifacts_3170 tests to use '|' instead of (|) - Add conformity test s#360: (|) errors even with op defined - Add test verifying '|' (quoted) is valid
1 parent a8062de commit db48e33

File tree

3 files changed

+30
-20
lines changed

3 files changed

+30
-20
lines changed

src/parser/parser.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
812812
Ok(false)
813813
}
814814

815-
fn reduce_brackets(&mut self, op_dir: &CompositeOpDir) -> bool {
815+
fn reduce_brackets(&mut self) -> bool {
816816
if self.stack.is_empty() {
817817
return false;
818818
}
@@ -835,18 +835,13 @@ impl<'a, R: CharRead> Parser<'a, R> {
835835
// Reject incomplete reductions and ISO-forbidden syntax
836836
// See: https://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#C2
837837
match self.stack[idx].tt {
838-
TokenType::Comma => {
838+
TokenType::Comma | TokenType::HeadTailSeparator => {
839+
// ISO: (,) and (|) are NEVER valid syntax.
840+
// Bar and comma are solo characters but NOT atoms.
841+
// Use '|' or ',' (quoted) to write them as atoms.
842+
// See conformity test s#360: even with op(1105,xfy,'|'), (|) must error.
839843
return false;
840844
}
841-
TokenType::HeadTailSeparator => {
842-
// ISO TC2 C2: (|) is only valid when | IS an operator
843-
// When | is not an operator, bar is "not an atom" so (|) is invalid
844-
// When | IS an operator, bar is "equivalent to atom '|'" so (|) is valid
845-
if get_op_desc(atom!("|"), op_dir).is_none() {
846-
return false;
847-
}
848-
// Fall through - | is an operator, allow (|)
849-
}
850845
_ => {}
851846
}
852847

@@ -1013,7 +1008,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
10131008
Token::Open => self.shift(Token::Open, 1300, DELIMITER),
10141009
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
10151010
Token::Close => {
1016-
if !self.reduce_term() && !self.reduce_brackets(op_dir) {
1011+
if !self.reduce_term() && !self.reduce_brackets() {
10171012
return Err(ParserError::IncompleteReduction(
10181013
self.lexer.line_num,
10191014
self.lexer.col_num,

src/tests/iso_syntax_errors.pl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,25 @@
1515
)
1616
)).
1717

18+
%% Conformity test s#360: (|) must error even when | IS an operator
19+
%% https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing#360
20+
test("single_bar_in_parens_with_op_defined_should_error", (
21+
op(1105, xfy, '|'),
22+
catch(
23+
(read_from_chars("(|).", _), false),
24+
error(syntax_error(_), _),
25+
true
26+
),
27+
op(0, xfy, '|')
28+
)).
29+
30+
%% ISO: The only valid way to write bar as an atom is '|' (quoted)
31+
%% Per Cor.2 8.14.3.4: permission_error(create, operator, '|')
32+
test("quoted_bar_atom_is_valid", (
33+
read_from_chars("'|'.", T),
34+
T == '|'
35+
)).
36+
1837
test("op_create_empty_curly_should_error", (
1938
catch(
2039
(op(500, xfy, {}), false),

src/tests/lr_artifacts_3170.pl

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,8 @@
8686
op(0, xfy, '|')
8787
)).
8888

89-
test("quoted_bar_in_curly_succeeds", (
90-
op(1105, xfy, '|'),
91-
read_from_chars("{(|)}.", T),
92-
op(0, xfy, '|'),
89+
test("quoted_bar_atom_in_curly_succeeds", (
90+
read_from_chars("{'|'}.", T),
9391
T == '{}'('|')
9492
)).
9593

@@ -100,10 +98,8 @@
10098
T == '{}'('|'(a,b))
10199
)).
102100

103-
test("quoted_bar_in_expression_succeeds", (
104-
op(1105, xfy, '|'),
105-
read_from_chars("{a*(|)}.", T),
106-
op(0, xfy, '|'),
101+
test("quoted_bar_atom_in_expression_succeeds", (
102+
read_from_chars("{a*'|'}.", T),
107103
T == '{}'(a*'|')
108104
)).
109105

0 commit comments

Comments
 (0)