Precedence of the power and sign operators
Rainer Schuetze
r.sagitario at gmx.de
Thu Jun 2 01:20:06 PDT 2011
Hi,
compiling this little code snippet
void main()
{
int x = 1;
int a = x++ ^^ 2; // ok
int b = ++x ^^ 2; // error
int c = -x ^^ 2;
}
dmd 2.053 produces this rather unexpected message:
testpow.d(6): Error: int __powtmp4 = x;
, __powtmp4 * __powtmp4 is not an lvalue
Leaving the quality of the error message aside, why is it failing in the
first place? Similar errors happen with unary *,~ and other operators.
This is caused by the way PowExpression is inserted into the grammar:
MulExpression:
UnaryExpression
MulExpression * UnaryExpression
... // more operators /,%
UnaryExpression:
PowExpression
++ UnaryExpression
-- UnaryExpression
* UnaryExpression
- UnaryExpression
... // some more rules recursing on UnaryExpression including
+,&,!,~,delete,cast
PowExpression:
PostfixExpression
PostfixExpression ^^ UnaryExpression
PostfixExpression:
PrimaryExpression
PostfixExpression ++
PostfixExpression --
... // some more rules
Which essentially means that the ^^ binds stronger than prefix
increment, but not as strong as the postfix increment. So, "++x ^^ 2" is
parsed as "++(x ^^ 2)" causing the error later. This was introduced to
let "-x ^^ 2" in the example above yield negative results.
I think the desired way is that ^^ should only have higher precedence
than the sign operators, but lower precedence than any of the other
UnaryExpression operators. The best way I could find to express this in
the grammar is
MulExpression:
SignExpression
MulExpression * SignExpression
... // more operators /,%
SignExpression:
PowExpression
+ SignExpression
- SignExpression
PowExpression:
UnaryExpression2
UnaryExpression2 ^^ SignExpression
UnaryExpression:
UnaryExpression2
+ SignExpression
- SignExpression
UnaryExpression2:
PostfixExpression
++ UnaryExpression
-- UnaryExpression
* UnaryExpression
... // some more rules including &,!,~,delete,cast should recurse on
UnaryExpression
I even dare to say that "- a * b" should also be parsed as "- (a * b)"
to be mathematically correct, but that would break compatibility with
the way it is done in C/C++ (I tried 3 different compilers, it was
always parsed as "(-a) * b"). It might also only make a difference in
case of abused operator overloading.
I'm not so sure whether ! and ~ belong to the same group of operators as
+ and - and should also be added to SignExpression.
What do you think?
Rainer
More information about the Digitalmars-d
mailing list