Ergo.Context (ergo v0.3.1)

Ergo.Context defines the Context record type and functions to create and manipulate them.

Fields

  • status

When a parser returns it either sets status to :ok to indicate that it was successful or to a tuple {:error, :error_atom} where error_atom is an atom indiciting the specific type of error. It may optionally set the message field to a human readable message.

  • message

A human readable version of any error raised.

  • input

The binary input being parsed.

  • index

Represents the position in the input which has been read so far. Initially 0 it increments for each character processed.

  • line

Represents the current line of the input. Initially 1 it increments whenever a is read from the input.

  • col

Represents the current column of the input. Initially 1 it is incremented every time a character is read from the input and automatically resets whenever a is read.

  • char

Represents the last character read from the input.

  • ast

Represents the current data structure being built from the input.

Link to this section Summary

Functions

Because we build ASTs using lists they end up in reverse order. This method reverses the AST back to in-parse-order

Where an AST has been built from individual characters and needs to be converted to a string

Called to perform an arbitrary transformation on the AST value of a Context.

The ignore parser matches but returns a nil for the AST. Parsers like sequence accumulate these nil values. Call this function to remove them

Returns a newly initialised Context with an empty input.

Returns a newly initialised Context with input set to the string passed in.

Reads the next character from the input of the passed in Context.

Examples

iex> context = Context.new("Hello")
...> Context.peek(context)
%Context{status: :ok, char: ?H, ast: ?H, input: "ello", index: 1, line: 1, col: 2}

iex> context = Context.new()
...> Context.peek(context)
%Context{status: {:error, :unexpected_eoi}, message: "Unexpected end of input", index: 0, line: 1, col: 1}

Clears the value of the status and ast fields to ensure that the wrong status information cannot be returned from a child parser.

Link to this section Functions

Link to this function

ast_in_parsed_order(ctx)

Because we build ASTs using lists they end up in reverse order. This method reverses the AST back to in-parse-order

Examples

iex> context = Ergo.Context.new()
...> context = %{context | ast: [4, 3, 2, 1]}
...> Context.ast_in_parsed_order(context)
%Context{ast: [1, 2, 3, 4]}
Link to this function

ast_to_string(ctx)

Where an AST has been built from individual characters and needs to be converted to a string

Examples

iex> context = Ergo.Context.new()
iex> context = %{context | ast: [?H, ?e, ?l, ?l, ?o]}
iex> Context.ast_to_string(context)
%Context{ast: "Hello"}
Link to this function

ast_transform(ctx, fun)

Called to perform an arbitrary transformation on the AST value of a Context.

Examples

iex> alias Ergo.Context
iex> context = Context.new()
iex> context = %{context | ast: "Hello World"}
iex> Context.ast_transform(context, &Function.identity/1)
%Context{ast: "Hello World"}

iex> alias Ergo.Context
iex> context = Context.new()
iex> context = %{context | ast: "Hello World"}
iex> Context.ast_transform(context, &String.length/1)
%Context{ast: 11}

iex> alias Ergo.Context
iex> context = Context.new()
iex> context = %{context | ast: "Hello World"}
iex> Context.ast_transform(context, nil)
%Context{ast: "Hello World"}
Link to this function

ast_without_ignored(ctx)

The ignore parser matches but returns a nil for the AST. Parsers like sequence accumulate these nil values. Call this function to remove them

Examples

iex> context = Ergo.Context.new()
...> context = %{context | ast: ["Hello", nil, "World", nil]}
...> Context.ast_without_ignored(context)
%Context{ast: ["Hello", "World"]}

Returns a newly initialised Context with an empty input.

Examples

iex> Context.new() %Context{}

Link to this function

new(input, debug \\ false)

Returns a newly initialised Context with input set to the string passed in.

Examples:

iex> Context.new("Hello World") %Context{status: :ok, input: "Hello World", line: 1, col: 1, index: 0}

Link to this function

next_char(context)

Reads the next character from the input of the passed in Context.

If the input is empty returns status: {:error, :unexpected_eoi}.

Otherwise returns a new Context setting char to the character read and incrementing positional variables such as index, line, and column appropriately.

Examples

iex> Context.next_char(Context.new()) %Context{status: {:error, :unexpected_eoi}, message: "Unexpected end of input"}

iex> Context.next_char(Context.new("Hello World")) %Context{status: :ok, input: "ello World", char: ?H, ast: ?H, index: 1, line: 1, col: 2}

Examples

iex> context = Context.new("Hello")
...> Context.peek(context)
%Context{status: :ok, char: ?H, ast: ?H, input: "ello", index: 1, line: 1, col: 2}

iex> context = Context.new()
...> Context.peek(context)
%Context{status: {:error, :unexpected_eoi}, message: "Unexpected end of input", index: 0, line: 1, col: 1}
Link to this function

reset_status(ctx)

Clears the value of the status and ast fields to ensure that the wrong status information cannot be returned from a child parser.

Examples

iex> context = Context.new("Hello World")
iex> context = %{context | status: {:error, :inexplicable_error}, ast: true}
iex> context = Context.reset_status(context)
iex> assert %Context{status: :ok, ast: nil} = context