Ergo.Meta (Ergo v0.9.9)
The Meta parsers are not really parsers at all but operate within the parsing framework.
All Meta parsers are combinators that accept a parser and either report on or modify its operation.
Link to this section Summary
Functions
The around
parser is a pass-thru parser that can be used to run code before or
after another parser. For example to inspect the context or output additional
debugging information.
commit/0
is not technically a parser, rather a sentinel that a sequence
can use to determine whether an error is fatal or not
The failed
parser is a combinator that invokes a parser and if the parser fails
runs the given function on the resulting context. This can be used to output additional
debugging information where failure was unexpected.
Link to this section Functions
around(parser, opts \\ [])
The around
parser is a pass-thru parser that can be used to run code before or
after another parser. For example to inspect the context or output additional
debugging information.
Specify on of around(parser, before: fn ctx -> … end) around(parser, after: fn ctx, parsed_ctx -> … end) around(parser, before: fn ctx -> … end, after: fn ctx, parsed_ctx -> … end)
Note that where both before:
and after:
are specified, the after function will
receive both the context before and after parsing as separate parameters.
If neither of before:
nor around:
are specified an error will be raised.
Examples
iex> alias Ergo.{Context, Parser}
iex> import Ergo.Meta
iex> null_parser = Parser.combinator(:null, "null_parser", fn %Context{} = ctx -> ctx end)
iex> assert_raise(RuntimeError, fn -> Ergo.parse(around(null_parser), "") end)
iex> alias Ergo.{Context, Parser}
iex> import Ergo.Meta
iex> null_parser = Parser.combinator(:null, "null_parser", fn %Context{} = ctx -> ctx end)
iex> parser = around(null_parser, before: fn _ctx -> send(self(), :before) end)
iex> Ergo.parse(parser, "")
iex> assert_receive :before
iex> alias Ergo.{Context, Parser}
iex> import Ergo.Meta
iex> null_parser = Parser.combinator(:null, "null_parser", fn %Context{} = ctx -> ctx end)
iex> parser = around(null_parser, after: fn _ctx, _new_ctx -> send(self(), :after) end)
iex> Ergo.parse(parser, "")
iex> assert_receive :after
iex> alias Ergo.{Context, Parser}
iex> import Ergo.Meta
iex> null_parser = Parser.combinator(:null, "null_parser", fn %Context{} = ctx -> ctx end)
iex> parser = around(null_parser, before: fn _ctx -> send(self(), :before) end, after: fn _ctx, _new_ctx -> send(self(), :after) end)
iex> Ergo.parse(parser, "")
iex> assert_receive :before
iex> assert_receive :after
commit()
commit/0
is not technically a parser, rather a sentinel that a sequence
can use to determine whether an error is fatal or not
failed(parser, fail_fn, opts \\ [])
The failed
parser is a combinator that invokes a parser and if the parser fails
runs the given function on the resulting context. This can be used to output additional
debugging information where failure was unexpected.
Examples
iex> alias Ergo.Parser
iex> import Ergo.Meta
iex> failing_parser = Parser.combinator(:err, "err_parser", fn ctx -> %{ctx | status: {:error, :unfathomable_error}} end)
iex> parser = failed(failing_parser, fn _pre_ctx, _post_ctx, _parser -> send(self(), :failed) end)
iex> Ergo.parse(parser, "")
iex> assert_received :failed