boost::spirit::qi rule reduce parsing error
<p>I try to parse a list of <code>integer</code> and <code>double</code> pairs using <code>boost::spirit::qi</code>. An <code>integer</code> precedes and follows to this list. An example of this list is:</p>

<pre><code>20 1 1.3 2 2.3 30
</code></pre>

<p>The structure I want to create is:</p>

<pre><code>typedef std::vector&lt; std::pair&lt;int, double&gt; &gt; vec_t;
struct list_s{
  int first;
  std::vector&lt; std::pair&lt;int, double&gt; &gt; list;
  int last;
};
</code></pre>

<p>Also I added error handling to my parser using <code>qi::on_error</code> and converting all sequences <code>&gt;&gt;</code> to expects <code>&gt;</code>.</p>

<p>My implementation is:</p>

<pre><code>#include &lt;boost/config/warning_disable.hpp&gt;
#include &lt;boost/spirit/include/qi.hpp&gt;
#include &lt;boost/spirit/include/phoenix.hpp&gt;
#include &lt;boost/fusion/adapted/std_pair.hpp&gt;
#include &lt;boost/fusion/include/adapt_struct.hpp&gt;

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;tuple&gt;

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

typedef std::vector&lt; std::pair&lt;int, double&gt; &gt; vec_t;
struct list_s{
  int first;
  vec_t list;
  int last;
};

BOOST_FUSION_ADAPT_STRUCT(
    list_s,
    (int, first)
    (vec_t, list)
    (int, last)
)

template &lt;typename Iterator&gt;
struct list_parser : qi::grammar&lt;Iterator, list_s(), ascii::space_type &gt;
{
  public:
    list_parser() : list_parser::base_type(r) {
      r = qi::eps &gt;&gt;
        (
          qi::int_
          &gt; *( qi::int_ &gt; qi::double_ )
          &gt; qi::int_
        );

      r.name("r");
      qi::on_error&lt;qi::fail&gt;
        (
         r
         , std::cout
         &lt;&lt; phoenix::val("\nError! Expecting ")
         &lt;&lt; qi::labels::_4 
         &lt;&lt; phoenix::val(" here: \"")
         &lt;&lt; phoenix::construct&lt;std::string&gt;(qi::labels::_3, qi::labels::_2)
         &lt;&lt; phoenix::val("\"\n\n")
        );
    }
  private:
    qi::rule&lt;Iterator, list_s(), ascii::space_type &gt; r;
};

int main() {
  std::string str("20 1 1.3 2 2.3 30");

  list_s r;
  list_parser&lt;std::string::const_iterator&gt; p;
  std::string::const_iterator iter = str.begin();
  std::string::const_iterator end = str.end();
  if( qi::phrase_parse(iter, end, p, ascii::space, r) ){
    std::cout &lt;&lt; r.first &lt;&lt; std::endl;
    for(auto&amp; i : r.list) std::cout &lt;&lt; i.first &lt;&lt; " , " &lt;&lt; i.second &lt;&lt; std::endl;
    std::cout &lt;&lt; r.last &lt;&lt; std::endl;
  }
  return 0;
}
</code></pre>

<p>When running this example I get </p>

<pre><code>Error! Expecting &lt;real&gt; here: ""
</code></pre>

<p>I know I can change the list parsing rule to <em>sequence</em></p>

<pre><code>*( qi::int_ &gt;&gt; qi::double_ )
</code></pre>

<p>to overcome the above error. But then the parsing of <code>20 1 1.3 2 error 30</code> is also successful. The result would be:</p>

<pre><code>20
1 , 1.3
2
</code></pre>

<p>Any suggestion to overcome this problem?</p>