Opened 11 years ago
Closed 11 years ago
#6043 closed Patches (wontfix)
Spirit insists that user types are adapted to Fusion
Reported by: | Vladimir Prus | Owned by: | Joel de Guzman |
---|---|---|---|
Milestone: | To Be Determined | Component: | spirit |
Version: | Boost 1.47.0 | Severity: | Problem |
Keywords: | Cc: |
Description
I've played with Spirit for the first time, and arrived at the attached example. Basically, I want to create Foo instances from pairs of numbers. This example does not compile unless Foo is adapted to fusion. I don't think this is a good idea, because from the point of view of user, the parser should create instances of Foo, and it's not really clear why parser should iterate over existing instances -- which is what it is trying to do.
Attachments (2)
Change History (6)
by , 11 years ago
comment:1 by , 11 years ago
On IRC, Thomas produced somewhat easier example. Code the does not work:
#include <boost/spirit/home/qi.hpp> #include <boost/spirit/home/phoenix.hpp> namespace fusion = boost::fusion; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; struct foo { foo(fusion::vector<int, double>) {} }; int main() { typedef std::string::iterator iterator; qi::rule<iterator, foo()> foo_rule; foo_rule = (qi::int_ >> qi::double_); }
Code that does work:
#include <boost/spirit/home/qi.hpp> #include <boost/spirit/home/phoenix.hpp> namespace fusion = boost::fusion; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; struct foo { foo() {} foo(int, double) {} foo(fusion::vector<int, double>) {} }; int main() { typedef std::string::iterator iterator; qi::rule<iterator, fusion::vector<int, double>()> tuple_rule; qi::rule<iterator, foo()> foo_rule; tuple_rule = (qi::int_ >> qi::double_); foo_rule %= tuple_rule.alias(); }
I frankly don't understand what's going on here, but trying the same workaround for me does not work (with Boost trunk, and gcc 4.5.3), while Thomas reported this new example (main-with-workaround.cpp) compiles for him just fine with 1.47.
by , 11 years ago
Attachment: | main-with-workaround.cpp added |
---|
testcase with attempted workaround, still does not work for me.
comment:2 by , 11 years ago
Component: | None → spirit |
---|---|
Owner: | set to |
comment:3 by , 11 years ago
Here's what's happening:
When you have A >> B, the rules are: http://tinyurl.com/bqch2m6
So, as far as compatibility goes, the attribute either has to be a fusion sequence *or* a std container. That is why your code does not compile.
The thing is, spirit is optimal and walks the sequence and builds its elements in-situ, instead of synthesising a temporary sequence in memory and assign later. That is why it has to iterate over existing instances. In this case, it cannot walk a foo. Heller's workaround works because the inner rule is able to walk the fusion sequence and then attribute transformation kicks in whereby it assigns the fusion sequence to foo. That works but is sub optimal.
comment:4 by , 11 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Volodya, I'm going to close this as no-fix. If you want to discuss, we can do it in IRC or the mailing lists.
testcase