Почему n +++ n действителен, а n ++++ n - нет?

В Java выражение:

n+++n

Появляется, чтобы оценить как эквивалент:

n++ + n

Несмотря на то, что +n является допустимым унарным оператором с более высоким приоритетом, чем арифметический оператор + в n + n. Таким образом, компилятор полагает, что оператор не может быть унарным оператором и разрешать выражение.

Однако выражение:

n++++n

Не компилируется, хотя существует единственная допустимая возможность для его разрешения:

n++ + +n

++n и +n указаны как имеющие одинаковый приоритет, поэтому почему компилятор разрешает кажущуюся двусмысленность в n+++n в пользу арифметики +, но не делает этого с n++++n?

Ответы

Ответ 1

Файл символизируется (преобразуется в последовательность токенов) сначала с максимальным правилом munch - всегда получает максимально допустимый токен. Ваш текст преобразуется в следующую последовательность:

n ++ ++ n

И это недопустимое выражение.

Из JLS §3.2:

3,2. Лексические переводы

Сырой поток символов Unicode преобразуется в последовательность токенов, используя следующие три лексические шаги перевода, которые применяются в свою очередь:

  • Перевод Unicode-экранов (§3.3) в необработанном потоке Unicode символов к соответствующему символу Юникода. Выделение Unicode формы \uxxxx, где xxxx является шестнадцатеричным значением, представляет код UTF-16, кодирование которого равно xxxx. Этот шаг перевода позволяет любой программе выражаться с использованием только символов ASCII.

  • Перевод потока Юникода, полученного на этапе 1, в поток входных символов и терминаторов строк (§3.4).

  • Перевод потока входных символов и терминаторов строк, полученных на этапе 2, в последовательность входных элементов (§3.5), которые после пробела (п. 3.6) и комментарии (п. 3.7) отбрасываются, содержат токены (п. 3.5), которые являются терминальными символами синтаксической грамматики (§ 2.3).

Самый длинный возможный перевод используется на каждом шаге, даже если результат в конечном итоге не делает правильную программу, а другой лексический перевод.

(Таким образом, входные символы a--b обозначаются (§3.5) как a, --, b, который не является частью какой-либо грамматически корректной программы, хотя токенизация a, -, -, b может быть частью грамматически правильной программа).