jayferd/parsimmon — pull request #3 by laughinghan (2013-04-06 09:50:14+00:00)
Title: Better error messages: furthest

If a parser fails, always use the error message from the branch that advanced the furthest into the stream.

Ignore the first 5 commits, those are just #2.

Check out the nice error messages this gives for a toy "real world" example, an s-expression parser:
```js
var atom = regex(/^[^()\s]+/);
var sexpr = string('(').then(function() { return list; }).skip(string(')'));
var list = optWhitespace.then(atom.or(sexpr)).skip(optWhitespace).many();

assert.deepEqual(list.parse('(a b) (c ((() d)))'), [['a', 'b'], ['c', [[[], 'd']]]]);

assert.throws(function() { list.parse('(a b ()) c)'); },
partialEquals("Parse Error: expected EOF at character 10, got '...)'\n parsing: '(a b ()) c)'"));
assert.throws(function() { list.parse('(a (b)) (() c'); },
partialEquals("Parse Error: expected ')', got the end of the string\n parsing: '(a (b)) (() c'"));
```
Before, the `.many().skip(eof)` would result in `expected EOF at character 0` for both.

I'm not ecstatic about how the code turned out; though the HOFs definitely cleaned up what I started with, it still feels like there's some duplication between `.or()`, `.then()`, and `.many()` in having to call `furthestFailure{,Success}` at all, almost like there should be some kind of HOF on the combinators that would just handle that stuff for you (note that what `.many()` does is basically equivalent to inlining `furthestFailure()`.

It's not too bad since it's restricted to the primitive or optimized combinators; honestly the most annoying thing is writing good, easy-to-understand minimal test cases of the edge cases where the wrong error message gets thrown, which is why I haven't finished `.times()`, wanna take a stab at it?