Как объединить точки настройки Boost.Spirit с Nabialek? - PullRequest
0 голосов
/ 14 мая 2019

Перво-наперво: я использую стандарт языка C ++ по умолчанию для MS Visual Studio 2017 (v15.19.11), C ++ 14, наряду с Boost v1.65.1

У меня отформатирован входной файлкак это:

IterName        SomeName
IterDesc        Some Description
COLUMNS fname.XCT               posn.detect.R           posn.source.z
        expt_KF000000.raw       0.0                     27.639320225002102
        expt_KF000180.raw       216.34457142857138      30.584848796430673
        expt_KF000360.raw       72.68914285714277       33.530377367859245

Я пытаюсь разобрать и загрузить это в структуру, как показано ниже:

struct Stax { std::string stage, axis; };
struct Configuration {
    std::map<std::string, std::string> filenames; // "expt_KF000000.raw": "XCT", "other_file.raw": "OCT"
    std::map<double, Stax> positions;  // 0.0: ["Detect", "R"], 27.639: ["Source", "Z"]
};
struct Iteration {
    std::string name;
    std::string descript;
    std::vector<Configuration> configs;
};

Каждая строка после той, которая содержит " COLUMNS "должен сгенерировать новый Configuration экземпляр, который будет добавлен к Iteration.configs.

Как следует из комментариев в коде, некоторые столбцы могут отсутствовать (" fname.OCT"вэтот пример) ... но порядок столбцов может варьироваться (как и число), поэтому я попытался использовать локальное состояние правила для хранения переменного количества анализаторов, по одному для каждого столбца, как предложено здесь: https://stackoverflow.com/a/31382602/1206102

Элементы Configuration.positions состоят из информации, следующей за строкой заголовка " posn. ", а также любого содержимого, проанализированного в самой ячейке.Аналогично, элементы Configuration.filenames состоят из всего, что следует за " fname. " в заголовке плюс содержимое ячейки.Поэтому мне нужно каким-то образом сохранить информацию, которую я анализирую, из строки заголовка, чтобы использовать ее позже при разборе ячеек ... поэтому я храню это вместе с анализаторами ячеек в локальном состоянии правила var.

I 'мы перепробовали все, от локальных правил до членов данных в оболочке Phoenix, от прямого распространения атрибутов до адаптированных Fusion структур и «точек настройки», даже attr_cast с transform_attribute специализациями ... но ничего не удалось скомпилироватьеще.Мой список попыток следующий:

  1. https://wandbox.org/permlink/fU1WOazzxOVPbh9n
  2. https://wandbox.org/permlink/Itlq3HfydUByUSaH
  3. https://wandbox.org/permlink/96yDzVpCpI0K4ujs
  4. https://wandbox.org/permlink/u8iWv61jJSQv01bU

Моя последняя попытка все еще приводит к 11 ошибкам во время компиляции, первая из которых ('const_iterator': is not a member of 'Configuration') говорит: что-то (Qi / Fusion / Phoenix) ожидает, что Configuration будет итеративным ... вероятно, потому что проанализированныйТип, который заполняет это (вектор кортежей).

Это может быть суть моей проблемы: я пытаюсь вставить анализируемый итерируемый в не повторяемую * сложную структуру: некоторые из кортежей впроанализированный вектор войдет в один элемент данных структуры, в то время как другие войдут в другой элемент данных.(* Я говорю, что не повторяется, потому что нет смысла итерировать на Configuration, но если Qi / Fusion / Phoenix настаивает, я мог бы попытаться приспособиться. Фактически вы увидите [закомментированную] попытку определить const_iteratorвведите Configuration.)

Я хочу сделать это, используя Boost.Spirit, если это возможно, так что ... есть идеи, что я делаю не так?

1 Ответ

1 голос
/ 14 мая 2019
  1. &cell_stage не принимает адрес cell_stage, поскольку operator& перегружен. Используйте boost/std::addressof для получения адреса.
  2. qi::rule<Iterator, Skipper, double()>* не может быть преобразовано в qi::rule<Iterator, Skipper, boost::variant<std::string, double, bool>>*
  3. В qi::eps[_offset = -1, px::ref(_ncols) = px::size(_tstore)] вы просто назначаете -1 на _offset при инициализации, это должно быть px::ref(_offset) = -1
  4. qi::repeat(_ncols) будет повторяться не _ncols раз, а числом, которое _ncols содержало во время создания правила, которое равно нулю.
  5. В qi::eps[_offset = ++_offset % _ncols], как и в предыдущих, вы не создаете лямбду Феникса, а просто что-то вроде qi::eps[0]. Это должно быть qi::eps[px::ref(_offset) = ++px::ref(_offset) % px::cref(_ncols)].
  6. Я не понял, что должен делать qi::attr(_tstore[_offset]) >> *_pstore[_offset], но это явно не то, что вы на самом деле имели в виду, вероятно qi::lazy(px::cref(_tstore)[_offset]) >> qi::lazy(px::cref(_pstore)[_offset]).

В этот момент я должен остановиться и спросить: вы действительно хотите, чтобы это работало?

Не используйте Spirit в качестве Бирмингемской отвертки . Вы не обязаны делать все в одном анализаторе Духа. Например, вы можете анализировать строки в обычном цикле for, и его будет намного проще писать и поддерживать.

...