Quantcast

fusion pair issue?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

fusion pair issue?

Patrick Welche
Given the trivial working attached code, I do the following:

--- works.cpp 2017-03-27 17:25:13.008492450 +0200
+++ fails.cpp 2016-06-14 13:17:12.683679158 +0200
@@ -2,16 +2,17 @@
 
 #include <boost/spirit/home/x3.hpp>
 #include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/fusion/include/std_pair.hpp>
 
 namespace x3 = boost::spirit::x3;
 
 struct result
 {
- std::string first, second;
+ std::pair<std::string, std::string> both;
 };
 
 BOOST_FUSION_ADAPT_STRUCT(result,
- first, second
+ both
 )
 
 int main()
@@ -27,8 +28,8 @@
  std::cout << "Bit left over at the end: "
           << std::string(iter, end) << std::endl;
  else
- std::cout << "found: " << res.first << ' '
-                       << res.second << std::endl;
+ std::cout << "found: " << res.both.first << ' '
+                       << res.both.second << std::endl;
 
  return 0;
 }


and get a compiler error. What have I forgotten to change?

(Hoping to use the automatic semantic action feature of x3. I'm sure I
could write a lot more code and have it work, but I don't see why a priori
the above isn't sufficient...)

Cheers,

Patrick

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

works.cpp (789 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fusion pair issue?

sehe
On 27-03-17 17:34, Patrick Welche wrote:
Given the trivial working attached code, I do the following:

--- works.cpp	2017-03-27 17:25:13.008492450 +0200
+++ fails.cpp	2016-06-14 13:17:12.683679158 +0200
@@ -2,16 +2,17 @@
 
 #include <boost/spirit/home/x3.hpp>
 #include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/fusion/include/std_pair.hpp>
 
 namespace x3 = boost::spirit::x3;
 
 struct result
 {
-	std::string first, second;
+	std::pair<std::string, std::string> both;
 };
 
 BOOST_FUSION_ADAPT_STRUCT(result,
-	first, second
+	both
 )
 
 int main()
@@ -27,8 +28,8 @@
 		std::cout << "Bit left over at the end: "
 		          << std::string(iter, end) << std::endl;
 	else
-		std::cout << "found: " << res.first << ' '
-		                       << res.second << std::endl;
+		std::cout << "found: " << res.both.first << ' '
+		                       << res.both.second << std::endl;
 
 	return 0;
 }


and get a compiler error. What have I forgotten to change?

(Hoping to use the automatic semantic action feature of x3. I'm sure I
could write a lot more code and have it work, but I don't see why a priori
the above isn't sufficient...)

Equivalent would be

#define BOOST_SPIRIT_X3_DEBUG

#include <boost/fusion/include/std_pair.hpp>
#include <boost/spirit/home/x3.hpp>

namespace x3 = boost::spirit::x3;

using result = std::pair<std::string, std::string>;

See http://coliru.stacked-crooked.com/a/5e266b02bf68272a

Alternatively use:

struct result : std::pair<std::string, std::string> {};
BOOST_FUSION_ADAPT_STRUCT(result, first, second)


See http://coliru.stacked-crooked.com/a/674c614ed7f75e70

Or

    result res;
    bool ok = x3::parse(iter, end, +x3::alnum >> ' ' >> +x3::alnum, res.both);

See http://coliru.stacked-crooked.com/a/2a847ad1037640f3

Or even more mixages:

struct result
{
    std::pair<std::string, std::string> both;
};

BOOST_FUSION_ADAPT_STRUCT(result, both.first, both.second)

See http://coliru.stacked-crooked.com/a/96ddef3f1dcba167

Last one, in case you really need to force automatic attribute propagation without any Fusion sequence unpacking hints:

    result res;
    auto const p = x3::rule<struct _, decltype(result::both)> {}
                 = +x3::alnum >> ' ' >> +x3::alnum;
    bool ok = x3::parse(iter, end, p, res);

See http://coliru.stacked-crooked.com/a/020b2510b47aa467

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fusion pair issue?

Patrick Welche
Thank you so much for your answer!

I was struck by this version:

> See http://coliru.stacked-crooked.com/a/2a847ad1037640f3

No need to know the member names of a pair for a BOOST_FUSION wrapping.

Given ciere.com/cppnow15/x3_docs/spirit/tutorials/rexpr.html:

  "We need to tell fusion about our rexpr struct to make it a
  first-class fusion citizen"

I would never have guessed your solution was possible.

Fusion is still necessary via

  #include <boost/fusion/include/std_pair.hpp>

but nicely hidden. I have no idea what the correct fusion wrapping would
be for a map (we had to know and list "first" and "second" for the pair),
however thankfully I don't need to know!

Thanks again,

Patrick

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

try.cpp (815 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fusion pair issue?

Patrick Welche
The euphoria has settled a bit:

> bool ok = x3::parse(iter, end,
> +( +x3::alnum >> ' ' >> +x3::alnum >> ';' ),
> res.both);

I had called parse() with res.both instead of res. The whole point of
this was to hand over a struct capable of holding the parsed values
without adding semantic actions. Then one can extended the struct
to more complicated grammars.

Attached is a working example, which then breaks when I apply:

--- try.cpp.orig 2017-04-01 00:59:43.065447337 +0100
+++ try.cpp 2017-04-01 08:46:52.798091359 +0100
@@ -2,6 +2,7 @@
 
 #include <map>
 
+#include <boost/fusion/include/adapt_struct.hpp>
 #include <boost/fusion/include/std_pair.hpp>
 #include <boost/spirit/home/x3.hpp>
 
@@ -20,7 +21,7 @@
  result res;
  bool ok = x3::parse(iter, end,
  +( +x3::alnum >> ' ' >> +x3::alnum >> ';' ),
- res.both);
+ res);
  if (!ok)
  std::cout << "Parsing failed\n";
  else if (iter != end)



Any more tips?


Cheers,

Patrick

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

works.cpp (860 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fusion pair issue?

sehe
On 01-04-17 09:54, Patrick Welche wrote:

Any more tips?
No real difference. Indeed I had been reshaping the problem in several ways to match the conventions that jell with X3.

If you must, you will have to do some type "hinting" work. I love hiding the cruft in small factory lambdas like this: http://coliru.stacked-crooked.com/a/416a5b7061721b2d :

using Map = std::map<std::string, std::string>;

struct result {
    Map both;
};

BOOST_FUSION_ADAPT_STRUCT(result, both)

int main()
{
    std::string const buf("one two;three four;");
    auto iter = buf.begin(), end = buf.end();
    auto parser = []{
        using namespace boost::spirit::x3;

        auto string_ = lexeme [ +(graph - ';') ];
        auto map_    = -(string_ >> string_) % ';';

        return rule<struct _, Map> {"parser"} = skip(space) [ map_ ];
    };
   
    result res;
    bool ok = parse(iter, end, parser(), res);

    if (ok) {
        std::cout << "Parse success\n";
    }
    else {
        std::cout << "Parsing failed\n";
    }

    if (iter != end) {
        std::cout << "Bit left over at the end: " << std::string(iter, end) << std::endl;
    }
    else {
        for (auto p : res.both) {
            std::cout << "found: " << p.first << ' ' << p.second << std::endl;
        }
    }
}

Which prints

    <parser>
      <try>one two;three four;</try>
      <success></success>
      <attributes>[[[[o, n, e], [t, w, o]], [[t, h, r, e, e], [f, o, u, r]]]]</attributes>
    </parser>
    Parse success
    found: one two
    found: three four


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fusion pair issue?

Patrick Welche
On Sat, Apr 01, 2017 at 10:48:02PM +0200, Seth wrote:
> On 01-04-17 09:54, Patrick Welche wrote:
> >
> > Any more tips?
> No real difference. Indeed I had been reshaping the problem in several
> ways to match the conventions that jell with X3.

Thank you very much!

Unfortunately I'm temporarily stumped by my gcc 5.4.0 being unhappy with it:

/usr/src/local/spirit/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:17: note:   candidate expects 2 arguments, 3 provided
                 attr.insert(attr.end(), rest.begin(), rest.end());

(I'm using spirit head abe2a14a7fd2, boost 1.63.0, and note that your
coliru example was compile with clang++)

Will ponder later...


Cheers,

Patrick

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fusion pair issue?

sehe
On 02-04-17 23:58, Patrick Welche wrote:
> (I'm using spirit head abe2a14a7fd2, boost 1.63.0, and note that your
> coliru example was compile with clang++)

Just switch it to g++: http://coliru.stacked-crooked.com/a/219c72b32b64d01a

Or, indeed g++-5.4.1 20160904:
http://coliru.stacked-crooked.com/a/91aecd5b1a45f1a0



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fusion pair issue?

Patrick Welche
On Mon, Apr 03, 2017 at 11:51:50PM +0200, Seth wrote:
> On 02-04-17 23:58, Patrick Welche wrote:
> > (I'm using spirit head abe2a14a7fd2, boost 1.63.0, and note that your
> > coliru example was compile with clang++)
>
> Just switch it to g++: http://coliru.stacked-crooked.com/a/219c72b32b64d01a
>
> Or, indeed g++-5.4.1 20160904:
> http://coliru.stacked-crooked.com/a/91aecd5b1a45f1a0

I compiled clang version 4.0.0 (branches/release_40 r294123)
just in case, use it for the first time, and much prefer the error
messages.

It turned out it wasn't an issue with the compiler: if I make use of
sprit x3 from boost 1.63.0, rather than git-head, the compile succeeds.

Cheers,

Patrick

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Loading...