In actual code it's not much difference, e.g.:
while (test("-")) { element() }
vs. do { element(); } while (test("-")) while (test("-")) { element() }
vs. do { element(); } while (test("-"))I have written recursive descent parsers in the past, and if I remember correctly, the way I set things up, I had to handle leading list elements specially. It's possible that this was unnecessary and I was simply blinded to a simpler way of doing things because I was following the EBNF too strictly.
Edit: I noticed that we're not actually accounting for an empty list here. That makes things slightly more complex:
comma-separated = [ element, *(",", element) ];
Your code would need to test if there is an element or a list terminator before processing the element.