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

Синтаксис Java +

Почему следующий синтаксис правильный:

x = y+++y;

Где это означает y++ + y или y + ++y, что означает y * 2 + 1 (не уверен в этом, хотя: очень двусмысленный)

Но этот синтаксис неправильный:

x = y+++++y;

Что должно означать y++ + ++y, что означает y * 2 + 2

Есть ли причина неправильности этого синтаксиса? (Edit: спасибо за объяснение, почему это недопустимый синтаксис, но это не мое намерение с этим вопросом.)

(Изменить:) Я не использую это в реальном коде, просто в интересах парсеров/лексеров, но мне интересно, почему парсеру это не нравится, последний пример даже выглядит меньше неоднозначный, чем первый.)

( Edit:

    int i = 0;
    int j = (i = 3)+++i;

Недопустимо также, хотя для меня это кажется очень однозначным, (i = 3) - это значение, таким образом (значение +), а затем токен ++i.)

4b9b3361

Ответ 1

Синтаксический анализ является жадным, то есть он ищет самый длинный совпадающий маркер. Это значительно упрощает реализацию (предположительно). Кроме того, спецификация языка Java (3.2) говорит

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

Итак, для y+++++y; синтаксический анализатор/токенизатор сломает что-то вроде этого:

  • variable y
  • operator ++ (поскольку нет оператора +++, ++ является самым длинным, который соответствует синтаксису java)
  • operator ++ (поскольку нет оператора +++, ++ является самым длинным, который соответствует синтаксису java)
  • operator + (Это первое, что соответствует синтаксису)
  • variable y

Эффективно анализируется как (y++) (++) (+y) оператор ++ определен для переменной, однако первое выражение (y++) возвращает значение. Вы не можете применить следующий оператор (++) к значению.

Это означает, что x = y+++y; будет анализироваться как y++ + y, что не имеет ничего плохого.

Ответ 2

Короче говоря, из-за порядка, в котором вычисляются выражения Java, парсер считает, что вы пытаетесь использовать оператор ++ в выражении, что является незаконным.

Я думаю, что это:

x = y+++++y;

анализируется как нечто подобное:

x = ((y++)++) + y);

или что-то вроде этого:

x = (y + (++(++y)));

Я предполагаю, что это всего лишь академический вопрос и что вы на самом деле не пытаетесь использовать такой код в реальном мире. Неравномерность операторов ведет только к боли и страданиям.

Спецификация языка Java перечисляет все правила для оценки выражений здесь.

Ответ 3

Я предполагаю, что это потому, что y+++++y; анализируется как y++++ + y;, а второй ++ принимает y++ в качестве аргумента, что является недопустимым. Помните, что возвращаемое значение y++ является значением, а не переменной. Вы не можете сказать 5++ по той же причине.

Ответ 4

Ну, во-первых, потому что это катастрофа.:)

Ваш первый пример анализируется так, как вы ожидаете: y+++y - (y++) + y.

Но ваш второй пример не делает - я провел несколько экспериментов, а y+++++y - ((y++)++) + y. Что убивает вас, это первая часть, потому что y++ возвращает число, к которому вы не можете применить оператор ++.

Тем не менее, (y++) + (++y) действительно.

Ответ 5

Итак, из моих экспериментов:

y+++ ++y;  // valid
y++ + ++y; // valid
y++ +++y;  // Invalid argument to operation ++/--
y+++++y;   // Invalid argument to operation ++/--

Я собираюсь предположить, что причина, по которой последние две не работают, связана с токенами +++y. Парсер жадный и разбор ++(+(y)), что является незаконным.

Но какое это имеет значение? Ни один из них не является разборчивым и не должен использоваться, если вы не пытаетесь написать обфускацию кода Java.

Ответ 6

Как вы можете видеть здесь PreIncrementExpression определяется как ++ UnaryExpression , но UnaryExpression может быть + UnaryExpression, поэтому он пытается для его анализа в неправильном порядке:

y++ ++ +y

пытается применить оператор ++ к +y, что является незаконным.

Просто сторона node: y+++y эффективно интерпретируется как y + ++y.

Еще одно примечание: если вы используете y++ + ++y, он работает.

Ответ 7

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