Skip to content
This repository was archived by the owner on Dec 12, 2024. It is now read-only.

Commit 27b51f9

Browse files
committed
Implement operator precedence.
I just took a look on how tree-sitter-c parser does it. This also adds some missing operators. Parenthesis still not implemented.
1 parent 5d5dc70 commit 27b51f9

File tree

6 files changed

+24302
-18026
lines changed

6 files changed

+24302
-18026
lines changed

grammar.js

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@ const const_start = /[A-Z]/,
99
['|', '|', '\\|'],
1010
];
1111

12+
const PREC = {
13+
DEFAULT: 0,
14+
LOGICAL_OR: 1,
15+
LOGICAL_AND: 2,
16+
INCLUSIVE_OR: 3,
17+
EXCLUSIVE_OR: 4,
18+
BITWISE_AND: 5,
19+
EQUAL: 6,
20+
RELATIONAL: 7,
21+
SHIFT: 9,
22+
ADD: 10,
23+
MULTIPLY: 11,
24+
};
25+
1226
module.exports = grammar({
1327
name: 'crystal',
1428

@@ -446,21 +460,56 @@ module.exports = grammar({
446460
// prec('splat_operator', seq('**', token.immediate($._expression))),
447461

448462
// https://github.com/will/tree-sitter-crystal/blob/15597b307b18028b04d288561f9c29794621562b/grammar.js#L545
449-
binary_operation: $ =>
450-
prec.left(
451-
seq(
452-
$._expression,
453-
alias($._binary_operator, $.operator),
454-
$._expression,
455-
),
456-
),
463+
binary_operation: $ => {
464+
const table = [
465+
['+', PREC.ADD],
466+
['&+', PREC.ADD],
467+
['-', PREC.ADD],
468+
['&-', PREC.ADD],
469+
['*', PREC.MULTIPLY],
470+
['&*', PREC.MULTIPLY],
471+
['/', PREC.MULTIPLY],
472+
['//', PREC.MULTIPLY],
473+
['%', PREC.MULTIPLY],
474+
['||', PREC.LOGICAL_OR],
475+
['&&', PREC.LOGICAL_AND],
476+
['|', PREC.INCLUSIVE_OR],
477+
['^', PREC.EXCLUSIVE_OR],
478+
['&', PREC.BITWISE_AND],
479+
['==', PREC.EQUAL],
480+
['=~', PREC.EQUAL],
481+
['!~', PREC.EQUAL],
482+
['===', PREC.EQUAL],
483+
['<=>', PREC.EQUAL],
484+
['!=', PREC.EQUAL],
485+
['>', PREC.RELATIONAL],
486+
['>=', PREC.RELATIONAL],
487+
['<=', PREC.RELATIONAL],
488+
['<', PREC.RELATIONAL],
489+
['<<', PREC.SHIFT],
490+
['>>', PREC.SHIFT],
491+
];
492+
493+
return choice(...table.map(([operator, precedence]) => {
494+
return prec.left(precedence, seq(
495+
field('left', $._expression),
496+
// @ts-ignore
497+
field('operator', operator),
498+
field('right', $._expression),
499+
));
500+
}));
501+
},
457502

458503
_binary_operator: $ =>
459504
choice(
460505
'+',
506+
'&+',
461507
'-',
508+
'&-',
462509
'*',
510+
'&*',
463511
'/',
512+
'//',
464513
'%',
465514
'&',
466515
'|',
@@ -477,6 +526,7 @@ module.exports = grammar({
477526
'<=>',
478527
'===',
479528
'=~',
529+
'!~',
480530
),
481531
},
482532
});

0 commit comments

Comments
 (0)