Разбор EOF токена в CUP

У меня проблемы с тем, чтобы мой анализатор CUP анализировал токен EOF. Я прочитал в документации, что с помощью %cup Флаг в моем коде Jflex подразумевает, что есть что-то вроде этого:

%eofval{
  return new java_cup.runtime.Symbol(<CUPSYM>.EOF);
%eofval}
%eofclose

Это все хорошо, но когда я попробую следующее первое правило в моей грамматике (файл CUP):

program                 ::=   program declaration EOF
                          | /* Empty */
                          ;

Я получаю сообщение об ошибке, что EOF не объявлено CUP.

Error : java_cup.runtime.Symbol "EOF" has not been declared

Отлично, поэтому я добавляю следующее в мой файл CUP:

terminal EOF;

Нет, потому что тогда CUP говорит мне:

Fatal : JavaCUP Internal Error Detected: Duplicate terminal (EOF) created
enter code here

Тем не менее, без определения терминала EOF, и я смотрю в sym.java класс, который генерирует Кубок, я нахожу:

  public static final int EOF = 0;

Так что я довольно растерялся, как это исправить. Документация к обоим действительно расплывчата по этому вопросу.

Редактировать: Основная причина, по которой я хочу проанализировать токен EOF, заключается в том, что я хочу распечатать таблицу символов в конце и другие материалы для целей отладки.

3 ответа

Решение

Итак, вместо того, чтобы явно анализировать токен EOF для выполнения некоторого кода, я добавил следующую "обертку" в мою грамматику, которая позволяет мне делать именно то, что я хотел.

Вместо:

program                 ::=   program declaration
                          | /* Empty */
                          ;

Теперь у меня есть:

initial                 ::=   program   {: /* Code for EOF here */ :}
                          ;
program                 ::=   program declaration EOF
                          | /* Empty */
                          ;

Это позволяет мне выполнять код в конце каждого успешного анализа.

Убедитесь, что вы не забыли ";" в любом из ваших произведений грамматики, соответствующих вашему "file.cup".

program                 ::=   program declaration EOF
                          | /* Empty */
                          ;

Вам не нужно EOF в этом производстве. Это неявно.

Другие вопросы по тегам