Как реализовать директивы 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, не возвращая токен парсеру qi?

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


person May Oakes    schedule 09.05.2012    source источник


Ответы (1)


Посмотрите, как работает Boost Wave< /strong> делает следующее:

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

А по характеристикам:

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

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

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

person sehe    schedule 10.05.2012