Skip to content

Commit

Permalink
FIXED: ISO compatible parsing for fy 2 yf and similar cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
JanWielemaker committed Nov 14, 2024
1 parent b1b0c9d commit 7e4c4d1
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
6 changes: 3 additions & 3 deletions src/Tests/core/test_syntax.pl
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@
term_string_(T, "fy fy 1").
test(r2, T == xfy(1, xfy(2,3))) :-
term_string_(T, "1 xfy 2 xfy 3").
test(r3, [T == xfy(1, yfx(2,3)), blocked(bug)]) :-
test(r3, T == xfy(1, yfx(2,3))) :-
term_string_(T, "1 xfy 2 yfx 3").
test(r4, [T == fy(yf(2)), blocked(bug)]) :-
term_string_(T, "fy 2 fy").
test(r4, T == fy(yf(2))) :-
term_string_(T, "fy 2 yf").
test(r5, T == yf(yf(1))) :-
term_string_(T, "1 yf yf").
test(r6, T == yfx(yfx(1,2),3)) :-
Expand Down
16 changes: 14 additions & 2 deletions src/pl-read.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,8 @@ typedef struct
} op; /* Name of the operator */
unsigned isblock : 1; /* [...] or {...} operator */
unsigned isterm : 1; /* Union is a term */
char kind; /* kind (prefix/postfix/infix) */
char kind; /* kind (OP_PREFIX, ...) */
unsigned char type; /* OP_FX, ... */

This comment has been minimized.

Copy link
@Abramo-Bagnara

Abramo-Bagnara Nov 14, 2024

Nobody read this field, I don't think it is expected

short left_pri; /* priority at left-hand */
short right_pri; /* priority at right hand */
short op_pri; /* priority of operator */
Expand Down Expand Up @@ -3720,6 +3721,7 @@ isOp(DECL_LD op_entry *e, unsigned char kind, ReadData _PL_rd)

if ( !currentOperator(_PL_rd->module, op_name(e), kind, &type, &pri) )
fail;
e->type = type;
e->kind = kind;
e->op_pri = pri;

Expand Down Expand Up @@ -3877,9 +3879,19 @@ typedef enum
} reduce_side;

static bool
must_reduce(const op_entry *sop, const op_entry *fop reduce_side side)
must_reduce(const op_entry *sop, const op_entry *fop, reduce_side side)
{ int cpri = side == REDUCE_LEFT ? fop->left_pri : fop->right_pri;

if ( cpri == sop->op_pri )
{ /* Deal with `fy 2 yf`, `1 xfy 2 yfx 3`, etc. */

if ( ((sop->kind == OP_PREFIX || sop->kind == OP_INFIX) &&
sop->op_pri == sop->right_pri) &&
((fop->kind == OP_POSTFIX || fop->kind == OP_INFIX) &&
fop->op_pri == fop->left_pri) )
return false;
}

return cpri >= sop->op_pri;
}

Expand Down

2 comments on commit 7e4c4d1

@Abramo-Bagnara
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JanWielemaker, please take a look to my comment on line 390

@JanWielemaker
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I first used this and next came up with a more generic approach. I left the field there because it may be useful in the future. Even if the compiler doesn't optimize this the cost are very small.

Please sign in to comment.