Какой прием использует Java, чтобы избежать пробелов в >>? - PullRequest
16 голосов
/ 11 мая 2010

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

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

Что это за уловка?

Ответы [ 5 ]

9 голосов
/ 11 мая 2010

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

Вот фрагмент магии из 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;
    }

Хорошо видно, что это действительно уловка, и она в грамматике:)

5 голосов
/ 11 мая 2010

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

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

5 голосов
/ 11 мая 2010

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

2 голосов
/ 11 мая 2010

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

1 голос
/ 11 мая 2010

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

...