Re: x3 semantic action and attribute transformation

Olaf Peter <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
> I try in x3 to parse integers which can have seperators '_'. But it
> fails to compile:
>
>           detail::move_to(std::move(src), dest
>           ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
>             , typename attribute_category<Dest>::type());
>             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> etc.
>
> The idea behind is to parse it first into vector<int> and use these rule
> with a semantic action (SA) with a 2nd rule to combine it finally to an
> int. Append the SA directly to the 1st rule also fails to compile.
>
> What is the correct way? Are there any simplifications also? The first
> question seems to me fundamental to be solved.
>
> BTW, why the syntax :
>     auto const integer_def = integer %=
> is there a better one?
>
> Thanks,
> Olaf
>
> ---8<---
> #include <iosfwd>
> //#define BOOST_SPIRIT_X3_DEBUG
>
> #include <boost/spirit/home/x3.hpp>
>
> #include <iostream>
> #include <vector>
> #include <algorithm> // for copy
> #include <iterator>  // for ostream_iterator
> #include <sstream>
>
> namespace parser {
>
>    namespace x3 = boost::spirit::x3;
>    namespace iso8859_1 = boost::spirit::x3::iso8859_1;
>
>    using iso8859_1::char_;
>
>    typedef x3::rule<struct integer_class, uint> integer_type;
>    typedef x3::rule<struct inner_integer_class, std::vector<int>>
> inner_integer_type;
>
>    integer_type const integer { "integer" };
>    inner_integer_type const inner_integer { "inner integer" };
>
>
>    auto combine_to_uint = [](auto &ctx) {
>      auto const &v = x3::_val(ctx);
>      std::ostringstream ss;
>      std::copy(v.begin(), v.end(), std::ostream_iterator<int>(ss, ""));
>      uint int_ { 0 };
>      x3::_pass(ctx) = x3::parse(ss.str().begin(), ss.str().end(),
> x3::uint_, int_);
>      std::cout << int_ << '\n';
>      x3::_attr(ctx) = int_;
>    };
>
>    x3::uint_parser<int, 10, 1, 1>  const digit = { };
>
>    // Parse '1_000' as 1000
>    auto const inner_integer_def =
>      digit >> *( x3::omit[ -char_('_') ] >> digit )
>      ;
>
>    auto const integer_def = integer %= inner_integer[combine_to_uint];
>
>    BOOST_SPIRIT_DEFINE(inner_integer, integer)
> }
>
>
> int main()
> {
>    namespace x3 = boost::spirit::x3;
>
>    std::vector<std::string> const test_cases {
>        "0",
>        "1",
>        "01",
>        "1_000",
>        "42_666_4711",
>        "4_294_967_295", // uint32::max
>        "4_294_967_296" // ??? how to get message about UINT_MAX failed??
>        };
>
>    typedef std::string::const_iterator iterator_type;
>
>    for(auto str: test_cases) {
>      iterator_type iter = str.begin();
>      iterator_type const end = str.end();
>
>      auto& rule = parser::integer;
>
>      std::cout << "parse `" << str << "´:\n";
>
>      std::vector<int> i;
>
>      bool r = x3::phrase_parse(iter, end, rule, x3::space, i);
>
>      if (r && iter == end) {
>        std::cout << "succeeded\n";
>      } else {
>        std::cout << "failed\n";
>      }
>    }
>
>    return 0;
> }
> --->8---

Probably I miss the hook to inform spirit x3 how to move src -> dest. 
Simply x3::_val(ctx) = std::move(int_) doesn't solve it:

x3/support/traits/move_to.hpp:
...detail::move_to_plain ...  [with Source = std::vector<int>; Dest = 
unsigned int, ...
...detail::move_to...[with Source = std::vector<int>; Dest = unsigned 
int, ...


------------------------------------------------------------------------------
Announcing the Oxford Dictionaries API! The API offers world-renowned
dictionary content that is easy and intuitive to access. Sign up for an
account today to start using our lexical data to power your apps and
projects. Get started today and enter our developer competition.
http://sdm.link/oxford
_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.