Подтвердить что ты не робот

Почему работает "+ + b", но "a ++ b" нет?

Я играл с разными вещами, вроде этого

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

и я мог бы удалить пробелы, и он все равно будет работать.

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

Затем я попробовал

a + + b

Он запускался и оценивался до 3, но когда я удалял пробелы, (a++b) он не запускался, и у него было предупреждение, которое гласило: "Confusing plusses."

Я могу понять, что в таких случаях, как

a+++++b

который можно интерпретировать как любое из следующих

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

что это будет путать.

Но в случае

a++b

единственный допустимый способ интерпретировать это, насколько я могу судить,

a + +b

Почему не работает a++b?

4b9b3361

Ответ 1

Парсер Javascript является жадным (он соответствует самому длинному действительному оператору каждый раз), поэтому он получает оператор ++ от a++b, делая:

(a++) b

что является недопустимым. Когда вы помещаете пробелы a + + b, синтаксический анализатор интерпретирует это следующим образом:

(a) + (+b)

который действителен и работает как три.

Подробнее об этом см. в статье в Википедии Максимальный munch.

Ответ 2

Он читает a++, затем встречает b и не знает, что с ним делать.

Ответ 3

Это b/c разности унарных операторов.

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

Ответ 4

Правила оценки оператора Javascript для оператора приращения ++ не имеют лево-правой ассоциативности. Это означает, что a++b можно интерпретировать как a++ b или a ++b в зависимости от конкретной реализации. В любом случае, это синтаксическая ошибка, так как у вас есть 2 переменные, один унарный оператор и ничто не объединяет две переменные.

В практическом плане:

a = 1
b = 2;

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

Что означает 1 3 как JS-код?

Ответ 5

Большинство парсеров языка программирования пытаются получить самый длинный фрагмент текста, который имеет смысл, поэтому, когда Javascript видит:

[a][][][][]

"variable a" - это имеет смысл, пусть видит следующий символ:

[a][+][][]

"будет добавлять в varaible a" - это имеет смысл, пусть видит следующий символ:

[a][+][+][]

"будет использовать переменную post-increment a" - это имеет смысл, пусть видит следующий символ,

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

Это не имеет смысла. У меня есть два выражения (a ++) и (b) и между ними нет инфиксного оператора.

Если вы сделаете это a+ +b, он не найдет оператора ++, и он будет работать как a + + b.

Ответ 6

Самое длинное совпадение. Он говорит, что парсер должен принимать во внимание самый длинный токен, начиная слева направо (я полагаю, что грамматика Javascript - слева направо). Поэтому просто примените это правило, и вы получите ответ.

Парсер начнет с левой стороны и будет делать a +, + и b отдельные токены в случае "a + + b" (из-за пробела между ними). В случае "a ++ b" он применяет самое длинное правило совпадения и будет создавать символы ++ и b в качестве токена. a ++ b как выражение не делает никакого смыслового смысла, поэтому он не будет скомпилирован.

Ответ 7

Ответ заключается в том, что ++ - это оператор, а также +, и что + + - это два + оператора, а не оператор ++.

Хотя это не Javascript, С++ имеет схожую забаву с операторами + и ++. Это было исследовано в одном из "Гуру недели" назад.