Skip to content

Commit 4cbd2ab

Browse files
kddnewtonmatzbot
authored andcommitted
[ruby/prism] Properly handle non-assoc operators
ruby/prism@dbd5c929d6
1 parent 3571190 commit 4cbd2ab

File tree

5 files changed

+21
-2
lines changed

5 files changed

+21
-2
lines changed

prism/prism.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21764,8 +21764,11 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
2176421764
// Otherwise we'll look and see if the next token can be parsed as an infix
2176521765
// operator. If it can, then we'll parse it using parse_expression_infix.
2176621766
pm_binding_powers_t current_binding_powers;
21767+
pm_token_type_t current_token_type;
21768+
2176721769
while (
21768-
current_binding_powers = pm_binding_powers[parser->current.type],
21770+
current_token_type = parser->current.type,
21771+
current_binding_powers = pm_binding_powers[current_token_type],
2176921772
binding_power <= current_binding_powers.left &&
2177021773
current_binding_powers.binary
2177121774
) {
@@ -21806,6 +21809,13 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
2180621809
// If the operator is nonassoc and we should not be able to parse the
2180721810
// upcoming infix operator, break.
2180821811
if (current_binding_powers.nonassoc) {
21812+
// If this is a non-assoc operator and we are about to parse the
21813+
// exact same operator, then we need to add an error.
21814+
if (match1(parser, current_token_type)) {
21815+
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_NON_ASSOCIATIVE_OPERATOR, pm_token_type_human(parser->current.type), pm_token_type_human(current_token_type));
21816+
break;
21817+
}
21818+
2180921819
// If this is an endless range, then we need to reject a couple of
2181021820
// additional operators because it violates the normal operator
2181121821
// precedence rules. Those patterns are:
@@ -21815,7 +21825,7 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
2181521825
//
2181621826
if (PM_NODE_TYPE_P(node, PM_RANGE_NODE) && ((pm_range_node_t *) node)->right == NULL) {
2181721827
if (match4(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_DOT, PM_TOKEN_AMPERSAND_DOT)) {
21818-
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_NON_ASSOCIATIVE_OPERATOR, pm_token_type_human(parser->current.type), pm_token_type_human(parser->previous.type));
21828+
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_NON_ASSOCIATIVE_OPERATOR, pm_token_type_human(parser->current.type), pm_token_type_human(current_token_type));
2181921829
break;
2182021830
}
2182121831

test/prism/errors/binary_range_with_left_unary_range.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
^~ unexpected range operator; .. and ... are non-associative and cannot be chained
33
...1..
44
^~ unexpected range operator; .. and ... are non-associative and cannot be chained
5+
^~ unexpected ..; .. is a non-associative operator
56
^~ unexpected .., expecting end-of-input
67
^~ unexpected .., ignoring it
78

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
1 == 2 == 3
2+
^~ unexpected '=='; '==' is a non-associative operator
23
^~ unexpected '==', expecting end-of-input
34
^~ unexpected '==', ignoring it
45
1 != 2 != 3
6+
^~ unexpected '!='; '!=' is a non-associative operator
57
^~ unexpected '!=', expecting end-of-input
68
^~ unexpected '!=', ignoring it
79
1 === 2 === 3
10+
^~~ unexpected '==='; '===' is a non-associative operator
811
^~~ unexpected '===', expecting end-of-input
912
^~~ unexpected '===', ignoring it
1013
1 =~ 2 =~ 3
14+
^~ unexpected '=~'; '=~' is a non-associative operator
1115
^~ unexpected '=~', expecting end-of-input
1216
^~ unexpected '=~', ignoring it
1317
1 !~ 2 !~ 3
18+
^~ unexpected '!~'; '!~' is a non-associative operator
1419
^~ unexpected '!~', expecting end-of-input
1520
^~ unexpected '!~', ignoring it
1621
1 <=> 2 <=> 3
22+
^~~ unexpected '<=>'; '<=>' is a non-associative operator
1723
^~~ unexpected '<=>', expecting end-of-input
1824
^~~ unexpected '<=>', ignoring it
1925

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
1..2..3
2+
^~ unexpected ..; .. is a non-associative operator
23
^~ unexpected .., expecting end-of-input
34
^~ unexpected .., ignoring it
45

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
1..2..
2+
^~ unexpected ..; .. is a non-associative operator
23
^~ unexpected .., expecting end-of-input
34
^~ unexpected .., ignoring it
45

0 commit comments

Comments
 (0)