 Expression Tutor

# The Structure of Expressions

Operator precedence and associativity in Java A programming language has rules that determine precisely how an expression is decomposed into subexpressions. By “decomposing into subexpressions” we mean how we could group subexpressions by surrounding them with parentheses. E.g., expression `1 + 2 * 3` could be grouped into subexpressions as follows:`(1 + (2 * 3))`, which shows that `2 * 3` is a subexpression (but `1 + 2` is not).

Understanding how to decompose expressions is particularly important for expressions that contain multiple operators (like `1 - 2 * 3`).

Some languages (like WeScheme) require that you make the structure of the expression explicit by always using parentheses. Other languages (like Pyret) require parentheses only where expressions otherwise would be ambiguous. Most languages, though, have a set of rules that determine how parenthesis-less expressions are to be decomposed.

Operator Precedence and Associativity

The rules that govern the decomposition are called precedence rules and associativity rules. The precedence rules distinguish between different kinds of operators (where a higher precedence means the operators are grouped into subexpressions earlier). The associativity rules distinguish whether operators of the same precedence should be grouped into subexpressions from left to right or from right to left.

The following expression contains no operator. So we don't have to worry about the decomposition:

`15`

The following expression contains one single operator. So we also don't need to worry in which order operators get evaluated. (However, we might have to worry whether and in which order the operands of the operator are evaluated! That aspect, however, is not part of the operator precedence or associativity rules!)

`width * height`

The following expression contains two operators with different precedence:

`2 * width + height`

Let's assume the expression is written in the Java programming language. Given that in Java the multiplication operator (*) has higher precedence (12) than the addition operator (+, 11), Java first evaluates the multiplication, and then uses the result of the multiplication to evaluate the addition.

The following expression contains two operators of the same precedence:

`12 - 1 + 9`

The associativity of these operators is left-to-right. Thus, first Java computes `12 - 1 = 11`, and then `11 + 9 = 20`. (If the associativity was right-to-left, then it would first compute `1 + 9 = 10`, and then `12 - 10 = 2`. That would lead to a different result!)

Operator Precedence and Associativity in Java

The following table shows, from highest (what happens first) to lowest (what happens last), the precedence of the operators in Java. It also shows their associativity.

PrecedenceOperatorKindAssociativity
15()
[]
·
Parentheses
Array subscript
Member selection
Left to Right
14++
--
Unary post-increment
Unary post-decrement
(not associative)
13++
--
+
-
!
~
( type )
Unary pre-increment
Unary pre-decrement
Unary plus
Unary minus
Unary logical negation
Unary bitwise complement
Unary type cast
Right to left
12*
/
%
Multiplication
Division
Modulus
Left to right
11+
-
Subtraction
Left to right
10<<
>>
>>>
Bitwise left shift
Bitwise right shift with sign extension
Bitwise right shift with zero extension
Left to right
9<
<=
>
>=
instanceof
Relational less than
Relational less than or equal
Relational greater than
Relational greater than or equal
Type comparison (objects only)
(not associative)
8==
!=
Relational is equal to
Relational is not equal to
Left to right
7&Bitwise ANDLeft to right
6^Bitwise exclusive ORLeft to right
5|Bitwise inclusive ORLeft to right
4&&Logical ANDLeft to right
3||Logical ORLeft to right
2? :Ternary conditionalRight to left
1=
+=
-=
*=
/=
%=
Assignment
Subtraction assignment
Multiplication assignment
Division assignment
Modulus assignment
Right to left

Most Java programmers do not memorize this entire table! But they at least understand the precedence and associativity of the basic arithmetic operators (+, -, *, /) one learns in school. And they are able to use the table so they can evaluate or type-check expressions, and so they can properly break an expression into subexpressions.

Examples: Indicating Subexpression Structure with Parentheses

In the following examples we show an expression and then rewrite that expression by adding extra (unnecessary) parentheses. The parentheses show the structure of the expression (how the expression is broken into subexpressions). This is like the tree structure discussed in our “Expression Trees”.

In this first example, all operators have the same precedence (11).

These operators (`+` and `-`) are left-associative (they group left-to-right). Thus,

`a + b - c + d`

means

`(((a + b) - c) + d)`

Equality Operators

The two equality operators (`==` and `!=`) have the same precedence (8).

They are left-associative (they group left-to-right). Thus,

`a == b != c == d`

means

`(((a == b) != c) == d)`

Note: what would the type of `c` and `d` have to be for this expression to type-check?

Assignment Operators

The various assignment operators have the same precedence (1).

They are right-associative (they group right-to-left). Thus,

`a = b += c = d`

means

`(a = (b += (c = d)))`

Note: Using assignment operators in subexpressions is not necessarily good style. Some programmers use them when they want to set multiple variables in one statement (`x = y = 0;`). However, assignments have side effects (they change the value of a variable) and thus using them deep inside an expression can be confusing and should usually be avoided.

Conditional Operator

The ternary conditional operator is right-associative (it groups right-to-left). Thus,

`a ? b : c ? d : e`

means

`(a ? b : (c ? d : e))`