In the C99 standard, the expressions allow for precedence and associativity.
Precedence is documented quite well since the order in which the operators appear in the
The grammar itself specifies associativity, by the productions used:
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
This means that in a * b * c
, c
must be parsed as a cast-expression
, and a * b
as one multiplicative-expression
, before further parsing of a * b
itself. Thus the left-associativity of multiplication is forced into the syntax-tree by the parsing rules.
Operator associativity isn't specified explicitly as “right-associative” or “left-associative”. You deduce it from the grammar. In your example, the multiplicative-expression
term refers to itself recursively, and the recursion is on the left-hand side of the operator. That means that a parser encountering a * b * c
must parse a * b * c
like (a * b) * c
, which is left-associative.
The assignment-expression
term (6.5.16) has this grammar:
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
So a parser encountering a = b = c
has to parse it like a = (b = c)
, which is right-associative.