Почему x ++ - + - ++ x легально, но x +++ - +++ x нет?

Мне интересно, почему в С# все нормально:

int y = x++-+-++x;

Но

int y = x+++-+++x;

нет? Почему существует смещение против +?

Ответ 1

Два других ответа верны; Я добавлю к ним, что это иллюстрирует некоторые основные принципы лексического анализа:

  • Лексический анализатор близорукий - он имеет минимальный "внешний вид"
  • Лексический анализатор жадный - он пытается сделать самый длинный токен, который он может сейчас.
  • Лексический анализатор не отступает, пытаясь найти альтернативные решения, если один из них не работает.

Эти принципы подразумевают, что +++x будет лексироваться как ++ + x, а не + ++ x.

Затем синтаксический анализатор анализирует ++ + x как ++(+x), а (+x) не является переменной, это значение, поэтому его нельзя увеличить.

Смотрите также: http://blogs.msdn.com/b/ericlippert/archive/2010/10/11/10070831.aspx

Ответ 2

Я использую VS 2012. Это интересно.

Первый может быть проанализирован на:

int y = (x++) - (+(-(++x)));

без изменения конечного результата. Итак, вы можете понять, почему это было бы правильно.

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

int y = (x++)+(-(+(++x)));

.

Я уверен, что Джон Скит или Эрик Липперт или кто-то появится и укажет соответствующую часть спецификации С#. Я даже не знаю, с чего начать. Но просто следуя за общим анализом слева направо, вы могли видеть, где он задохнется от второго.

Ответ 3

Компилятор ищет переменную или свойство после второго ++ в int y = x+++-+++x и не может определить это без пробела или скобок.

Вы можете сделать что-то вроде:

int y = x+++-+(++x); 

или

int y = x++ + -+ ++x;

если хотите.

Причина, по которой первый приведенный вами пример приведен в работе, заключается в том, что компилятор может определить, что +- из ++x; тогда как во втором примере он не может определить, где отделить +++ и, естественно, ожидает переменную после того, как она прочитает первый ++; Короче говоря, компилятор пытается использовать +x как переменную, которая недействительна.

Оба, вероятно, действительны с использованием какого-либо другого компилятора. Это зависит от семантики.