Show operator precedence?

In the old days, I used to use a handy utility every once in a while to show how the parser interprets operator precedence:

% perl -MO=Deparse,-p -e '$x < 3 && $y < 7' 
(($x < 3) and ($y < 7));

I’ve always found this a lot easier than locating the precedence table in the docs, and trying to remember which way “higher” and “lower” means. Is there something similar in Julia, maybe a macro?

4 Likes

https://docs.julialang.org/en/v1/manual/mathematical-operations/#Operator-Precedence-and-Associativity

Does that cover what you are looking for? Specifically the link to the parser file and/or the operator precedence lookup:

julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.)
(11, 12, 17)
2 Likes

A great utility — especially if you’re already familiar with Lispy (non-)syntaxes — is Meta.show_sexpr:

julia> Meta.show_sexpr(:(x < 3 && y < 7))
(:&&, (:call, :<, :x, 3), (:call, :<, :y, 7))

julia> Meta.show_sexpr(:(x < 3 & y < 7))
(:comparison, :x, :<, (:call, :&, 3, :y), :<, 7)
15 Likes

Meta.@lower could also be useful.

julia> Meta.@lower x < 3 && y < 7
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope`
1 ─ %1 = x < 3
└──      goto #3 if not %1
2 ─ %3 = y < 7
└──      return %3
3 ─      return false
))))
5 Likes

there’s also Meta.@dump which will show the parsing with fewer changes.

1 Like

is there an from_sexpr?

Thanks, those are all good to know - I think Meta.show_sexpr() might be the most directly useful for this purpose. Still takes a bit of brain-scratching to see what’s happening, but not too much.

Another one for the heap, using JuliaSyntax.jl:

julia> JuliaSyntax.parsestmt(SyntaxNode, "x < 3 && y < 7")
line:col│ tree                                   │ file_name
   1:1  │[&&]
   1:1  │  [call-i]
   1:1  │    x
   1:3  │    <
   1:5  │    3
   1:9  │  [call-i]
   1:10 │    y
   1:12 │    <
   1:14 │    7
2 Likes

To go from_sexpr, you plop an Expr in front of each and every parentheses. So (:comparison, :x, :<, (:call, :&, 3, :y), :<, 7) is:

julia> Expr(:comparison, :x, :<, Expr(:call, :&, 3, :y), :<, 7)
:(x < 3 & y < 7)

seems like it could be a useful addition to Base.