views:

299

answers:

8
+12  Q: 

Java syntax of +

Why is the following syntax correct:

x = y+++y;

Where it means y++ + y or y + ++y which means y * 2 + 1 (not sure about this, though: very ambiguous)

But this syntax is incorrect:

x = y+++++y;

Which should mean y++ + ++y, which means y * 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 = 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.)

+10  A: 

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.

Syntactic
y+++++y will likely be parsed as y++ ++ +y , which is not valid..
leeeroy
Yeah, I'm having trouble wrapping my head around exactly which way it'll parse, but any way you look at it, it's awful and wrong.
Syntactic
"Is there a reason for this?"
Pindatjuh
I'm not sure that how the expression is parsed is quite the same as order of evaluation. It might just be a coincidence that javac parses this expression greedily, or it could be clever design. (Or it could be something else entirely. I know almost enough about compiler design to be dangerous.)
Bill the Lizard
+2  A: 

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.

Ben S
A: 

Don't know and don't care because I would never ever use that in real code. Unless you are trying win an obfuscation contest (see the plane: http://en.wikipedia.org/wiki/International_Obfuscated_C_Code_Contest) there are very few applications to this

Pyrolistical
-1 Obviously such code should not be used in production. Anyway it is valid to ask such a question. If at all, then this should be a comment.
Felix Kling
No reason to downvote... +1 because I really don't give a flying f*** neither.
Webinator
+3  A: 

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.

Bill the Lizard
Though the example is not ambiguous; is this a parser bug? If not; "Is there a reason for this?"
Pindatjuh
I don't really think it's a parser bug. The parser seems to be consuming as many `+`'s as it can (two at a time) consistently. Given that, the expression `y+++y` is unambiguously `y++ + y`. The other expression (that gives you an error) is just invalid syntax.
Bill the Lizard
+3  A: 

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.

Etaoin
+2  A: 

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.

Jack
Very insightful. Though, considering it was not done on purpose, but does this mean that the parser rules are fault? Because `y+++++y` is not ambiguous, it fails to parse, which sounds like a prerequisite (or at least something necessary) of a regular language, like the Java syntax.
Pindatjuh
+1 for actually digging into the spec, as I was too lazy to do.
Syntactic
+16  A: 

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

Effectivly 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 there's nothing wrong with.

nos
"This simplify the implementations a lot", thank you!
Pindatjuh
The *scanning* is greedy.
EJP
dude, no pdf link!
irreputable
the spec isn't quite consistent. `>>` should be treated as one token: http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.12 but when in generics like `List<List<String>>` it's parsed into two tokens.
irreputable
A: 

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.

EJP