The non-commutavity is a feature, not a bug. It allows you to have clearly defined parsing for grammars that would traditionally be considered ambiguous.
But that’s not how humans writing code generally think about ambiguous expressions. You can see that by how few precedence rules programmers tend to internalize, and often prefer extra parentheses to make sure that the parser interprets it the way they mean.
> But that’s not how humans writing code generally think about ambiguous expressions. You can see that by how few precedence rules programmers tend to internalize
I'd argue that it is how humans think about ambiguous syntax, except in the special case of operator precedence, which is the most complex example. A more salient example to me would be, say, the case of an ‘else’ block after a double-‘if’:
if (c) if (d) X; else Y;
It's technically ambiguous, but you only need to run into it once, see how your IDE auto-formatter indents it, and then you've internalized the precedence rule immediately.
I am not talking about operator precedence, that’s a separate thing. Consider the parsing of math expressions, where juxtaposition of terms denotes multiplication unless it can be interpreted as something else. So f(x+2) is function application, whereas 3(x+2) is multiplication. With a PEG, you just write a standard expression grammar with an additional choice at the end for the implicit multiplication. With a conventional parser, this is much more difficult – you have to explicitly list all the different ways that terms could be next to each other without meaning something else.
We rarely have preferences that are independent of the concrete use case. Your argument boils down to saying that existing precedence hierarchies are badly designed (or else they would always match everyone’s intuitions), but that’s not the case. (Operator precedence is only one illustrative example here.)