anchor.diff:  current_pos(#ts{ last     = T })       -> end_pos(pos(T)).
   
   -spec mk_error(#ts{}, term()) -> error().
  -mk_error(Ts, Err) -> {current_pos(Ts), Err}.
  +mk_error(Ts, Err) ->
  +    {current_pos(Ts), Err}.
  +
  +-spec unexpected_token_error(#ts{}, token()) -> error().
  +unexpected_token_error(Ts, T) ->
  +    mk_error(Ts, io_lib:format("Unexpected token ~p", [tag(T)])).
   
   %% Get the next token from a token stream. Inserts layout tokens if necessary.
   -spec next_token(#ts{}) -> false | {token(), #ts{}}.
  
positive.code: -spec parse(parser(A), tokens()) -> {ok, A} | {error, term()}.
  parse(P, S) ->
    case parse1(apply_p(P, fun(X) -> {return_plus, X, {fail, no_error}} end), S) of
      {[], {Pos, Err}} -> {error, {Pos, parse_error, lists:flatten(Err)}};
      {[A], _}         -> {ok, A};
      {As, _}          -> {error, {{1, 1}, ambiguous_parse, As}}
    end.
  
  %% -- Derived combinators ----------------------------------------------------
  
  
negative.code: parse1({return_plus, X, P}, Ts, Acc,  Err) ->
      case next_token(Ts) of
          false  -> parse1(P, Ts, [X | Acc], Err);
          {T, _} -> parse1(P, Ts, Acc, unexpected_token_error(Ts, T))
      end;
  parse1({fail, Err}, Ts, Acc, Err1) ->
      Err2 = case next_token(Ts) of
               {T, _} -> unexpected_token_error(Ts, T);
               _      -> no_error
             end,
      {Acc, add_error(add_error(mk_error(Ts, Err), Err2), Err1)}.
  
  %% Get the current position of the token stream. This is the position of the next token if any, and
  %% the line after the last token if at the end of the stream.
  