Thank you for the suggestion to use raw[] it did give me the result I was going for (as shown below).  But, qi::raw [+digit_[qi::_a = qi::_1]] never returned from the parse attempt.

 

string ("*ARSS") >> colon >>                  // Initial response

      qi::raw [qi::int_[qi::_a = qi::_1]] >> crlf >>    // Number of discovered devices - save in local qi::_a, output the raw text as well

          qi::omit [ok [qi::_b = qi::_1]] >>        // Match but don't emit the "OK" here - save it for the end

          qi::repeat (qi::_a)                       // Repeat for each discovered device

          [

                 crlf >>

         (

            qi::hold [profile1]

            | qi::hold [profile2]

              …blah, blah…

         )

          ] >>

          qi::attr(qi::_b);                         // Emit the "OK" here

 

 

This bumbling native is in awe of such god-like magic,

SGL

steven.lemay@igt.com

 

From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of TONGARI J
Sent: Friday, September 20, 2013 9:50 PM
To: boost-users@lists.boost.org
Subject: Re: [Boost-users] Newbie boost::spirit rule semantic action question

 

2013/9/21 LeMay.Steve <Steve.Lemay@igt.com>

Brand-newbie boost::spirit::qi question.  MSVS2012, boost 1.54

 

I have a response from a serial device that provides with 0 or more “profiles” in a given character format.  I want to capture the number of profile responses in the list (semantic action) as well as have the value into the final result (std::vector<std::string>).  How do I properly express this?

 

Given the input….  (in this case, there are zero profiles returned)

 

*ARSS:0<CR><LF>OK<CR><LF> 

 

Expect a vector of strings containing “*ARSS” “0” “OK”

 

This sub-rule fails to return… (Not failing to parse)

 

boost::spirit::qi::rule<Iter, std::vector<std::string>(), boost::spirit::qi::locals<int, std::string>> service_search_list;

 

       service_search_list %=                       // %= operator is necessary for attribute propagation when using symantic attributes (anything in [ ])

          string ("*ARSS") >> colon >>               // Initial response

          +digit [qi::_a = qi::_1] >> crlf >>       // Number of discovered devices - save in local qi::_a

          qi::omit [ok [qi::_b = qi::_1]] >>        // Match but don't emit the "OK" here - save it for the end

          qi::repeat (qi::_a)                       // Repeat for each discovered device

          [

                 crlf >>

         (

            qi::hold [profile1]

            | qi::hold [profile2]

            …

         )

          ] >>

          qi::attr(qi::_b);                         // Emit the "OK" here at the end of the list

 

Using qi::int_[qi::_a = qi::_1] provides and empty string “” in the result and not “0”.

 

Because int_ returns "int" which is not comatible with "string".

 

If I omit the numeric input from the result… qi::omit [qi::int_[qi::_a = qi::_1]] the parse will succeed but number of items in the response list is lost in the final result (omitted as requested).

 

Try qi::raw[], it'll give you a range which is string-compatible.


HTH