Синтаксис Java + - PullRequest
       15

Синтаксис Java +

16 голосов
/ 12 апреля 2010

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

x = y+++y;

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

Но этот синтаксис неверен :

x = y+++++y;

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

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

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

( Edit:

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

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

Ответы [ 7 ]

20 голосов
/ 12 апреля 2010

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

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

Итак, для y+++++y; парсер / токенизатор сломает его примерно так:

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

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

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

10 голосов
/ 12 апреля 2010

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

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

x = y+++++y;

анализируется примерно так:

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

или как-то так:

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

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

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

4 голосов
/ 12 апреля 2010

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

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

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

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

4 голосов
/ 12 апреля 2010

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

3 голосов
/ 12 апреля 2010

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

y++ ++ +y

пытается применить оператор ++ к +y, что недопустимо.

Просто боковой узел: y+++y фактически интерпретируется как y + ++y.

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

3 голосов
/ 12 апреля 2010

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

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

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

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

0 голосов
/ 13 апреля 2010

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

...