Skip to content

Commit e772975

Browse files
alanzfacebook-github-bot
authored andcommitted
fix boolean precedence
Summary: The tree-sitter grammar does not properly reflect the erlang precedence rules for binary operations. The key changes are that we initially misunderstood the priority allocations, so it is reversed, and most importantly `orelse` and `andalso` had the highest, rather than lowest priority. This diff aligns it with the erlc compiler, for both precedence and associativity. Reviewed By: TD5 Differential Revision: D70894827 fbshipit-source-id: ebcb3321448e89876806618d1611e931cb2d95de
1 parent 370cea6 commit e772975

File tree

5 files changed

+31720
-30105
lines changed

5 files changed

+31720
-30105
lines changed

grammar.js

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,37 @@ const PREC = {
2020
DCOLON: 1, // `::`
2121
PIPE: 2, // `|`
2222
EQ: 3, // `=` in Expr
23-
PREFIX_OP: 4, // prefix op binds directly to its argument
24-
MULT_OP: 5, // mult_op is left-associative
25-
ADD_OP: 5, // add_op is left-associative
23+
2624
DOTDOT: 6, // `..` in Type
2725
DARROW: 7, // `=>` in Type, Expr
28-
BANG: 13, // `!` in Expr
29-
ORELSE: 14, // `orelse` in Expr
30-
ANDALSO: 15, // `andalso` in Expr
31-
LIST_OP: 16, // `++` / `--` in Expr
26+
27+
28+
// Binary op precedences
29+
// see https://www.erlang.org/doc/system/expressions.html#operator-precedence
30+
//
31+
// Listed in descending order of precedence
32+
// - so earlier entries should have higher tree-sitter precedence
33+
// Operator | Association
34+
// # |
35+
// Unary + - bnot not | PREFIX_OP |
36+
// / * div rem band and | MULT_OP | Left-associative
37+
// + - bor bxor bsl bsr or xor | ADD_OP | Left-associative
38+
// ++ -- | LIST_OP | Right-associative
39+
// == /= =< < >= > =:= =/= | COMP_OP | Non-associative
40+
// andalso | ANDALSO | Left-associative
41+
// orelse | ORELSE | Left-associative
42+
// catch |
43+
// = ! | EQ, BANG | Right-associative
44+
// ?= | Non-associative
45+
46+
PREFIX_OP: 21, // prefix op binds directly to its argument
47+
MULT_OP: 20, // mult_op is left-associative
48+
ADD_OP: 19, // add_op is left-associative
49+
LIST_OP: 18, // `++` / `--` in Expr
3250
COMP_OP: 17, // Comparison operators in Expr
51+
ANDALSO: 15, // `andalso` in Expr
52+
ORELSE: 14, // `orelse` in Expr
53+
BANG: 13, // `!` in Expr
3354

3455
// For remote vs binary :
3556
REMOTE: 1,
@@ -541,18 +562,20 @@ module.exports = grammar({
541562
'?=',
542563
field("rhs", prec.right($._expr)),
543564
)),
565+
566+
// https://www.erlang.org/doc/system/expressions.html#operator-precedence
544567
binary_op_expr: $ => choice(
545568
prec.right(PREC.BANG, seq(
546569
field("lhs", $._expr),
547570
'!',
548571
field("rhs", $._expr),
549572
)),
550-
prec.right(PREC.ORELSE, seq(
573+
prec.left(PREC.ORELSE, seq(
551574
field("lhs", $._expr),
552575
'orelse',
553576
field("rhs", $._expr),
554577
)),
555-
prec.right(PREC.ANDALSO, seq(
578+
prec.left(PREC.ANDALSO, seq(
556579
field("lhs", $._expr),
557580
'andalso',
558581
field("rhs", $._expr),

src/grammar.json

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)