Parsing of a mapping between keys and values by X3 programming interface

SF Markus Elfring via Spirit-general <[email protected]> Sat, 22 Sep 2018 21:21:11 +0200
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
Hello,

I would like to improve my software development experiences also for the class
library “Boost.Spirit” once more based on the topic “Parsing a list of key-value
pairs using Spirit.Qi”.
https://boost-spirit.com/home/articles/qi-example/parsing-a-list-of-key-value-pairs-using-spirit-qi/

I got into the mood to try something out again with the software version “X3”
which I can use from “Boost 1.68”.
I have adjusted one of my previous development attempts based on the example
“RExpressions - Recursive ASTs!”.
https://drop.ciere.com/xr-tutorial/boost/libs/spirit/doc/x3/html/spirit_x3/tutorials/rexpr.html
https://github.com/boostorg/spirit/blob/6846946823ec8822050bc8396b9100cb63c21cf1/example/x3/rexpr/rexpr_min/rexpr.cpp#L9

Unfortunately, I have got understanding difficulties here.
Now I stumble on the following error message.

elfring@Sonne:~/Projekte> LANG=C /usr/bin/clang++-6.0.1 bind-test3.cpp
In file included from bind-test3.cpp:6:
In file included from /usr/include/boost/spirit/home/x3.hpp:14:
In file included from /usr/include/boost/spirit/home/x3/auxiliary.hpp:11:
In file included from /usr/include/boost/spirit/home/x3/auxiliary/any_parser.hpp:17:
/usr/include/boost/spirit/home/x3/support/traits/move_to.hpp:195:9: error: no matching function for call to 'move_to'
        detail::move_to(std::move(src), dest
        ^~~~~~~~~~~~~~~
/usr/include/boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp:29:21: note: in instantiation of function template specialization 'boost::spirit::x3::traits::move_to<parser::structures::settings,
      std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>,
      std::__cxx11::basic_string<char> > > > >' requested here
            traits::move_to(std::forward<Transformed>(attr), val);
                    ^
…


I would appreciate your advices.

Regards,
Markus

_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
bind-test3.cpp (text/x-c++src, 2.2 KB)
#include <iostream>
#include <stdexcept>
#include <utility>
#include <string>
#include <map>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/include/io.hpp>
#include <cstdio>
#include <cstdlib>

namespace parser
{
namespace bsx = boost::spirit::x3;
namespace bsa = boost::spirit::x3::ascii;

namespace structures
{
typedef std::pair<std::string, std::string> assignment_type;
typedef std::map<std::string, std::string> map_type;

struct settings
{
map_type mapping;
};
}

bsx::rule<class assignment, structures::assignment_type> const assigned("assignment");
bsx::rule<class settings, structures::settings> const settings("settings");
auto const assigned_def((+ bsa::alnum) >> bsx::lexeme['=' >> + bsa::graph]);
auto const settings_def(+ assigned);
BOOST_SPIRIT_DEFINE(assigned, settings);


struct extractor
{
   structures::map_type table;

   void parse(std::string const& text)
   {
      auto first = text.begin();
      auto last = text.end();
      bool r(bsx::phrase_parse(first, last, settings, bsa::space, table));
      if (!r)
      {
         std::cerr << "stopped at: \"" << std::string(first, last) << '"' << std::endl;
         throw std::runtime_error("Parsing failure");
      }
   }
};

}

BOOST_FUSION_ADAPT_STRUCT(parser::structures::settings, mapping)

int main(int argc, char* argv[])
{
   char const my_message[] = " exception was caught.";
  
   try
   {
      parser::extractor ex;
      ex.parse(argc == 1 ? "key=value" : argv[1]);
      std::cout << ex.table.size() << " parameters" << std::endl;

      for (auto& x: ex.table)
      {
         std::cout << '|' << x.first << "|: |" << x.second << '|' << std::endl;
      }
   }
   catch (std::bad_alloc const& b)
   {
      (void) std::fputs("out of memory\n", stderr);
      return EXIT_FAILURE;
   }
   catch (std::exception const& x)
   {
      (void) std::fprintf(stderr,
                          "A kind of standard%s\n%s\n",
                          my_message,
                          x.what());
      return EXIT_FAILURE;
    }
    catch (...)
    {
       (void) std::fprintf(stderr, "An unknown%s\n", my_message);
       throw;
    }
}