[Spirit Development][Karma] statement [_0 = _val] is broken in trunk

Robert Nelson <[email protected]> Sat, 1 Jan 2011 16:35:39 -0700
Newsgroups gmane.comp.parsers.spirit.devel
Message-ID <[email protected]>
I am trying to use the following rule with [_0 = _val] at the end.  It
compiles fine, but executes improperly.

rule<iter,point()> broken_rule = (int_ << ',' << int_)[_0 = _val];

A very similar rule, however, works just fine.

rule<iter,point()> working_rule = (int_ << ',' << int_);

The relevant part of the code is:
  point data(1,2);
  rule<iter,point()> broken_rule = (int_ << ',' << int_)[_0 = _val];
  std::string broken_output;
  generate(std::back_inserter(broken_output),broken_rule,data);


The semantic action appears to break it.
The output of my program is:

expected output: 1,2
broken   output: 0,0
working  output: 1,2

Apparently [_0 = _val] discards _val and default constructs _0 to [0,0].

------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl

_______________________________________________
Spirit-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
main.cpp (text/x-c++src, 975 B)
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <iterator>
#include <string>

int main()
{
  typedef boost::fusion::vector2<int,int> point;

  using namespace boost::spirit::karma;
  using namespace boost::phoenix;
  typedef std::back_insert_iterator<std::string> iter;

  //a minimal example of the problem
  point data(1,2);
  rule<iter,point()> broken_rule = (int_ << ',' << int_)[_0 = _val];
  std::string broken_output;
  generate(std::back_inserter(broken_output),broken_rule,data);
  std::cout<<"expected output: "<<boost::fusion::at_c<0>(data)<<","<<boost::fusion::at_c<1>(data)<<std::endl;
  std::cout<<"broken   output: "<<broken_output<<std::endl;

  
  //a similar grammar that works 
  rule<iter,point()> working_rule = (int_ << ',' << int_);
  std::string working_output;
  generate(std::back_inserter(working_output),working_rule,data);
  std::cout<<"working  output: "<<working_output<<std::endl;
}