rule's attribute captures too much?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

rule's attribute captures too much?

Martin.Franzke-2
Hello,

Trying to parse "0/1/x" with

qi::ascii::digit >> +(qi::char_('/') >> qi::ascii::digit)

I had expected the synthesized attributes value to be "0/1".

But he following code results in "0/1/", where the suffix is "/x". Is this the correct behavior?

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>

int main(void)
{
  using namespace boost::spirit;
  char const * first = "0/1/x";
  char const * last = first + std::strlen(first);
  std::string capture;
  bool ok = qi::parse(first, last, qi::ascii::digit >> +(qi::char_('/') >> qi::ascii::digit) >> lit("/x"), capture);
  std::cout << "captured = '" << capture << "'\n";
  std::cout << "full match = " << std::boolalpha << (ok && first == last) << "\n";
  return ok;
}

Running the code results in

captured = '0/1/'
full match = true

Regards
Martin

------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: rule's attribute captures too much?

Joel de Guzman
On 09/11/2016 4:44 PM, [hidden email] wrote:
> Hello,
>
> Trying to parse "0/1/x" with
>
> qi::ascii::digit >> +(qi::char_('/') >> qi::ascii::digit)
>
> I had expected the synthesized attributes value to be "0/1".
>
> But he following code results in "0/1/", where the suffix is "/x". Is this the correct behavior?

It might not be intuitive, but I think it is the correct behavior. Qi
is greedy and will eat as much as it can. '/' is valid at that point,
while digit, after it, will fail and thus exit the + loop. The other
interpretation will be very inefficient requiring backtracking and
attribute saving and try-commit semantics.

If you want the behavior you expect, use syntactic predicates or
some other means to test first before committing the attribute.
Example:

   digit >> +(('/' >> &digit) >> attr('/') >> digit)

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general