title: Understanding the List Operator (%) in Boost.Spirit
body: <p>Can you help me understand the difference between the <code>a % b</code> parser and its expanded <code>a &gt;&gt; *(b &gt;&gt; a)</code> form in Boost.Spirit? Even though <a href="http://www.boost.org/doc/libs/1_59_0/libs/spirit/doc/html/spirit/qi/reference/operator/list.html">the reference manual</a> states that they are equivalent,</p>
  
  <blockquote>
    <p>The list operator, <code>a % b</code>, is a binary operator that matches a list of one or more repetitions of <code>a</code> separated by occurrences of <code>b</code>. This is equivalent to <code>a &gt;&gt; *(b &gt;&gt; a)</code>.</p>
  </blockquote>
  
  <p>the following program produces different results depending on which is used:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;vector&gt;
  
  #include &lt;boost/fusion/include/adapt_struct.hpp&gt;
  #include &lt;boost/spirit/include/qi.hpp&gt;
  
  struct Record {
    int id;
    std::vector&lt;int&gt; values;
  };
  
  BOOST_FUSION_ADAPT_STRUCT(Record,
    (int, id)
    (std::vector&lt;int&gt;, values)
  )
  
  int main() {
    namespace qi = boost::spirit::qi;
  
    const auto str = std::string{"1: 2, 3, 4"};
  
    const auto rule1 = qi::int_ &gt;&gt; ':' &gt;&gt; (qi::int_ % ',')                 &gt;&gt; qi::eoi;
    const auto rule2 = qi::int_ &gt;&gt; ':' &gt;&gt; (qi::int_ &gt;&gt; *(',' &gt;&gt; qi::int_)) &gt;&gt; qi::eoi;
  
    Record record1;
    if (qi::phrase_parse(str.begin(), str.end(), rule1, qi::space, record1)) {
      std::cout &lt;&lt; record1.id &lt;&lt; ": ";
      for (const auto&amp; value : record1.values) { std::cout &lt;&lt; value &lt;&lt; ", "; }
      std::cout &lt;&lt; '\n';
    } else {
      std::cerr &lt;&lt; "syntax error\n";
    }
  
    Record record2;
    if (qi::phrase_parse(str.begin(), str.end(), rule2, qi::space, record2)) {
      std::cout &lt;&lt; record2.id &lt;&lt; ": ";
      for (const auto&amp; value : record2.values) { std::cout &lt;&lt; value &lt;&lt; ", "; }
      std::cout &lt;&lt; '\n';
    } else {
      std::cerr &lt;&lt; "syntax error\n";
    }
  }
  </code></pre>
  
  <p><a href="http://coliru.stacked-crooked.com/a/f11b90c4dc24d85f">Live on Coliru</a></p>
  
  <pre><code>1: 2, 3, 4, 
  1: 2, 
  </code></pre>
  
  <p><code>rule1</code> and <code>rule2</code> are different only in that <code>rule1</code> uses the list operator (<code>(qi::int_ % ',')</code>) and <code>rule2</code> uses its expanded form (<code>(qi::int_ &gt;&gt; *(',' &gt;&gt; qi::int_))</code>). However, <code>rule1</code> produced <code>1: 2, 3, 4,</code> (as expected) and  <code>rule2</code> produced <code>1: 2,</code>. I cannot understand the result of <code>rule2</code>: 1) why is it different from that of <code>rule1</code> and 2) why were <code>3</code> and <code>4</code> not included in <code>record2.values</code> even though <code>phrase_parse</code> returned true somehow?</p>