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

Commit ca96eb8

Browse files
hugoplnobodywasishere
authored andcommitted
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 ca96eb8

File tree

6 files changed

+24307
-18027
lines changed

6 files changed

+24307
-18027
lines changed

grammar.js

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,20 @@ const const_start = /[A-Z]/,
77
['{', '}', '\\}'],
88
['<', '>', '>'],
99
['|', '|', '\\|'],
10-
];
10+
],
11+
PREC = {
12+
DEFAULT: 0,
13+
LOGICAL_OR: 1,
14+
LOGICAL_AND: 2,
15+
INCLUSIVE_OR: 3,
16+
EXCLUSIVE_OR: 4,
17+
BITWISE_AND: 5,
18+
EQUAL: 6,
19+
RELATIONAL: 7,
20+
SHIFT: 9,
21+
ADD: 10,
22+
MULTIPLY: 11,
23+
};
1124

1225
module.exports = grammar({
1326
name: 'crystal',
@@ -446,21 +459,56 @@ module.exports = grammar({
446459
// prec('splat_operator', seq('**', token.immediate($._expression))),
447460

448461
// 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-
),
462+
binary_operation: $ => {
463+
const table = [
464+
['+', PREC.ADD],
465+
['&+', PREC.ADD],
466+
['-', PREC.ADD],
467+
['&-', PREC.ADD],
468+
['*', PREC.MULTIPLY],
469+
['&*', PREC.MULTIPLY],
470+
['/', PREC.MULTIPLY],
471+
['//', PREC.MULTIPLY],
472+
['%', PREC.MULTIPLY],
473+
['||', PREC.LOGICAL_OR],
474+
['&&', PREC.LOGICAL_AND],
475+
['|', PREC.INCLUSIVE_OR],
476+
['^', PREC.EXCLUSIVE_OR],
477+
['&', PREC.BITWISE_AND],
478+
['==', PREC.EQUAL],
479+
['=~', PREC.EQUAL],
480+
['!~', PREC.EQUAL],
481+
['===', PREC.EQUAL],
482+
['<=>', PREC.EQUAL],
483+
['!=', PREC.EQUAL],
484+
['>', PREC.RELATIONAL],
485+
['>=', PREC.RELATIONAL],
486+
['<=', PREC.RELATIONAL],
487+
['<', PREC.RELATIONAL],
488+
['<<', PREC.SHIFT],
489+
['>>', PREC.SHIFT],
490+
];
491+
492+
return choice(...table.map(([operator, precedence]) => {
493+
return prec.left(precedence, seq(
494+
field('left', $._expression),
495+
// @ts-ignore
496+
field('operator', operator),
497+
field('right', $._expression),
498+
));
499+
}));
500+
},
457501

458502
_binary_operator: $ =>
459503
choice(
460504
'+',
505+
'&+',
461506
'-',
507+
'&-',
462508
'*',
509+
'&*',
463510
'/',
511+
'//',
464512
'%',
465513
'&',
466514
'|',
@@ -477,6 +525,7 @@ module.exports = grammar({
477525
'<=>',
478526
'===',
479527
'=~',
528+
'!~',
480529
),
481530
},
482531
});

0 commit comments

Comments
 (0)