NimbleParsec return value

One thing I can’t seem to figure out from the NimbleParsec docs is what the elements in the :ok tuple represent. Consider this example from the docs

defmodule MyParser do
  import NimbleParsec

  defparsec :repeat_lower, repeat(ascii_char([?a..?z]))
end

MyParser.repeat_lower("abcd")
#=> {:ok, [?a, ?b, ?c, ?d], "", %{}, {1, 0}, 4}

MyParser.repeat_lower("1234")
#=> {:ok, [], "1234", %{}, {1, 0}, 0}

With some guessing, I can figure out some of the elements

  • :ok
  • [?a, ?b, ?c, ?d]: The data returned by the parser
  • "", The data after the matched data
  • %{}: A map of some kind of metadata…? I don’t see anything in the docs with this populated.
  • {1, 0}: No idea what the tuple is
  • 4: The number of parsed characters

Does anyone know what these are?

Returns {:ok, [token], rest, context, position, byte_offset} or
{:error, reason, rest, context, line, byte_offset} where position
describes the location of the #{name} (start position) as {line, offset_to_start_of_line}.
To column where the error occurred can be inferred from byte_offset - offset_to_start_of_line.
## Options
* :byte_offset - the byte offset for the whole binary, defaults to 0
* :line - the line and the byte offset into that line, defaults to {1, byte_offset}
* :context - the initial context value. It will be converted to a map

from here

Hm, what’s context?

EDIT: Ah, just saw your edit! I see where you found it. Annoying, that’s not in the docs. Here it is in the source

https://github.com/dashbitco/nimble_parsec/blob/dc1e2278349f4263eee2babd4432b30cff0e9210/lib/nimble_parsec/compiler.ex#L9-L22

Thanks!

Haven’t used context myself. Looks like it is for keeping some context around when doing traversals etc.

The docs can be found on the created function.

$> cat my_parser.exs
defmodule MyParser do
  import NimbleParsec

  defparsec :repeat_lower, repeat(ascii_char([?a..?z]))
end
$> iex
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Interactive Elixir (1.14.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Mix.install([ {:nimble_parsec, "~> 1.2"}])
:ok
iex(2)> c("my_parser.exs", ".")
[MyParser]
iex(3)> h MyParser.repeat_lower

                      def repeat_lower(binary, opts \\ [])

  @spec repeat_lower(binary(), keyword()) ::
          {:ok, [term()], rest, context, line, byte_offset}
          | {:error, reason, rest, context, line, byte_offset}
        when line: {pos_integer(), byte_offset},
             byte_offset: pos_integer(),
             rest: binary(),
             reason: String.t(),
             context: map()

Parses the given binary as repeat_lower.

Returns {:ok, [token], rest, context, position, byte_offset} or {:error,
reason, rest, context, line, byte_offset} where position describes the location
of the repeat_lower (start position) as {line, offset_to_start_of_line}.

To column where the error occurred can be inferred from byte_offset -
offset_to_start_of_line.

## Options

  • :byte_offset - the byte offset for the whole binary, defaults to 0
  • :line - the line and the byte offset into that line, defaults to {1,
    byte_offset}
  • :context - the initial context value. It will be converted to a map