2011-09-20 37 views
38

Yo estaba jugando un poco con diferentes cosas, como este¿Por qué funciona "a + + b", pero "a ++ b" no?

var a = 1, b = 2; 
alert(a + - + - + - + - + - + - + - + b); //alerts -1 

y pude quitar los espacios, y no por ello deja trabajar.

a+-+-+-+-+-+-+-+b 

Luego probé

a + + b 

Se corrió y se evalúa a 3, pero cuando me quita los espacios, (a++b) sería no correr, y tenía una advertencia que decía "pros confusas "

puedo entender que en casos como

a+++++b 

que podría interpretarse como cualquiera de los siguientes

(a++) + (++b) 
(a++) + +(+b) 
a + +(+(++b)) 
a + +(+(+(+b))) 

que sería confuso.

Pero en el caso de

a++b 

la única forma válida para interpretar esto, por lo que yo puedo decir, es

a + +b 

Por qué no a++b trabajo?

+8

Supongo que entra en conflicto con a ++ que es synax válido, o ++ b. – TheCodeKing

+3

También podría interpretarse (a ++) bo a (++ b) ... –

+0

'++ b' también es válido – Andrew

Respuesta

57

El analizador Javascript es codicioso (que coincide con el operador válida más larga cada vez), por lo que recibe el operador ++ de a++b, haciendo:

(a++) b 

que es válido. Cuando se pone en espacios a + + b, el analizador lo interpreta así:

(a) + (+b) 

que es válido y funciona a ser tres.

Vea este artículo de Wikipedia en Maximal munch para más detalles.

+7

Creo que esta es la respuesta clave: el analizador es ** codicioso **. – Andrey

+3

Si no fuera codicioso, sería bastante inútil. 'a ++' se interpretaría como 'a + +', que es ilegal. Una de las ideas importantes es que descubrir qué fichas contiene la entrada consiste antes de descubrir qué significan esas fichas. Entonces '++' va a ser el token '++' incluso si ese token no es válido en ese contexto. –

12

Está leyendo a++, luego encuentra un b y no sabe qué hacer con él.

+3

+1 para maximizar Munch! –

+0

@carlnorum, sí. –

7

Esto es b/c de la diferencia en operadores unarios.

"a + + b" is the same as "a + (+b)" 
"a++b" is the same as "(a++) _ b" <--- there is a missing operator where the _ is 
3

Las reglas de precendencia del operador de Javascript para el operador de incremento ++ no tienen asociatividad de izquierda a derecha. Eso significa que a++b se puede interpretar como a++ b o a ++b dependiendo de la implementación particular. De cualquier manera, es un error de sintaxis, ya que tiene 2 variables, un operador único y nada que una las dos variables.

En términos prácticos:

a = 1 
b = 2; 

a++ b; -> 2 2 
a ++b; -> 1 3 

¿Qué significa 1 3 como el código JS?

3

La mayoría de los analizadores de lenguajes de programación intenta trozo más largo del texto que tiene sentido, por lo que cuando Javascript ve:

[a][][][][] 

"variable a" - Tiene sentido, vamos a ver el siguiente carácter:

[a][+][][] 

"va a agregar a varaible un" - Tiene sentido, vamos a ver el siguiente carácter:

[a][+][+][] 

"variable a va-incremento publicar" - Tiene sentido, vamos a ver el próximo carácter,

[a][+][+][b] 

Esto no tiene sentido. Tengo dos expresiones (a ++) y (b) y ningún operador infijo entre ellos.

Si lo haces a+ +b no encontrará el operador ++ y funcionará como a + + b.

1

Longest Match la regla entra en escena aquí. Dice que el analizador tiene que tener en cuenta el token más largo comenzando de izquierda a derecha (supongo que la gramática de Javascript es de izquierda a derecha). Así que solo aplica esta regla y obtendrás tu respuesta.

El analizador comenzará desde la izquierda y formará un, +, + & b tokens separados en el caso de "a + + b" (debido al espacio en blanco entre ellos). En el caso de "a ++ b" aplicará la regla de coincidencia más larga y creará un ++ & b como token. a ++ b como expresión no tiene ningún sentido semántico por lo que no se compilará.

0

La respuesta es que ++ es un operador además de +, y que + + es dos operadores, no un operador ++.

Aunque no es Javascript, C++ tiene una diversión similar con los operadores + y ++. Esto fue investigado en uno de los Gurus of the Week desde hace mucho tiempo.

Cuestiones relacionadas