Boost.Spirit: отчет об ошибках Lex + Qi

Я пишу синтаксический анализатор для довольно сложных файлов конфигурации, которые используют отступы и т.д. Я решил использовать Лекс, чтобы сломать входные данные в токены, поскольку это, по-видимому, облегчает жизнь. Проблема заключается в том, что я не могу найти примеры использования QI-инструментов отчетности ошибок (on_error) с синтаксическими анализаторами, которые работают с потоком токенов вместо символов.

Обработчик ошибок, который будет использоваться в on_error, позволяет некоторым образом указать, где именно ошибка во входном потоке. Все примеры просто конструируют std::string из пары итераторов и печатают их. Но если использовать Lex, эти итераторы являются итераторами последовательности токенов, а не символов. В моей программе это привело к зависанию в конструкторе std::string, прежде чем я заметил недопустимый тип итератора.

Как я понимаю, токен может содержать пару итераторов во входном потоке в качестве значения. Это тип атрибута по умолчанию (если тип похож на lex::lexertl::token<>). Но если я хочу, чтобы мой токен содержал что-то более полезное для синтаксического анализа (int, std::string и т.д.), Эти итераторы теряются.

Как я могу создавать дружественные человечеству сообщения об ошибках, указывающие положение во входном потоке при использовании Lex с Qi? Есть ли примеры такого использования?

Спасибо.

Ответ 1

Извините за поздний ответ, но мне потребовалось некоторое время, чтобы подготовить достойный пример того, чего вы пытаетесь достичь. Теперь я добавил новый пример lexer для Spirit: conjure_lexer. Это модифицированная версия примера conjure (Qi), реализующая небольшой язык программирования. Главное отличие состоит в том, что он использует лексер вместо чистой грамматики Qi.

Новый пример conjure_lexer демонстрирует несколько вещей: а) он использует новый класс position_token, который расширяет существующий тип token. Он всегда хранит пару итераторов, указывающих на соответствующую согласованную последовательность ввода (в дополнение к обычной информации, такой как идентификатор токена, значение токена и т.д.). б) он использует эту позиционную информацию для сообщения об ошибках c) и вдоль линий, он демонстрирует, как использование лексера может упростить грамматику.

Новый пример представлен в SVN (trunk) и будет доступен в Boost V1.47 (скоро будет выпущен). В этом каталоге: $BOOST_ROOT/libs/spirit/example/qi/compiler-tutorial/conjure_lexer.