Как реализовать директивы include, используя boost::spirit::lex?

У меня есть простой анализатор конфигурационных файлов, созданный из spirit:: lex и spirit::qi. Когда лексер достигает шаблона include "path" Я хочу, чтобы текст файла был включен. Как вы, возможно, знаете, spirit::lexer::begin() запускает процесс сканирования:

// Read file contents into a std::string
...

// _first and _last are const char*
_first = _contents.c_str();
_last  = &_first[_input.size()];

// _token is a lexer::iterator_type for the current token
_token = _lexer.begin(_first, _last);

Моя идея состоит в том, чтобы иметь стек, который хранит состояние лексера в виде структуры:

struct LexerState
{
    const char* first;
    const char* last;
    std::string contents;
};

Лексер должен был бы распознать шаблон для include "path" и в семантическом действии извлеките путь к включаемому файлу. Затем текущее состояние лексера помещается в стек, содержимое файла загружается в строку, и новое состояние инициализируется, как описано выше, с использованием lexer::begin().

Когда лексер находит символ EOF, стек выталкивается и вызывается lexer:: begin () с использованием предыдущих переменных состояния лексера.

Можно ли повторно вызывать lexer:: begin () вот так? Как мне заставить lex:: lexer распознать include "path" шаблон и символ EOF без возврата токена в парсер ци?

Наконец, есть ли альтернативные или лучшие способы сделать это?

1 ответ

Посмотрите, как Boost Wave работает:

Wave Библиотека препроцессора C++ использует Spirit библиотека конструирования синтаксического анализатора для реализации лексера C++ с возможностями предварительной обработки в соответствии со стандартами ISO/ANSI. Он предоставляет интерфейс итератора, который возвращает текущий предварительно обработанный токен из входного потока. Этот предварительно обработанный токен генерируется на лету при итерации по последовательности итераторов препроцессора (в терминологии STL эти итераторы являются прямыми итераторами).

А что касается особенностей:

Препроцессор C++ предоставляет четыре отдельных средства, которые вы можете использовать по своему усмотрению:

  • Включение заголовочных файлов
  • Макро расширение
  • Условная компиляция
  • Линия управления

Их пример быстрого запуска показывает, как вы будете использовать интерфейс лексера Boost Wave.

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