Improve error handling

Use the rightmost-failure-position algorithm from [Bryan Ford's original PEG paper](http://www.bford.info/pub/lang/thesis.pdf) to better place the position of errors.

This requires a context struct to be threaded through the parse function, adding a lifetime which prevents the  lifetime elision we rely on to allow `&str` return values.