Почему следующий корректный синтаксис:
x = y+++y;
Где это означает
y++ + y
илиy + ++y
что означаетy * 2 + 1
(не уверенный в этом, хотя: очень неоднозначный)
Но этот синтаксис является неправильным:
x = y+++++y;
Который должен означать
y++ + ++y
, что означаетy * 2 + 2
Существует ли причина неправильности этого синтаксиса? (Редактирование: спасибо за объяснение, почему это - недопустимый синтаксис, но это не мое намерение с этим вопросом.)
(Редактирование: конечно, я не использую это в реальном коде, просто в интересе синтаксических анализаторов/лексических анализаторов; но интересно, почему синтаксическому анализатору не нравится это; последний пример даже выглядит менее неоднозначным, чем первый.)
(Редактирование:
int i = 0;
int j = (i = 3)+++i;
Недопустимо также, хотя это кажется очень однозначным мне, (i = 3)
значение, таким образом (значение +
значение) и затем ++i
маркер значения.)
Анализ является жадным, то есть сначала ищет самый длинный совпадающий токен. Это сильно упрощает реализацию (предположительно). Также в спецификации языка Java (3.2) говорится, что
Java всегда использует максимально длинный перевод на каждом шаге, даже если результат в конечном итоге не дает {{ 1}} исправит программу Java, тогда как другой лексический перевод будет
Итак, для y +++++ y;
синтаксический анализатор / токенизатор сломает его примерно так:
y
++
(поскольку нет оператора +++
, ++
является самым длинным, соответствующим синтаксису of java) ++
(поскольку нет оператора +++
, ++
является самым длинным, который соответствует синтаксису java) +
(Это первое, что теперь соответствует синтаксису) y
Фактически она анализируется как (y ++) (++) (+ y)
оператор ++
определен для переменной, однако первое выражение ( y ++
) возвращает значение. К значению нельзя применить следующий оператор ( ++
).
Это означает, что x = y +++ y;
будет проанализирован как y ++ + y
, в чем нет ничего плохого.
Короче говоря, из-за порядка, в котором вычисляются выражения Java, синтаксический анализатор думает, что вы пытаетесь использовать оператор ++ в выражении, которое незаконно.
Я думаю, что это:
x = y+++++y;
разбирается как что-то вроде этого:
x = ((y++)++) + y);
или что-то вроде этого:
x = (y + (++(++y)));
Я предполагаю, что это просто академический вопрос, и что вы на самом деле не пытаетесь используйте такой код в реальном мире. Недостаточное расстояние между операторами приводит только к боли и страданиям.
В спецификации языка Java перечислены все правила вычисления выражений здесь .
Ну, во-первых, потому что это катастрофа. :)
Ваш первый пример разбирается так, как вы ожидаете: y+++y
- это (y++) + y
.
Но ваш второй пример не работает - я провел несколько экспериментов, и y+++++y
- это ((y++)++) + y
. Вас убивает первая часть, потому что y++
возвращает число, к которому нельзя применить оператор ++
.
При этом (y++) + (++y)
является допустимым.
Я предполагаю, что это потому, что y +++++ y;
анализируется как y ++++ + y;
, а второй ++
принимает y ++
в качестве недопустимого аргумента. Помните, что возвращаемое значение y ++
- это значение, а не переменная. Вы не можете сказать 5 ++
по той же причине.
Как вы можете видеть здесь, PreIncrementExpression
определяется как ++ UnaryExpression
но UnaryExpression
может быть + UnaryExpression
, поэтому он пытается разобрать его в неправильном порядке:
y++ ++ +y
пытается применить оператор ++
к +y
, что незаконно.
Просто боковой узел: y+++y
эффективно интерпретируется как y+++y
.
Еще одно побочное замечание: если вы используете y++ + ++y
, то это работает.
Это не из-за синтаксического анализа, не из-за порядка, в котором оцениваются выражения Java, и не из-за старшинства операторов. Это проблема сканирования. Последовательные "+" сканируются как ++, в результате получается a++++++b, что не является правильным выражением.
Итак, из моего эксперименты:
y+++ ++y; // valid
y++ + ++y; // valid
y++ +++y; // Invalid argument to operation ++/--
y+++++y; // Invalid argument to operation ++/--
Я собираюсь предположить, что причина, по которой последние два не работают, связана с токенами +++ y
. Синтаксический анализатор жадный и выполняет синтаксический анализ ++ (+ (y))
, что является недопустимым.
Но какое это имеет значение? Ничто из этого не является разборчивым и не должно использоваться, если вы не пытаетесь написать запутанный код Java.