digitalmars.D - Precedence of the power and sign operators
- Rainer Schuetze (76/76) Jun 02 2011 Hi,
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
Jun 02 2011