Java syntax of +
Why is the following syntax correct:
x = y+++y;
Where it means
y++ + y
ory + ++y
which meansy * 2 + 1
(not sure about this, though: very ambiguous)
But this syntax is incorrect:
x = y+++++y;
Which should mean
y++ + ++y
, which meansy * 2 + 2
Is there a reason for the incorrectness of this syntax? (Edit: thank you for explaining why it is invalid syntax, but that is not my intention with this question.)
(Edit: ofcourse I'm not using this in real code, purely in interest of parsers/lexers; but I wonder why the parser doesn't like this; the last example even looks less ambiguous than the first one.)
(Edit:
int i = 开发者_JS百科0;
int j = (i = 3)+++i;
Is invalid too, though it seems very unambiguous to me, (i = 3)
is a value, thus (value +
value) and then the ++i
value token.)
The parsing is greedy, that is , it looks for the longest matching token first. This simplify the implementations a lot (presumably). Also the Java language spec(3.2) says
Java always uses the longest possible translation at each step, even if the result does not ultimately make a correct Java program, while another lexical translation would
So, for y+++++y;
the parser/tokenizer will break it down something like this:
- variable
y
- operator
++
(as there is no+++
operator,++
is the longest that match the syntax of java) - operator
++
(as there is no+++
operator,++
is the longest that match the syntax of java) - operator
+
(This was the first thing that matches the syntax now) - variable
y
Effectively it is parsed as (y++) (++) (+y)
the ++
operator is defined for a variable, however the first expression (y++
) returns a value. You can't apply the next operator (++
) to a value.
This means that x = y+++y;
would be parsed as y++ + y
, which is nothing wrong with.
In short, because of the order in which Java expressions are evaluated, the parser thinks you're trying to use the ++ operator on an expression, which is illegal.
I think that this:
x = y+++++y;
is getting parsed as something like this:
x = ((y++)++) + y);
or something like this:
x = (y + (++(++y)));
I'll assume that this is just an academic question and that you're not actually trying to use code like that in the real world. Not spacing operators well only leads to pain and suffering.
The Java language spec lists all the rules for evaluating expressions here.
I'm assuming this is because y+++++y;
is parsed as y++++ + y;
and the second ++
is taking y++
as an argument, which is invalid. Remember, the return value of y++
is a value, not a variable. You can't say 5++
for the same reason.
Well, first of all, because this is a disaster. :)
Your first example gets parsed as you expect: y+++y
is (y++) + y
.
But your second example doesn't -- I did some experiments, and y+++++y
is ((y++)++) + y
. What's killing you is that first part, because y++
returns a number, to which you can't apply the ++
operator.
That said, (y++) + (++y)
is valid.
So, from my experiments:
y+++ ++y; // valid
y++ + ++y; // valid
y++ +++y; // Invalid argument to operation ++/--
y+++++y; // Invalid argument to operation ++/--
I'm going to guess that the reason the last two don't work is due to the tokens +++y
. The parser is greedy and parsing ++(+(y))
, which is illegal.
But what does it matter? None of those are legible and shouldn't be used unless you're attempting to write obfuscated Java code.
As you can see here the PreIncrementExpression
is defined as ++ UnaryExpression
but UnaryExpression
can be + UnaryExpression
so it tries to parse it in the wrong order:
y++ ++ +y
trying to apply the ++
operator to +y
, which is illegal.
Just a side node: y+++y
is effectively interpreted as y + ++y
.
Another side note: if you use y++ + ++y
it works.
It's not because of parsing, or the order in which Java expressions are evaluated, or operator precedence either. This is a scanning issue. The consecutive +'s are scanned as ++, yielding a++ ++ +b, which isn't a valid expression.
精彩评论