errore di generazione con spirito spinta grammatica (boost 1.43 e g ++ 4.4.1) parte III

StackOverflow https://stackoverflow.com/questions/3115420

  •  29-09-2019
  •  | 
  •  

Domanda

Ok

sto cercando di costruire una grammatica e attualmente si presenta così:

#ifndef _INPUTGRAMMAR_H
#define _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/spirit/home/support/context.hpp>
#include <boost/spirit/home/phoenix.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;

namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;

using phoenix::at_c;
using phoenix::push_back;
using phoenix::bind;



template< typename Iterator , typename ExpressionAST >
struct InputGrammar : qi::grammar<Iterator, ExpressionAST(), space_type> {

    InputGrammar() : InputGrammar::base_type( command ) {

        identifier %= ( qi::char_("a-zA-Z_")  >> *qi::char_("a-zA-Z_0-9") ); 

        tag = identifier
          [
              at_c<0>(qi::_val) = qi::_1,
              phoenix::bind( &ExpressionAST::setAsTag , qi::_val )
          ];

        command =
        identifier
            [
               at_c<0>(qi::_val) = qi::_1,
               phoenix::bind( &ExpressionAST::setAsCommand , qi::_val )
            ]
        >>  "("
        >> -(parameter % ",")
            [
               //phoenix::push_back(at_c<1>(qi::_val) , qi::_1 )
                phoenix::bind( &std::vector< ExpressionAST , std::allocator< ExpressionAST > >::push_back, at_c<1>(qi::_val) , qi::_1 )
            ]
        >>  ")";


        parameter = ( command | tag ) [qi::_val = qi::_1];
    }
    qi::rule< Iterator , ExpressionAST() , space_type > tag;
    qi::rule< Iterator , std::string() , space_type > identifier;
    qi::rule< Iterator , ExpressionAST() , space_type > command;
    qi::rule< Iterator , ExpressionAST() , space_type > parameter;
};

#endif  /* _INPUTGRAMMAR_H */

un elemento di cattura del errore di generazione è il seguente, in fondo si dice che sta cercando di inizializzare un MockExpressionNode & (probabilmente l'argomento push_back) con un std :: vector , come in qualche modo fenice :: bind in cui la commutazione l'ordine di l'oggetto e il parametro argomenti.

../InputParser/InputGrammar.h:63:   instantiated from ‘InputGrammar<Iterator, ExpressionAST>::InputGrammar() [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, ExpressionAST = MockExpressionNode]’
tests_main.cpp:202:   instantiated from here
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/bind/detail/member_function_ptr.hpp:103: error: invalid initialization of reference of type ‘const MockExpressionNode&’ from expression of type ‘std::vector<MockExpressionNode, std::allocator<MockExpressionNode> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/bind/detail/member_function_ptr.hpp:103: error: return-statement with a value, in function returning 'void'

ho provato la fenice :: legano a std :: vector :: push_back solo dopo aver provato questa forma originale:

    >> -(parameter % ",")
        [
           phoenix::push_back(at_c<1>(qi::_val) , qi::_1 )
           // phoenix::bind( &std::vector< ExpressionAST , std::allocator< ExpressionAST > >::push_back, at_c<1>(qi::_val) , qi::_1 )
        ]
    >>  ")";

Ho ottenuto questo errore invece (solo parte finale) su alcuna funzione di corrispondenza per std :: vector :: push_back:

boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, false>, boost::fusion::cons<boost::spirit::qi::optional<boost::spirit::qi::action<boost::spirit::qi::list<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::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, false> >, boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::detail::function_eval<2>, boost::fusion::vector<boost::phoenix::value<boost::phoenix::stl::push_back>, boost::phoenix::composite<boost::phoenix::at_eval<1>, boost::fusion::vector<boost::spirit::attribute<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::void_> >, 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::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, false>, boost::fusion::nil> > > > >, mpl_::bool_<false> >, R = bool, T0 = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, T1 = const __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, T2 = boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >&, T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&]’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/nonterminal/rule.hpp:201:   instantiated from ‘boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>& boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const Expr&) [with Expr = boost::proto::exprns_::expr<boost::proto::tag::shift_right, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tag::shift_right, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tag::shift_right, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tag::subscript, boost::proto::argsns_::list2<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::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::sequence_eval, boost::fusion::vector<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::phoenix::composite<boost::phoenix::at_eval<0>, boost::fusion::vector<boost::spirit::attribute<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::void_> >, 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::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<boost::phoenix::detail::member_function_ptr<0, void, void (MockExpressionNode::*)()> >, boost::spirit::attribute<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::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >&>, 0l> >, 2l>&, boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const char (&)[2]>, 0l> >, 2l>&, const boost::proto::exprns_::expr<boost::proto::tag::negate, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tag::subscript, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tag::modulus, boost::proto::argsns_::list2<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::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const char (&)[2]>, 0l> >, 2l>&, boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::detail::function_eval<2>, boost::fusion::vector<boost::phoenix::value<boost::phoenix::stl::push_back>, boost::phoenix::composite<boost::phoenix::at_eval<1>, boost::fusion::vector<boost::spirit::attribute<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::void_> >, 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_> > >&>, 0l> >, 2l>&>, 1l>&>, 2l>&, boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const char (&)[2]>, 0l> >, 2l>, Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, T1 = MockExpressionNode(), T2 = 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>, T3 = boost::fusion::unused_type, T4 = boost::fusion::unused_type]’
../InputParser/InputGrammar.h:63:   instantiated from ‘InputGrammar<Iterator, ExpressionAST>::InputGrammar() [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, ExpressionAST = MockExpressionNode]’
tests_main.cpp:202:   instantiated from here
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/stl/container/container.hpp:492: error: no matching function for call to ‘std::vector<MockExpressionNode, std::allocator<MockExpressionNode> >::push_back(const std::vector<MockExpressionNode, std::allocator<MockExpressionNode> >&)’
/usr/include/c++/4.4/bits/stl_vector.h:733: note: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = MockExpressionNode, _Alloc = std::allocator<MockExpressionNode>]
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/stl/container/container.hpp:492: error: return-statement with a value, in function returning 'void'
È stato utile?

Soluzione

La seconda forma utilizzando fenice :: push_back è quella suggerita. Il problema è dove si definisce l'azione semantica. Il costrutto -(whatever % ",") ha un tipo di valore di attributo di vector<whatever>, che poi passato come parametro di push_back invitato il vector<MockExpressionNode>. In altre parole, lo spirito non sta passando gli argomenti, il codice è essenzialmente vector<>.push_back(vector<>). Si può vedere questo nella terza riga dell'ultimo blocco di errore che avete inviato:

/home/.../container.hpp:492: error: no matching function for call to
 ‘std::vector<...>::push_back(const std::vector<...>&)’

Debug errori di compilazione con questa roba a volte richiede leggendo tra le righe, letteralmente;)

Al contrario, collegare l'azione push_back al parser parameter direttamente, dal momento che questo parser ha il tipo di attributo MockExpressionNode. Prova:

command =
    identifier
        [
           at_c<0>(qi::_val) = qi::_1,
           phoenix::bind( &ExpressionAST::setAsCommand , qi::_val )
        ]
    >>  "("
    >> -(
                parameter[ phoenix::push_back(at_c<1>(qi::_val) , qi::_1 ) ] 
            %   ","
       )
    >>  ")";
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top