Ergo.Terminals (Ergo v0.9.9)

Ergo.Terminals contains the terminal parsers, which are those parsers not parameterized with other parsers and therefore work more at the level of text than structure.

Link to this section Summary

Functions

The alpha/0 parser accepts a single character in the range a..z or A..Z.

The any/0 parser matches any character.

The char/1 parser is a terminal parser that matches a specific character.

The delimited_text/2 parser matches a sequence of text delimited open_char and close_char. Because it is expected that open_char may appear multiple times within the sequence it balances the tokens to ensure the right number of closing tokens is matched.

The digit/0 parser accepts a character in the range of 0..9

The eoi parser is a terminal parser that checks whether the input has been fully consumed. If there is input remaining to be parsed the return context status is set to :error.

The literal/1 parser matches the specified string character by character.

The not_char matcher accepts a char or a list of chars and will match any char that is not in the list.

The wc/0 parser parses a word character and is analagous to the \w regular expression.

The ws/0 parser accepts a white space character and is equivalent to the \s regular expression.

Link to this section Functions

Link to this function

alpha(options \\ [])

The alpha/0 parser accepts a single character in the range a..z or A..Z.

Examples

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = alpha()
iex> assert %Context{status: :ok, input: "ello World", ast: ?H, index: 1, line: 1, col: 2} = Ergo.parse(parser, "Hello World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = alpha()
iex> assert %Context{status: :ok, input: "llo World", ast: ?e, index: 1, line: 1, col: 2} = Ergo.parse(parser, "ello World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = alpha()
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Expected: [|a|..|z|, |A|..|Z|] Actual: | |"}]}, input: " World"} = Ergo.parse(parser, " World")

The any/0 parser matches any character.

Examples

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = any()
iex> assert %Context{status: :ok, ast: ?H} = Ergo.parse(parser, "H")
iex> assert %Context{status: :ok, ast: ?e} = Ergo.parse(parser, "e")
iex> assert %Context{status: :ok, ast: ?!} = Ergo.parse(parser, "!")
iex> assert %Context{status: :ok, ast: ?0} = Ergo.parse(parser, "0")
Link to this function

char(c, opts \\ [])

The char/1 parser is a terminal parser that matches a specific character.

Examples

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char(?H)
iex> assert %Context{status: :ok, ast: ?H, input: "ello World", index: 1, line: 1, col: 2} = Ergo.parse(parser, "Hello World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char(?h)
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Expected: |h| Actual: |H|"}]}, input: "Hello World"} = Ergo.parse(parser, "Hello World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char(?H)
iex> assert %Context{status: {:error, [{:unexpected_eoi, {1, 1}, "Unexpected end of input"}]}} = Ergo.parse(parser, "")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char(?A..?Z)
iex> assert %Context{status: :ok, ast: ?H, input: "ello World", index: 1, line: 1, col: 2} = Ergo.parse(parser, "Hello World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char(?a..?z)
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Expected: |a|..|z| Actual: |H|"}]},input: "Hello World"} = Ergo.parse(parser, "Hello World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char(?A..?Z)
iex> assert %Context{status: {:error, [{:unexpected_eoi, {1, 1}, "Unexpected end of input"}]}} = Ergo.parse(parser, "")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char([?a..?z, ?A..?Z])
iex> assert %Context{status: :ok, ast: ?H, input: "ello World", index: 1, line: 1, col: 2} = Ergo.parse(parser, "Hello World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char([?a..?z, ?A..?Z])
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Expected: [|a|..|z|, |A|..|Z|] Actual: |0|"}]}, input: "0000"} = Ergo.parse(parser, "0000")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char(-?0)
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Should not have matched |0|"}]}, input: "0000"} = Ergo.parse(parser, "0000")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = char(-?a)
iex> assert %Context{status: :ok, input: "000", ast: ?0, index: 1, col: 2} = Ergo.parse(parser, "0000")
Link to this function

delimited_text(open_char, close_char, opts \\ [])

The delimited_text/2 parser matches a sequence of text delimited open_char and close_char. Because it is expected that open_char may appear multiple times within the sequence it balances the tokens to ensure the right number of closing tokens is matched.

Examples

  iex> alias Ergo
  iex> alias Ergo.Context
  iex> import Ergo.Terminals
  iex> parser = delimited_text(?{, ?})
  iex> assert %Context{status: :ok, ast: "{return {foo: \"bar\", bar: {baz: \"quux\"}};}", input: ""} = Ergo.parse(parser, "{return {foo: \"bar\", bar: {baz: \"quux\"}};}")
  iex> assert %Context{status: :ok, ast: "{function b(y) {return x + y;}; return b;}", input: "foo"} = Ergo.parse(parser, "{function b(y) {return x + y;}; return b;}foo")
Link to this function

digit(options \\ [])

The digit/0 parser accepts a character in the range of 0..9

Examples

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = digit()
iex> assert %Context{status: :ok, ast: ?0, input: "000", index: 1, line: 1, col: 2} = Ergo.parse(parser, "0000")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> import Ergo.Terminals
iex> parser = digit()
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Expected: |0|..|9| Actual: |A|"}]}, input: "AAAA", index: 0, line: 1, col: 1} = Ergo.parse(parser, "AAAA")

iex> alias Ergo.{Context, Parser}
iex> import Ergo.Terminals
iex> ctx = Context.new("")
iex> parser = digit()
iex> assert %Context{status: {:error, [{:unexpected_eoi, {1, 1}, "Unexpected end of input"}]}, input: "", index: 0, line: 1, col: 1} = Parser.invoke(ctx, parser)

The eoi parser is a terminal parser that checks whether the input has been fully consumed. If there is input remaining to be parsed the return context status is set to :error.

Examples

iex> alias Ergo.{Context, Parser}
iex> import Ergo.Terminals
iex> ctx = Context.new("")
iex> assert %Context{status: :ok, ast: nil} = Parser.invoke(ctx, eoi())

iex> alias Ergo.{Context, Parser}
iex> import Ergo.Terminals
iex> ctx = Context.new("Hello World")
iex> assert %Context{status: {:error, [{:not_eoi, {1, 1}, "Input not empty: Hello World"}]}, input: "Hello World"} = Parser.invoke(ctx, eoi())
Link to this function

literal(s, opts \\ [])

The literal/1 parser matches the specified string character by character.

Examples

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = literal("Hello")
iex> assert %Context{status: :ok, input: " World", ast: "Hello", index: 5, line: 1, col: 6} = Ergo.parse(parser, "Hello World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = literal("Hello")
iex> assert %Context{status: {:error, [{:bad_literal, {1, 5}, "literal<Hello>"}, {:unexpected_char, {1, 5}, "Expected: |o| Actual: |x|"}]}, input: "x World", index: 4, line: 1, col: 5} = Ergo.parse(parser, "Hellx World")
Link to this function

not_char(c_or_l, opts \\ [])

The not_char matcher accepts a char or a list of chars and will match any char that is not in the list.

Examples

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = not_char(?0)
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Should not have matched |0|"}]}, input: "0000"} = Ergo.parse(parser, "0000")
iex> assert %Context{status: :ok, ast: ?1} = Ergo.parse(parser, "1111")
iex> parser = not_char([?{, ?}])
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Should not have matched |{|"}]}, input: "{}"} = Ergo.parse(parser, "{}")
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Should not have matched |}|"}]}, input: "}"} = Ergo.parse(parser, "}")

The wc/0 parser parses a word character and is analagous to the \w regular expression.

Examples

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = wc()
iex> assert %Context{status: :ok, ast: ?H, input: "ello World", index: 1, col: 2} = Ergo.parse(parser, "Hello World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = wc()
iex> assert %Context{status: :ok, ast: ?0, input: " World", index: 1, col: 2} = Ergo.parse(parser, "0 World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = wc()
iex> assert %Context{status: :ok, ast: ?_, input: "Hello", index: 1, col: 2} = Ergo.parse(parser, "_Hello")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = wc()
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Expected: [|0|..|9|, |a|..|z|, |A|..|Z|, |_|] Actual: | |"}]}, input: " Hello"} = Ergo.parse(parser, " Hello")
Link to this function

ws(options \\ [])

The ws/0 parser accepts a white space character and is equivalent to the \s regular expression.

Examples

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = ws()
iex> assert %Context{status: :ok, ast: ?\s, input: "World", index: 1, line: 1, col: 2}= Ergo.parse(parser, " World")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = ws()
iex> assert %Context{status: :ok, ast: ?\t, input: "World", index: 1, line: 1, col: 2} = Ergo.parse(parser, "\tWorld")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = ws()
iex> assert %Context{status: :ok, ast: ?\n, input: "World", index: 1, line: 2, col: 1} = Ergo.parse(parser, "\nWorld")

iex> alias Ergo.Context
iex> import Ergo.Terminals
iex> parser = ws()
iex> assert %Context{status: {:error, [{:unexpected_char, {1, 1}, "Expected: [| |, |\t|, |\r|, |\n|, |\v|] Actual: |H|"}]}, input: "Hello World"} = Ergo.parse(parser, "Hello World")