Начал изучать сабж. Пару раз бросал и садился писать свой парсер, но, как ни крути, spirit получается удобнее. Только вот по нему нет нормальной документации и примеров, поэтому не остаётся ничего кроме как спросить здесь.
Первое, собственно, посоветуйте нормальных примеров вместо фуфла с офсайта, которое покрывает только самые тривиальные случаи использования.
Далее конкретные вопросы.
Есть парсер списка команд вида
FOO 1, 2, 3
BAR 1, 2, "ARG3"
BAZ 2, 0.5, "ZZZ"
парсит их в структуры вида
struct cmdfoo {
int arg1;
int arg2;
int arg3;
};
структуры нужно запаковать в набор векторов в другой структуре
struct cmdlist {
std::vector<cmdfoo> foos;
std::vector<cmdbar> bars;
std::vector<cmdbaz> bazs;
}
В целом, на BOOST_FUSION_ADAPT_STRUCT это хорошо ложится, но есть исключения.
Во-первых, есть несколько команд которые нужно парсить в одну структуру. При этом в структуре есть флаг который обозначает конкретную команду плюс немного различаются поля. Примерно так:
BARa 1, 2, 3
BARb 1, 2, 4
struct cmdbar {
enum { A, B } type;
int arg1;
int arg2;
int arg3;
int arg4;
};
Что с этим делать? Во-первых, не хочется дублировать правило грамматики для парсинга очень похожих штук. Во-вторых, как использовать BOOST_FUSION_ADAPT_STRUCT чтобы было 2 adapt'а для одной сруктуры? Видел BOOST_FUSION_ADAPT_STRUCT_NAMED, но как сказать правилу которое
qi::rule<Iterator, cmdbar()>, foocmda_rule;
использовать конкретный adapt?
Во-вторых, в грамматике, очевидно, будет общее правило для любой команды:
cmd_rule = cmdfoo_rule | cmdbar_rule | cmdbaz_rule;
Я видел что в таких случаях возвращают boost::variant, но не хочется паковать правила в вариант, а выше по грамматике распаковывать чтобы распихать по векторам. Можно как-то достучаться из правил-листьев до верха, т.е. правила которое генерирует cmdlist?
Это пока основное что мне не понятно.