Spirit2/2x: multi_pass iterator broken?

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Spirit2/2x: multi_pass iterator broken?

Cédric Venet-2
Hi,

I am using VS2008sp1 to sompile my code. I use boost 1.38.0. (But I
checked and the problem does not seems to be solved in boost trunk,
neither in spirit2x trunk).

I wanted to parse a file.

My first attempt was to include
<boost/spirit/include/support_look_ahead.hpp> and use that. but the
header is broken: it pass too much template parameter to
multi_pass_iterator.

I tryed to corect this problem by using the polycy_combinator:

  typedef std::istream_iterator<char> data_type;
  typedef boost::spirit::multi_pass_policies::input_iterator input_policy;
  typedef boost::spirit::multi_pass_policies::first_owner ownership_policy;
  typedef boost::spirit::multi_pass_policies::no_check check_policy;
  typedef boost::spirit::multi_pass_policies::fixed_size_queue<32>
storage_policy;
  typedef boost::spirit::multi_pass_policies::std_deque storage_policy;
  typedef
boost::spirit::multi_pass_policies::default_policy<ownership_policy,
check_policy, input_policy, storage_policy> policy_type;

  // iterator type used to expose the underlying input stream
  typedef boost::spirit::multi_pass<data_type, policy_type>
fixed_multi_pass_t;

This fail because multi_pass_policies::first_owner has no clone member.
using ref_counted instead fail because fixed_size_queue_policy call
input_at_eof with only one argument instead of two in is_eof.

replacing fixed_size_queue<32> by std_dequed return lot of errors and I
decided to stop my investigation here.

Did I do something wrong? Is multi_pass_iterator broken? Is there any
plan to correct this? Any other way to parse a file without buffering
all of it before?

I didn't try to fix the code since I am not sure of its state. I may
give it a try if I had a little more information on what is correct and
what is wrong (ie, on what class model my change).

regards,

Cédric

ps: the parser driver code I used:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
// #include <boost/spirit/include/support_look_ahead.hpp> // broken in 1.38

#include <iterator>
#include <fstream>
#include <string>
#include <algorithm>

namespace charset = boost::spirit::ascii;
namespace spirit  = boost::spirit;
namespace qi      = boost::spirit::qi;
namespace phoenix = boost::phoenix;

/* MY GRAMMAR, work ok on a string */

bool parse(/* */) {
  std::ifstream in(filename, std::ios_base::in);
  ASSERTM(in,"Error: Could not open input file: " << filename);

  // FIXME: should work directly on the file, with line number
//  std::string storage; // We will read the contents here.
  in.unsetf(std::ios::skipws); // No white space skipping!
//  
std::copy(std::istream_iterator<char>(in),std::istream_iterator<char>(),std::back_inserter(storage));

  // 32 look ahead is amply suffisante, except if someone put a lot a
space where between a key and the '{'
  // anyway, we could make the grammar work with a 1 char look ahead if
needed
  //typedef look_ahead<std::istream_iterator<char>, 32> fixed_multi_pass_t;
  // look_ahead is broken in 1.38


  typedef std::istream_iterator<char> data_type;
  typedef boost::spirit::multi_pass_policies::input_iterator input_policy;
  //typedef boost::spirit::multi_pass_policies::first_owner
ownership_policy;   // broken in 1.38
  typedef boost::spirit::multi_pass_policies::ref_counted ownership_policy;
  typedef boost::spirit::multi_pass_policies::no_check check_policy; //
buf_id_check
  //typedef boost::spirit::multi_pass_policies::fixed_size_queue<32>
storage_policy;   // broken in 1.38
  typedef boost::spirit::multi_pass_policies::std_deque storage_policy;
  typedef
boost::spirit::multi_pass_policies::default_policy<ownership_policy,
check_policy, input_policy, storage_policy> policy_type;

  // iterator type used to expose the underlying input stream
  typedef boost::spirit::multi_pass<data_type, policy_type>
fixed_multi_pass_t;

//  typedef std::string::iterator iterator_t;
//  iterator_t iter = storage.begin();
  data_type a(in);
  fixed_multi_pass_t iter(a);
  data_type end;
  fixed_multi_pass_t iter_end(end);

  AseGrammar<fixed_multi_pass_t> def(*actions);

  qi::rule<fixed_multi_pass_t> skipper;
  skipper = charset::space;// | ('%' > *~spirit::char_('\n') > '\n');

  bool r = phrase_parse(iter, iter_end, def, skipper );
 
  if (r && iter == iter_end) {
    LOG("Parsing succeeded");
  } else {
    ERROR("Parsing failed");
  }
}



------------------------------------------------------------------------------
_______________________________________________
Spirit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-devel