Precedence

Unary operators always bind stronger than any binary operator: $a + b is ($a) + b and not $(a + b).

If an unary operator’s first character is @ it is a sigil-like operator which binds stronger than a primarySuffix: @x.abc is parsed as (@x).abc whereas $x.abc is parsed as $(x.abc).

For binary operators that are not keywords the precedence is determined by the following rules:

Operators ending in either ->, ~> or \=> are called arrow like, and have the lowest precedence of all operators.

If the operator ends with \= and its first character is none of <, >, !, \=, ~, ?, it is an assignment operator which has the second lowest precedence.

Otherwise precedence is determined by the first character.

Precedence levelOperatorsFirst characterTerminal symbol
10 (highest)$ ^OP10
9 / div mod shl shr % % \ /OP9
8+ -+ - ~ |OP8
7&&OP7
6...OP6
5== <= < >= > != in notin is isnot not of as from= < > !OP5
4andOP4
3or xorOP3
2@ : ?OP2
1assignment operator (like +=, *=)OP1
0 (lowest)arrow like operator (like ->, =>)OP0

Whether an operator is used as a prefix operator is also affected by preceding whitespace (this parsing change was introduced with version 0.13.0):

  1. echo $foo
  2. # is parsed as
  3. echo($foo)

Spacing also determines whether (a, b) is parsed as an the argument list of a call or whether it is parsed as a tuple constructor:

  1. echo(1, 2) # pass 1 and 2 to echo
  1. echo (1, 2) # pass the tuple (1, 2) to echo