Как я могу использовать лексер JFlex с анализатором JavaCC?

Я пытаюсь научиться использовать JavaCC для написания парсера.

Я уже сгенерировал лексер, используя JFlex, и он возвращает список токенов. Каждый токен - это его собственный класс.

Я пишу правила производства, но, например, я не могу написать ";" потому что он не получит точку с запятой, а вместо этого экземпляр TokenSemicolon?

Что я могу сделать?

Кроме того, я запутался в TokenMangager и т. Д. У меня уже есть лексер и собственный список совместимых классов токенов. Что это?

Пожалуйста, помогите, потому что я очень смущен.

1 ответ

Вы задаете два связанных вопроса:

"Что это?" Под чем, я полагаю, вы имеете в виду: "Что такое менеджер токенов?"

Менеджер токенов является источником объектов токенов. Каждому анализатору JavaCC необходим источник токенов. Токены, кстати, представлены объектами класса Token, Есть два способа сделать менеджер токенов.

  1. Позвольте JavaCC сгенерировать один для вас. JavaCC генерирует лексический анализатор на основе набора правил, которые вы вводите в .jj файл. Таким образом, это очень похоже на JFlex. Это по умолчанию.
  2. Напиши свое. Для этого установите опцию USER_TOKEN_MANAGER=true, Затем JavaCC сгенерирует интерфейс Java с именем TokenManager, Все, что вам нужно сделать, это реализовать этот интерфейс с вашим собственным классом. Конечно, вы должны затем создать синтаксический анализатор, используя объект этого класса.

"А что я могу сделать?"

Есть несколько возможностей.

  1. Перепишите ваш код JFlex на JavaCC. Затем сгенерированный JavaCC менеджер токенов будет делать то же самое, что и ваш лексер JFlex, но он реализует правильный интерфейс и генерирует токены соответствующего типа (т.е. Token.)
  2. Напишите класс адаптера. Используйте JavaCC USER_TOKEN_MANAGER=true опцию и написать класс адаптера, который оборачивает ваш JFlex и реализует TokenManager интерфейс.
  3. Убедите JFlex сгенерировать лексер, который можно использовать с JavaCC. Я не уверен, возможно ли это вообще, но если это так, это может быть лучшим вариантом. В этом случае вы бы использовали USER_TOKEN_MANAGER=true, Тогда сделайте класс:class FooLexer extends FooJLexLexer implements TokenManager { ...put constructors here... }

Для варианта 3 вы должны убедиться, что сгенерированный лексер действительно реализует все методы, требуемые TokenManager, Если вам действительно нужны все ваши собственные классы токенов, вы можете расширить их сгенерированные Token учебный класс.

Если вы выберете вариант 2, ваш код для создания парсера будет выглядеть примерно так

TokenManager tm = new AdaptJFlexLexerToJavaCC( jflexLexer ) ;
FooParser p = new FooParser( tm ) ;

Вариант 3 заманчиво попробовать. Это может быть проще всего, если получится.

Если вариант 3 не сработает и если нет веских причин оставить лексер JFlex, я бы выбрал вариант 1. Перевод с JFlex на JavaCC, скорее всего, будет в значительной степени механическим и, следовательно, быстрым и простым. Единственная вещь в JFlex, для которой у JavaCC нет хорошего решения, является A / B построить.

Какой бы вариант вы ни выбрали, имейте в виду, что JavaCC ожидает, что каждый Token иметь .kind поле. Это целое число, но вы найдете символические имена для целых чисел в сгенерированном интерфейсе FooConstants,

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