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

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
1 Like