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;
}
}