В целях обучения я пытаюсь написать простой парсер, который принимает строковый литерал и помещает его в собственную структуру, используя библиотеку x3 из boost.Однако следующий минимальный пример, который адаптирован из примера здесь , не компилируется.
#include <iostream>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <string>
namespace x3 = boost::spirit::x3;
namespace ast {
struct Symbol {
std::string val;
};
}
BOOST_FUSION_ADAPT_STRUCT(
ast::Symbol,
val
)
namespace parser {
x3::rule<class Symbol, ast::Symbol> const
symbol = "symbol";
auto const symbol_def = x3::string("asd");// | x3::string("qwe");
BOOST_SPIRIT_DEFINE(
symbol
);
}
int main(int argc, char** argv) {
std::string input = "asd";
if (argc > 1) {
input = argv[1];
}
std::string::const_iterator begin = input.begin();
std::string::const_iterator end = input.end();
ast::Symbol sym;
bool success = x3::phrase_parse(begin, end, parser::symbol,
x3::ascii::space, sym);
std::cout << success << std::endl;
std::cout << sym.val << std::endl;
return 0;
}
Это дает очень длинную ошибку компилятора шаблона, которая сводится к
cannot convert ‘dest’ (type ‘ast::Symbol’) to type
‘boost::spirit::x3::traits::variant_attribute’
Это не имеет смысла для меня, потому что синтаксический анализатор x3 :: string должен иметь строковый атрибут, а структура ast :: Symbol имеет строковое поле, которое x3 должно заполнять автоматически, потому что я адаптировал структуру с помощьюFusion macro.Что еще более запутанно, так это то, что если я изменю определение парсера на чтение
auto const symbol_def = x3::string("asd") | x3::string("qwe");
, оно компилируется и работает, хотя теперь у парсера должен быть атрибут типа варианта.Может быть, кто-то может прояснить, почему это происходит, потому что мне кажется, что мне чего-то не хватает в том, как работает библиотека.