Различают дженерики вправо (>>) и Java - PullRequest
3 голосов
/ 26 января 2020

Я пишу лексер для java в flex. java spe c говорит:

"На каждом шаге используется максимально длинный перевод, даже если результат в конечном итоге не дает правильную программу, в отличие от другого лексического перевода. исключение: , если лексическая трансляция происходит в контексте типа (§4.11) и входной поток имеет два или более последовательных символа>, за которыми следует не-> символ, тогда каждый символ> должен быть преобразован в токен для оператор числового сравнения>. "

Так как же отличить guish между оператором правого сдвига и чем-то вроде в <List<List>>?

1 Ответ

3 голосов
/ 26 января 2020

В исходном предложении Java обобщения (JSR-14) требовалось изменить грамматику Java для параметризованных типов, чтобы она принимала >> и >>> в контекстах, где было возможно несколько близких угловых скобок. (Я не смог найти полезную официальную ссылку для JSR-14, но спецификация GJ Гилада Брачи все еще доступна на его веб-сайте; модификации грамматики показаны в разделе 2.3.)

Эти модификации насколько я знаю, они никогда официально не были включены ни в один Java стандарт; в конце концов, JLS8 включил изменение в описание лексического анализа, которое вы цитируете в своем вопросе. (См. JDK-8021600 , который также воспроизводит запутанную грамматику, которая была первоначально предложена.)

Модификации грамматики, предложенные Bracha et al., Будут работать, но вы можете обнаружить, что они делают включение других грамматические изменения сложнее. (На самом деле я не рассматривал это подробно, поэтому это не может быть проблемой для текущей Java спецификации языка. Но это все еще может быть проблемой для будущих выпусков.)

Хотя в контексте лексический анализ допускает более простую грамматику, фактически используемую в JLS, это, безусловно, создает трудности для лексического анализа. Один из возможных подходов - полностью отказаться от лексического анализа, используя синтаксический анализатор без сканера ; это, безусловно, сработает, но вы не сможете выполнить sh в рамках модели Bison / Flex. Кроме того, вы можете обнаружить, что некоторые модификации, необходимые для поддержки синтаксического анализа без сканирования, также требуют нетривиальных изменений в опубликованной грамматике.

Другая возможность состоит в использовании лексической обратной связи от синтаксического анализатора путем включения действий среднего правила ( MRA), которые включают и выключают флаг «контекста типа» при вводе и выходе контекста типа. (В §4.11 приведен полный список контекстов типов, который можно использовать для поиска подходящих мест в грамматике.) Если вы попробуете это, учтите, что выполнение MRA не полностью синхронизировано с лексическим анализом, поскольку анализатор обычно требуется жетон предварительного просмотра, чтобы решить, следует ли уменьшить MRA. Вам часто нужно поместить MRA на один символ в грамматике раньше, чем вы думаете, чтобы он действительно вступил в силу к тому времени, когда это необходимо.

Другая возможность может заключаться в том, чтобы никогда не распознавать >> и >>> в качестве жетонов. Вместо этого лексер может вернуть два разных токена >, один из которых используется, когда ближайший следующий символ является >:

>/>     { return CONJUNCTIVE_GT; }
>       { return INDEPENDENT_GT; }
  /* These two don't need to be changed. */
>>=     { return SHIFT_ASSIGN; }
>>>=    { return LONG_SHIFT_ASSIGN; }

Затем вы можете изменить свою грамматику для распознавания >> и >>> операторы, допуская любую форму > в качестве закрывающей угловой скобки:

shift_op     : CONJUNCTIVE_GT INDEPENDENT_GT
long_shift_op: CONJUNCTIVE_GT CONJUNCTIVE_GT INDEPENDENT_GT
close_angle  : CONJUNCTIVE_GT | INDEPENDENT_GT
gt_op        : INDENPENDENT_GT /* This unit production is not really necessary */

Это должно работать (хотя я не пробовал), но это не очень хорошо работает с Bison / Ya. cc механизм приоритета оператора, потому что вы не можете объявить приоритет для нетерминала. Поэтому вам необходимо использовать грамматику выражений с явными правилами приоритета операторов, а не двусмысленную грамматику, дополненную объявлениями предшествования.

...