Boost logo

Boost Users :

Subject: Re: [Boost-users] Spirit.Qi : forfait !
From: Michele Caini (michele.caini_at_[hidden])
Date: 2010-04-16 12:07:40


Il 16/04/2010 17:13, Hartmut Kaiser ha scritto:
> Michael,
>
> I really would like to help but I can't compile your example (parser.h and ../exception/sapecngexception.h is missing). And even if I could, it is always the best if you try to minimize the code you send to expose exactly the problem you're having. It's very difficult to understand such complex programs as yours without investing a significant amount of time.
>
> Regards Hartmut

Hi dear,
thank you very much.
Parser is part of a more complex software so it is not so easy to
extract it from the software. However, if you can, I'd like to
understand with your help steps to do.

Suppose our grammatic, like this, very simple (I put into quotes literal
component, like ".OUT", ok?):

  out := ".OUT" integer
  end := ".END"

  cmp := "R"(char)* integer integer double bool
  cmp := "L"(char)* integer integer double bool

  comment := "#"(char*) // it goes to the end of line

  start := (comment)*
           (cmp)+
           out
           end

That's all, if I'm not clear (this is not BNF, and this is not Spirit
like, I know!), please ask me.

Ok, go on.
I'd like to fill structs like this (adapted by BOOST_FUSION_ADAPT_STRUCT
macro, quite simple to do):

  struct cmp_s {
    int id;
    std::string name;
    int va, vb;
    double val;
    bool sym;
  };

  struct main_s {
    std::vector<std::string> comments;
    std::vector<cmp_s> cmps;
    int out;
  };

Suppose id comes from that symbols table (real table is quite more
complex but this is a foo-example, is it?):

  struct table_ : boost::spirit::qi::symbols< char, int >
  {
    table_()
    {
      add
        ("R", 1)
        ("L", 2)
      ;
    }
  };

That's all. Follows my grammar:

template < typename It >
struct parser : boost::spirit::qi::grammar
  < It, main_c(), boost::spirit::qi::ascii::space_type >
{

  typedef
  boost::spirit::qi::ascii::space_type
  space_type;

  parser(std::ostream& err): parser::base_type(start, "start")
  {
    using namespace boost::spirit;
    using namespace boost::phoenix;

    comment %= qi::lexeme['#' >> +(ascii::char_)];

    selm = qi::char_("RL")
              [at_c<0>(_val) = (table_() << _1), at_c<1>(_val) = _1]
>> *qi::char_("_a-zA-Z0-9") [at_c<1>(_val) += _1]
>> qi::int_ [at_c<2>(_val) = _1]
>> qi::int_ [at_c<3>(_val) = _1]
>> qi::double_ [at_c<4>(_val) = _1]
>> qi::bool_ [at_c<5>(_val) = _1]
      ;

    start = eps [at_c<4>(_val) = 0]
>> *(comment) [push_back(at_c<0>(_val), _1)]
>> +(selm) [push_back(at_c<1>(_val), _1)]
>> ".OUT"
>> qi::int_ [at_c<4>(_val) = _1]
>> ".END";
      ;

    comment.name("comment");
    selm.name("selm");
    start.name("start");

    qi::on_error<qi::fail>
      (start, err
        << val("Syntax error. Expecting ")
        << _4
        << val(" here: \"")
        << construct<std::string>(_3, _2)
        << val("\"")
        << std::endl
      );
  }

  boost::spirit::qi::rule<It, std::string(), space_type> comment;
  boost::spirit::qi::rule<It, ::client::selm(), space_type> selm;
  boost::spirit::qi::rule<It, ::client::circuit(), space_type> start;

};

A more complex example on this idea compiles fine, but invoking it with
something like:

# Comment 1
R1 1 2 2.5 0
L32 4 5 0.003 1
.OUT 3
.END

Returns from phrase_parse with a false value. I don't understand why
that! I'm sure to be in error (of course, it doesn't work as I want, so
something is wrong!!) but really since two days ago I look for the error
whitout find it.

Something to suggest?

Thanks in advance,
Michele


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