Some time ago I looked into this issue carefully. Basically, I tried to figure out some rules that provide a decent approximation to how we interpret formulas on a printed page.
Unfortunately, I can't find my notes on it, but my recollection is the following:
The argument of a named function (sin, cos, log, etc.) is determined as follows:
1. If the first token after the function name is a left delimiter (e.g., left parenthesis, bracket, | (absolute value function), or \langle (bilinear pairing)), then the argument includes up to the matching right delimiter and exponent (if any) but goes no further.
- sin(x)y --> (sin x) y
- sin(x+y)^2y --> (sin((x+y)^2)) y
2. If the first token is another named function, then the argument is the value of the second function (with its argument, as determined recursively by these rules).You can see that these rules seem to be consistent with what WolframAlpha does (although I haven't tested all cases).
- log log log x --> log(log(log x))
- log sin(x)y --> (log(sin x)) y
- log sin(x+y)^2y --> (log(sin((x+y)^2))) y
- log log (x+y)z --> (log(log(x+y))) z
3. Otherwise, the argument is the monomial that comes next, except that it stops just before any left delimiter or named function.
- sin x cos y --> (sin x)(cos y)
- sin x|y| --> (sin x)|y|
- sin x(y+z) --> (sin x)(y+z)
- sin 2x^2y^3+7 --> (sin(2x^2y^3)) + 7
You can see that these rules seem to be consistent with what WolframAlpha does (although I haven't tested all cases).
I doubt that these rules can be implemented within a framework of precedences, though.