Boost logo

Boost Users :

From: Michael Orlov (orlovm_at_[hidden])
Date: 2004-06-27 10:43:48


Hi,

I am new to Spirit, and I am writing a reader for s-expressions, and so far
has encountered the following problems, which seem to me to be contrarry to
the documentation (Spirit 1.8.0 in Boost 1.31.0).

Consider the following (small) C++ program:

---------------------------------------------

#include <iostream>
#include <iterator>
#include <string>
#include <boost/spirit/core.hpp>
#include <boost/spirit/iterator/multi_pass.hpp>

using namespace std;
using namespace boost::spirit;

struct Sexp
  : public boost::spirit::grammar<Sexp>
{
  template <typename ScannerT>
  struct definition
  {
    typedef rule<ScannerT> rule;

    definition(const Sexp &self)
    {
      first =
        ( sexp = '(' >> *sexp >> ')' );
    }

    subrule<0> sexp;

    rule first;
    const rule& start() const { return first; }
  };
};

int main()
{
  typedef std::istream_iterator<char> iterator_t;
  typedef boost::spirit::multi_pass<
    iterator_t,
    boost::spirit::multi_pass_policies::input_iterator,
    boost::spirit::multi_pass_policies::first_owner
> iterator_wrapper_t;

  Sexp sexper;

  iterator_t under_first(cin);
  iterator_t under_last;

  iterator_wrapper_t first(under_first);
  iterator_wrapper_t last(under_last);

  while (true) {
    parse_info<iterator_wrapper_t> info =
      parse(first, last, sexper);

    first.clear_queue();

    if (info.hit)
      std::cout << "Hit: " << info.length << std::endl;
    else
      break;
  };
}

---------------------------------------------

The purpose is to read s-expression from input, delivering them to the user
the moment they are ready. Since whitespace skipper tries to consume as much
space as it can, it is not suitable here, so I don't want to use it.

Here comes the first problem: even when I don't pass space_p to parse(), the
skipper is still present:

---
( )
^D
Hit: 2
---
---
(())(
Hit: 4
)
^D
Hit: 2
---
Another problem is when I try to use istreambuf_iterator instead of
istream_iterator (this is done in Spirit examples, too). When substituting
istreambuf_iterator in the first typedef in main(), the program no longer
compiles - neither with Intel Compiler 8.0.055, nor with GCC 3.3.2.
Intel complains about
  /usr/local/include/boost/spirit/iterator/multi_pass.hpp(537): error: initial
    value of reference to non-const must be an lvalue
                return **input;
and GCC's messages are too long to parse. :)
Any help?
Thanks,
Michael

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net