Analizador Boost.Spirit X3 "sin tipo llamado tipo en (...)"


staba jugando con el ejemplo de la calculadora Boost.Spirit X3 cuando encontré un error que no podía entende
Minimicé el programa para reducir la complejidad y seguí arrojando el mismo error. Digamos que quiero analizar una entrada como una lista de declaraciones (cadenas) seguidas de un delimitador (';').

Esta es mi estructura:


namespace client { namespace ast
 {    
     struct program
    {
        std::list<std::string> stmts;
    };
 }}

BOOST_FUSION_ADAPT_STRUCT(client::ast::program,
            (std::list<std::string>, stmts)
)
La gramática es la siguiente:
namespace client
{ 
    namespace grammar
    {

   x3::rule<class program, ast::program> const program("program");

    auto const program_def =
            *((*char_) > ';')
            ;

   BOOST_SPIRIT_DEFINE(
       program
    );
    auto calculator = program;
}

using grammar::calculator;

}

Invocado


    int
    main()
    {
    std::cout <<"///////////////////////////////////////////\n\n";
    std::cout << "Expression parser...\n\n";
    std::cout << //////////////////////////////////////////////////\n\n";
    std::cout << "Type an expression...or [q or Q] to quit\n\n";

    typedef std::string::const_iterator iterator_type;
    typedef client::ast::program ast_program;

    std::string str;
    while (std::getline(std::cin, str))
    {
        if (str.empty() || str[0] == 'q' || str[0] == 'Q')
            break;

        auto& calc = client::calculator;    // Our grammar
        ast_program program;                // Our program (AST)

        iterator_type iter = str.begin();
        iterator_type end = str.end();
        boost::spirit::x3::ascii::space_type space;
        bool r = phrase_parse(iter, end, calc, space, program);

        if (r && iter == end)
        {
            std::cout << "-------------------------\n";
            std::cout << "Parsing succeeded\n";
            std::cout<< '\n';
            std::cout << "-------------------------\n";
        }
        else
        {
            std::cout << "-------------------------\n";
            std::cout << "Parsing failed\n";
            std::cout << "-------------------------\n";
        }
    }

    std::cout << "Bye... :-) \n\n";
    return 0;
}
Error que obtengo es
/opt/boost_1_66_0/boost/spirit/home/x3/support/traits/container_traits.hpp: In instantiation of ‘struct boost::spirit::x3::traits::container_value<client::ast::program, void>’:
.
.
.

/opt/boost_1_66_0/boost/spirit/home/x3/support/traits/container_traits.hpp:76:12: error: no type named ‘value_type’ in ‘struct client::ast::program’
         struct container_value
/opt/boost_1_66_0/boost/spirit/home/x3/operator/detail/sequence.hpp:497:72: error: no type named ‘type’ in ‘struct boost::spirit::x3::traits::container_value<client::ast::program, void>’
          , typename traits::is_substitute<attribute_type, value_type>::type());
                                                                        ^~~~~~
Cosas que probé:


SiguiendoGetting boost :: spirit :: qi para usar contenedores stl
A pesar de que usa Qi, intenté:

namespace boost{namespace spirit{ namespace traits{
template<>
struct container_value<client::ast::program> 
//also with struct container<client::ast::program, void>
{
      typedef std::list<std::string> type;
};
}}}

Ves que estoy un poco a oscuras, así que es de esperar que no sirva de nada.

parser2.cpp:41:8: error: ‘container_value’ is not a class template
 struct container_value<client::ast::program>
        ^~~~~~~~~~~~~~~

En la misma pregunta SO que el autor dice
"Sin embargo, hay una limitación conocida cuando intenta utilizar una estructura que tiene un solo elemento que también es una compilación de contenedor, a menos que agregue qi :: eps >> ... a su regla".

ntenté agregar un eps ficticio también sin éxito.

Por favor, ayúdame a descifrar qué significa ese error.

Respuestas a la pregunta(1)

Su respuesta a la pregunta