2

を使用してベクターにデータを挿入する際に問題がありますphoenix::insert。このコードは、「(move xyz - loc r - robot item)」などの入力を解析して、struct Predicate「move」という名前の 3 つの変数 type loc、1 つの type 変数、robotおよび 1 つの変数 type に変換する必要がありますobject。これらのシンボルはすべて、問題に実際には関係のない単なる文字列です (私は信じています)。問題はphoenix::insert、ルールの定義で を使用していることですpredicate

ここに私が持っているコードがあります:

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.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/spirit/include/phoenix_object.hpp>
#include <boost/spirit/home/phoenix/container.hpp>
#include <boost/fusion/include/adapt_struct.hpp>


namespace client {

  namespace fusion = boost::fusion;
  namespace phoenix = boost::phoenix;
  namespace qi = boost::spirit::qi;
  namespace ascii = boost::spirit::ascii;

  struct Variable {
    std::string name;
    std::string type;
  };


  struct Predicate {
    std::string name;
    std::vector<Variable> vars;
  };


  struct TermList {
    std::vector<Variable> vars;

    TermList() = default;
    TermList(std::vector<std::string> names, std::string type)
    {
      for (auto& n : names)
      {
        Variable t;
        t.name = n;
        t.type = type;
        vars.push_back(t);
      }
    }

    TermList& operator=(const TermList& rhs) = default;
    TermList(const TermList& from) = default;
    TermList(TermList&& from) = default;
  };

}

BOOST_FUSION_ADAPT_STRUCT(
  client::Variable,
  (std::string, name)
  (std::string, type)
)

BOOST_FUSION_ADAPT_STRUCT(
  client::Predicate,
  (std::string, name)
  (std::vector<client::Variable>, vars)
)

BOOST_FUSION_ADAPT_STRUCT(
  client::TermList,
  (std::vector<client::Variable>, vars)
)

namespace client {

  template <typename Iterator, typename Skipper = ascii::space_type>
  struct strips_domain_grammar
  : qi::grammar<Iterator, Predicate(),
                qi::locals<std::vector<Variable>>, Skipper>
  {
    strips_domain_grammar()
    : strips_domain_grammar::base_type(predicate, "predicate")
    {

      using qi::eps;
      using qi::lit;
      using qi::lexeme;
      using qi::raw;

      using qi::on_error;
      using qi::fail;

      using phoenix::at_c;
      using phoenix::push_back;
      using phoenix::insert;
      using phoenix::begin;
      using phoenix::end;
      using phoenix::construct;
      using phoenix::val;

      using ascii::char_;
      using ascii::string;
      using ascii::alpha;
      using ascii::alnum;
      using namespace qi::labels;

      // identifier such as move or ?from
      identifier %= raw[lexeme[((alpha | char_('_') | char_('?'))
                                >> *(alnum | char_('_') | char_('-')))]];

      // x | x y | x - type | x y z - type
      term_list =
      +(identifier          [push_back(_a, _1)])
      >>
      (
       ('-' >
       identifier [qi::_val = phoenix::construct<TermList>(qi::_a, qi::_1)])
       |
       eps        [qi::_val = phoenix::construct<TermList>(qi::_a, "object")]
       )
      ;

      // (move x y z - loc r - robot item) // item is detault type - object
      predicate =
      char_('(')
      > identifier       [at_c<0>(_val) = _1]
      > +(term_list      [insert(at_c<1>(_val), end(at_c<1>(_val)),   // <- ERROR
                                 begin(at_c<0>(_1)), end(at_c<0>(_1)))])
      > ')'
      ;


      predicate.name("predicate");
      term_list.name("term list");
      identifier.name("id");

      // on_error is called only when an expectation fails (> instead of >>)
      on_error<fail>
      (
       predicate
       , std::cout
       << val("Error! Expecting ")
       << _4                               // what failed?
       << val(" here: \"")
       << construct<std::string>(_3, _2)   // iterators to error-pos, end
       << val("\"")
       << std::endl
       );
    }

    qi::rule<Iterator, std::string(), Skipper> identifier;

    qi::rule<Iterator, TermList(),
             qi::locals<std::vector<std::string>>, Skipper> term_list;

    qi::rule<Iterator, Predicate(),
             qi::locals<std::vector<Variable>>, Skipper> predicate;

  };
} // namespace client

int main(int argc, const char** argv)
{
  typedef std::string::const_iterator iterator_type;
  typedef client::strips_domain_grammar<iterator_type> domain_grammar;

  domain_grammar g;

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

    using boost::spirit::ascii::space;

    client::Predicate predicate;
    std::string::const_iterator iter = str.begin();
    std::string::const_iterator end = str.end();
    bool r = phrase_parse(iter, end, g, space, predicate);

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

しかし、コードは次のエラーにつながります (libc++ および c++11 を使用する clang3.3; mac os x 10.8):

boost/spirit/home/phoenix/stl/container/container.hpp:416:16: error: void function 'operator()' should not return a value [-Wreturn-type]
           return c.insert(arg1, arg2, arg3);

上記のように、エラーはルールphoenix::insertのアクションで使用した結果だと思います。predicate

ブーストヘッダーを編集してreturnステートメントを削除することで問題を「修正」しましたが、このライブラリについての理解が限られているため、それを避けたいと思います...

誰かが問題を説明したり、別の解決策を提案したりできますか?

4

0 に答える 0