www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Precedence of the power and sign operators

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