*a.b
Is it (*a).b
Or *(a.b)
Your heuristic says it should be the former. Is it? What about this one: *a->b* Name operators (e.g., a::b, a.b, a->b)
* a[b], a(b) expressions
* Unary suffix operators (C doesn't have these, but Rust's ? operator applies)
* Unary prefix operators
* Arithmetic operators, following normal mathematical precedence rules (i.e., a + b / c is a + (b / c), not (a + b) / c). Note that I don't have any mental model of how <<, &, |, ^ compare to each other or the normal {,/,%}; {+,-} rank.
Comparison operators
* Short-circuit operators (&&, ||)
* Ternary operator (?:)--and this one is right-associative.
* Assignment operators
This list I think is fairly objective, although C and some of its children "erroneously" place bitwise {&,|,^} below comparison operators instead of above them. The difference between suffix and prefix unary operators is somewhat debatable, but it actually does make sense if you think of array access and function call expressions as unary suffix operators instead of binary operators.
(...Over the reals. Your mileage may vary in less exact types. The Surgeon General recommends avoiding division in production code. Regulations vary by state.)
(2×3)÷(4×5) = 6÷20 = 0.3
2×(3÷4)×5 = 10×0.75 = 7.5
((2×3)÷4)×5 = 7.5That's kind of one problem with it, it's less PEMDAS and more P, E, MD, AS. Multiplication and division don't have precedence over each other and neither does addition and subtraction. Both of those go from left to right.