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

Какой трюк использует Java, чтобы избежать пробелов в >>?

В Java Generic Book, сравнивая разницу между С++ Templates и Java Generic, говорится:

В С++ возникает проблема, потому что → без пробела обозначает правый сдвиг. Java исправляет проблема с помощью трюка в грамматике.)

Что это за трюк?

4b9b3361

Ответ 1

Это фактически фиксируется в С++ в следующей версии. На самом деле это не очень трюк; если вы столкнулись с → во время разбора общего шаблона или шаблона, где вместо этого вы ожидали > , то у вас уже достаточно информации для генерации сообщения об ошибке. И, если у вас достаточно информации для генерации сообщения об ошибке, у вас также будет достаточно информации, чтобы интерпретировать → как два отдельных токена: > , а затем > .

Ответ 2

Парсер javac OpenJDK, JavacParser, массирует токены лексера GTGTGTEQ (>>>=), GTGTEQ, GTEQ, GTGTGT (>>>) и GTGT в токен с одним less '>' при анализе аргументов типа.

Вот фрагмент магии от JavacParser#typeArguments():

    switch (S.token()) {
    case GTGTGTEQ:
        S.token(GTGTEQ);
        break;
    case GTGTEQ:
        S.token(GTEQ);
        break;
    case GTEQ:
        S.token(EQ);
        break;
    case GTGTGT:
        S.token(GTGT);
        break;
    case GTGT:
        S.token(GT);
        break;
    default:
        accept(GT);
        break;
    }

Можно ясно видеть, что это действительно трюк, и это в грамматике:)

Ответ 3

Это простой синтаксический анализатор/лексер. Лексический анализатор обычно распознает пару >> как один токен. Однако, когда в середине разбора общего типа анализатор говорит лексеру не распознавать >>.

Исторически С++ не делал этого ради простоты реализации, но он может (и будет) исправляться с использованием того же трюка.

Ответ 4

Это не совсем трюк, они просто определили грамматику таким образом, что маркер правого сдвига синоним с двумя прямоугольными скобками (таким образом позволяя этому токену закрыть шаблон). Вы все же можете создавать неоднозначности, которые должны быть решены с помощью круглых скобок, но однозначные последовательности анализируются без вмешательства разработчиков. Это также делается в С++ 0x.

Ответ 5

Спецификация языка Java, третье издание показывает полную грамматику, оба оператора сдвига перечислены в InfixOp production, нет (очевидный) трюк. для определения того, какая операция > , → или → > намерена, будет решаться с помощью lookahead.