2015-10-21 2 views
4

Я пытаюсь узнать, как использовать JavaCC для написания парсера.Как я могу использовать лексер JFlex с парсером JavaCC?

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

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

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

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

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

ответ

2

Вы задаете два взаимосвязанных вопроса: "Что это?"

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

Менеджер токенов является источником токенов. Каждому парсеру 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.

Смежные вопросы