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
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.