Erro de construção com o Boost Spirit Grammar (Boost 1.43 e G ++ 4.4.1) Parte II
-
27-09-2019 - |
Pergunta
Estou tendo problemas para obter uma pequena gramática de espírito/qi para compilar. Estou usando o Boost 1.43 e G ++ 4.4.1.
O cabeçalho gramatical de entrada: o erro de construção parece estar apontando para a definição da regra de 'instrução', talvez seja a '[sp :: _ val = sp :: _ 1]' que de alguma forma o abre, mas isso é mais ou menos baseado em Sobre o que os tutoriais de documentação do Spirit estão fazendo com o analisador de nó XML
inputGrammar.h
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
namespace sp = boost::spirit;
namespace qi = boost::spirit::qi;
using namespace boost::spirit::ascii;
//using namespace boost::spirit::arg_names;
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
using phoenix::at_c;
using phoenix::push_back;
template< typename Iterator , typename ExpressionAST >
struct InputGrammar : qi::grammar<Iterator, ExpressionAST(), space_type> {
InputGrammar() : InputGrammar::base_type( block ) {
tag = sp::lexeme[+(alpha) [sp::_val += sp::_1]];//[+(char_ - '<') [_val += _1]];
block = sp::lit("block") [ at_c<0>(sp::_val) = sp::_1]
>> "(" >> *instruction[ push_back( at_c<1>(sp::_val) , sp::_1 ) ]
>> ")";
command = tag [ at_c<0>(sp::_val) = sp::_1]
>> "(" >> *instruction [ push_back( at_c<1>(sp::_val) , sp::_1 )]
>> ")";
instruction = ( command | tag ) [sp::_val = sp::_1]; //build error seems to be happening here
}
qi::rule< Iterator , std::string() , space_type > tag;
qi::rule< Iterator , ExpressionAST() , space_type > block;
qi::rule< Iterator , ExpressionAST() , space_type > function_def;
qi::rule< Iterator , ExpressionAST() , space_type > command;
qi::rule< Iterator , ExpressionAST() , space_type > instruction;
};
O programa de construção de teste:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//my grammar
#include <InputGrammar.h>
struct MockExpressionNode {
std::string name;
std::vector< MockExpressionNode > operands;
typedef std::vector< MockExpressionNode >::iterator iterator;
typedef std::vector< MockExpressionNode >::const_iterator const_iterator;
iterator begin() { return operands.begin(); }
const_iterator begin() const { return operands.begin(); }
iterator end() { return operands.end(); }
const_iterator end() const { return operands.end(); }
bool is_leaf() const {
return ( operands.begin() == operands.end() );
}
};
BOOST_FUSION_ADAPT_STRUCT(
MockExpressionNode,
(std::string, name)
(std::vector<MockExpressionNode>, operands)
)
int const tabsize = 4;
void tab(int indent)
{
for (int i = 0; i < indent; ++i)
std::cout << ' ';
}
template< typename ExpressionNode >
struct ExpressionNodePrinter
{
ExpressionNodePrinter(int indent = 0)
: indent(indent)
{
}
void operator()(ExpressionNode const& node) const {
cout << " tag: " << node.name << endl;
for (int i=0 ; i < node.operands.size() ; i++ ) {
tab( indent ); cout << " arg "<<i<<": "; ExpressionNodePrinter(indent + 2)( node.operands[i]); cout << endl;
}
}
int indent;
};
int test() {
MockExpressionNode root;
InputGrammar< string::const_iterator , MockExpressionNode > g;
std::string litA = "litA";
std::string litB = "litB";
std::string litC = "litC";
std::string litD = "litD";
std::string litE = "litE";
std::string litF = "litF";
std::string source = litA+"( "+litB+" ,"+litC+" , "+ litD+" ( "+litE+", "+litF+" ) "+ " )";
string::const_iterator iter = source.begin();
string::const_iterator end = source.end();
bool r = qi::phrase_parse( iter , end , g , space , root );
ExpressionNodePrinter< MockExpressionNode > np;
np( root );
};
int main() {
test();
}
Finalmente, o erro de construção é o seguinte:
(O rastreamento de erro completo é 20 vezes maior que o tamanho permitido para uma pergunta de Stackoverflow, então eu publiquei a versão completa em http://codepad.org/q74ivcuc)
/usr/bin/make -f nbproject/Makefile-linux_amd64_devel.mk SUBPROJECTS= .build-conf
make[1]: se ingresa al directorio `/home/mineq/NetBeansProjects/InputParserTests'
/usr/bin/make -f nbproject/Makefile-linux_amd64_devel.mk dist/linux_amd64_devel/GNU-Linux-x86/vpuinputparsertests
make[2]: se ingresa al directorio `/home/mineq/NetBeansProjects/InputParserTests'
mkdir -p build/linux_amd64_devel/GNU-Linux-x86
rm -f build/linux_amd64_devel/GNU-Linux-x86/tests_main.o.d
g++ `llvm-config --cxxflags` `pkg-config --cflags unittest-cpp` `pkg-config --cflags boost-1.43` `pkg-config --cflags boost-coroutines` -c -g -I../InputParser -MMD -MP -MF build/linux_amd64_devel/GNU-Linux-x86/tests_main.o.d -o build/linux_amd64_devel/GNU-Linux-x86/tests_main.o tests_main.cpp
from /home/mineq/third_party/boost_1_43_0/boost/spirit/include/phoenix_operator.hpp:11,
from ../InputParser/InputGrammar.h:14,
from tests_main.cpp:14:
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator/self.hpp: In instantiation of ‘const int boost::phoenix::result_of_assign<MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>::size’:
In file included from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator.hpp:16,
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator/self.hpp:27: instantiated from ‘const int boost::phoenix::result_of_assign<MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>::index’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator/self.hpp:27: instantiated from ‘boost::phoenix::result_of_assign<MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>’
/home/mineq/third_party/boost_1_43_0/boost/mpl/eval_if.hpp:38: instantiated from ‘boost::mpl::eval_if<boost::mpl::or_<boost::phoenix::is_actor<MockExpressionNode&>, boost::phoenix::is_actor<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, mpl_::bool_<false>, mpl_::bool_<false>, mpl_::bool_<false> >, boost::phoenix::re_curry<boost::phoenix::assign_eval, MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, boost::phoenix::result_of_assign<MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator/self.hpp:69: instantiated from ‘boost::phoenix::assign_eval::result<boost::phoenix::basic_environment<boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, bool, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, boost::spirit::attribute<0>, boost::spirit::argument<0> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/core/detail/composite_eval.hpp:89: instantiated from ‘boost::phoenix::detail::composite_eval<2>::result<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::phoenix::basic_environment<boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, bool, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/core/composite.hpp:61: instantiated from ‘boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >::result<boost::phoenix::basic_environment<boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, bool, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/core/actor.hpp:56: instantiated from ‘boost::phoenix::eval_result<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::phoenix::basic_environment<boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, bool, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/core/actor.hpp:65: instantiated from ‘boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >::result<boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >(boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>&, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >&, bool&)>’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/support/action_dispatch.hpp:44: instantiated from ‘bool boost::spirit::traits::action_dispatch<Component>::operator()(const boost::phoenix::actor<Eval>&, Attribute&, Context&) [with Eval = boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, Attribute = boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>, Context = boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, Component = boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::string(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::nil> > >]’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/action/action.hpp:62: instantiated from ‘bool boost::spirit::qi::action<Subject, Action>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Context = boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, Attribute = const boost::fusion::unused_type, Subject = boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::string(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::nil> > >, Action = boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >]’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:33: instantiated from ‘bool boost::spirit::qi::detail::parser_binder<Parser, Auto>::call(Iterator&, const Iterator&, Context&, const Skipper&, mpl_::true_) const [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, Context = boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, Parser = boost::spirit::qi::action<boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::string(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::nil> > >, boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > > >, Auto = mpl_::bool_<false>]’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:53: instantiated from ‘bool boost::spirit::qi::detail::parser_binder<Parser, Auto>::operator()(Iterator&, const Iterator&, Context&, const Skipper&) const [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, Context = boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, Parser = boost::spirit::qi::action<boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::string(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::nil> > >,
...
... mais erros, mas eu tive que truncar para ajustar o limite de 30k
make[2]: *** [build/linux_amd64_devel/GNU-Linux-x86/tests_main.o] Error 1
make[2]: se sale del directorio `/home/mineq/NetBeansProjects/InputParserTests'
make[1]: *** [.build-conf] Error 2
make[1]: se sale del directorio `/home/mineq/NetBeansProjects/InputParserTests'
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 2m 13s)
Solução
Sua mensagem de erro diz que você deseja atribuir um variant<MockExpressionNode, basic_string>
para um MockExpressionNode
As linhas relevantes são 33 e 34;
[...] error: no match for ‘operator=’ [...] boost::variant<MockExpressionNode, std::basic_string [...]
[...] candidates are: MockExpressionNode& MockExpressionNode::operator=(const MockExpressionNode&) [...]
Para entender por que isso acontece, temos que olhar para as definições. Da definição de um Qi regra, a assinatura do valor retornada é definida por um parâmetro de modelo. Por isso
qi::rule< Iterator , ExpressionAST() , space_type > command;
significa que o tipo retornado de um command
será um ExpressionAST
(ou seja, a MockExpressionNode
no seu caso). De forma similar
qi::rule< Iterator , std::string() , space_type > tag;
significa que tag
será do tipo string
. Combinando isso com instruction = (command | tag)
significa que um instruction
é um string
ou a MockExpressionNode
. Isso é armazenado internamente como um variant<MockExpressionNode, string>
. Finalmente,
qi::rule< Iterator , ExpressionAST() , space_type > instruction;
implica que o tipo retornado de instruction
é novamente um ExpressionAST
(ou seja, a MockExpressionNode
). Isso requer a atribuição de falha do variant
mantido internamente em um MockExpressionNode
.
Para resumir, você precisa fornecer tipos em seu qi::rule
s que "combina" um pouco os tipos implícitos na sua gramática no sentido de que a tarefa é possível. Apesar de todo o impulso. Para a questão em questão, você precisa fornecer um acessório operator=
, ou você deve atribuir os resultados das diferentes regras a diferentes tipos que suportam conversão implícita. Btw, você tem problemas de tipo semelhante para block
e command
no momento. Dê uma olhada cuidadosa no Exemplo mini_xml Na documentação: como definir tipos para uma estrutura recursiva e como as regras diferentes atribuem a diferentes tipos, dependendo da gramática definida (especialmente regras xml
e node
).