Open tedinski opened 5 years ago
I think it would be more confusing to use two different terms for precedence.
Ok, I'll defer to you on that one. I checked git blame
for those erroneous lines, and they go all the way back to Derek's initial SVN commit transitioning from CVS. We could chalk the confusion up to documentation back then being poor to non-existent.
Two immediate surprising bugs in Silver:
!1 < 2
parses as!(1 < 2)
-x % 2
parses as-(x % 2)
Precedence guidance
There are a few rules for choosing precedence:
1 + x.y
should naturally parse as1 + (x.y)
and never, ever(1 + x).y
.C has an incredible influence on expectations, and while some of C's choice are, in simple fact, wrong (bitwise operator precedence: just wrong wrong wrong!), most of C's choices are now just universally conventional.
One of C's rules for precedence is:
*a++
is*(a++)
.*x + 1
is(*x) + 1
.What does Silver get wrong?
!
which gives rise to the above unexpected parse.-
for both subtraction and negation, which is incorrect, these should have different precedence.How should we fix this?
First, where?
Not thinking clearly at first, I thought this would be a problem. After all, how do we give two different precedences to
-
? But this is silly: we can applyoperators
to productions. What we're really suffering from here is over-abuse of the precedence/associativity capabilities.We should adopt a new convention of limiting direct application of precedence/association to binary operators only, and instead develop a careful discipline for applying different rules for other operators (or the stray keyword, like
else
).I think we can solve this problem by introducing two new pseudo-terminals:
And the idea is to, on appropriate productions, apply an operator choice explicitly, rather than relying on the implicit operator choice (for everything except normal binary operators.)
So for example:
This gives prefix negation a higher precedence, so
-x%2
will now parse more tightly:(-x) % 2
, as has become expected due to C's conventions.Fun Fact
I just discovered that
neg
already looks like:It seems someone in history thought
precedence
on productions was the same mechanism as precedence on terminals, and had tried to fix this issue. That's not true! This is perhaps evidence we should rename this mechanism?So additional TODO items: