0

test262 test suite has test containing source:

var x=0, y=0;
var z=
x
++
++
y

The annotation says:

Since LineTerminator(LT) between Postfix Increment/Decrement Operator(I/DO) and operand is not allowed, two IO(just as two DO and their combination) between two references separated by [LT] after automatic semicolon insertion lead to syntax error

Why does this code lead to syntax error? I think it's a valid code snippet. The code above equals to var z=x; ++ ++ y;. Expression ++ ++ y is allowed by javascript grammar. So what's the problem?

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
sergeyz
  • 1,308
  • 2
  • 14
  • 23
  • 1
    `++ ++ y` is **not allowed at all**! – Naftali Jan 14 '13 at 19:18
  • @Neal but what about this production `UnaryExpression : ++UnaryExpression` ? – sergeyz Jan 14 '13 at 19:36
  • @sergeyz: Productions aren't everything. You could say it's sort of a runtime error, but it's detectable at compile time, since `++` can only take a reference as its operand, but can never yield one. –  Jan 14 '13 at 20:05

3 Answers3

4

This code will become:

var z = x;
++ ++ y;

The ++ ++ y is the root of the problem. Let’s look at why...

++ ++ y gets evaluated as ++(++y). The first step is to evaluate (++y). The ++ operator increments the value referenced by the variable it is next to, and returns the incremented value. The important part here is that it does not return a reference, just a value. So the second step would be ++(1), (or whatever ++y yielded), which is an error, since only references can be incremented.

marcus erronius
  • 3,613
  • 1
  • 16
  • 32
  • 1
    Just as I find the same explanation in ECMA-262, you post this answer :) It's hard to extract these rules from the standard, but it's basically [step 1 of `PutValue`](http://ecma-international.org/ecma-262/5.1/#sec-8.7.2), which is invoked by [step 5 of the prefix increment operator](http://ecma-international.org/ecma-262/5.1/#sec-11.4.4). –  Jan 14 '13 at 20:03
  • @Tinctorius PutValue rules say `If Type(V) is not Reference, throw a ReferenceError exception.` So de jure expression `++ ++ y;` leads to runtime error (exception) ? Not parse error? – sergeyz Jan 14 '13 at 20:15
  • It's usually caught by static analysis. If the compiler is certain that the types are safe (e.g. only if `Type(V)` is a `Reference`, in this case) at compile-time, you can skip a lot of type checking at run-time. It's not a parse error, it could be a runtime error, but it's usually a compile-time error during analysis. –  Jan 14 '13 at 20:20
  • Actually I'm trying to implement js parser. I believe it's better to correct original grammar from specification and report syntax error: `UnaryExpression: ++LeftHandSideExpression` – sergeyz Jan 15 '13 at 05:55
-1

That evaluates to:

var x = 0, y = 0;
var z = x ++ ++ y; //MAKES NO SENSE!
Naftali
  • 144,921
  • 39
  • 244
  • 303
-1

The grammar does not allow a new-line to precede a ++ or -- operator; such a new-line must be converted to a ;. Consequently, the expression must be parsed as though it had been:

var x = 0 , y = 0 ;
var z = x ;
++ ;
++ y ;

The third line is illegal.

References:

Section 7.9.1, "Rules of Automatic Semicolon Insertion", rule 3

Section 11.3, "11.3 Postfix Expressions".

Community
  • 1
  • 1
rici
  • 234,347
  • 28
  • 237
  • 341
  • That's not how it is interpreted. You're allowed to have line terminators between prefix increment/decrement and its operand. –  Jan 14 '13 at 19:59
  • Only *postfix* operators have the “no line break” rule. Prefix operators can consume as many line breaks as they want. Of course, why you would ever want to is beyond me :) – marcus erronius Jan 14 '13 at 20:06
  • @rici [this production](http://www.ecma-international.org/ecma-262/5.1/#sec-11.4) allows expressions `like ++ ++ y;`. It means your code equals to `var z = x; ++ ++ y;`, not `var z = x; ++; ++ y;`. So according to grammar parser accepts input and error actually is runtime exception? – sergeyz Jan 14 '13 at 20:07
  • @sergeyz: indeed, the UnaryExpression production allows multiple autoincrements, even though the PostfixExpression does not. (Truly odd, since in almost no case is a repeated prefix operator meaningful.) So, I agree, I was wrong, and so is the test case. – rici Jan 14 '13 at 20:31
  • 1
    @sergeyz, i checked both mozilla js implementations (SpiderMonkey and JägerMonkey) and both of them implement UnaryExpression as though it included `++ LeftSideExpression | -- LeftSideExpression`, as is also shown in this old Mozilla grammar: http://www-archive.mozilla.org/js/language/grammar14.html . The Google V8 engine parses according to the actual standard, but checks if the argument of prefix ++/-- is a LeftSideExpression and, if not, converts it to a runtime exception; there's a comment which says this is for compatibility with JSC. – rici Jan 14 '13 at 22:14