Combine.Parsers.Base

This module defines common abstract parsers, i.e. ignore, repeat, many, etc. To use them, just add import Combine.Parsers.Base to your module, or reference them directly.

Summary

between(parser1, parser2, parser3)

Applies parser1, parser2, and parser3 in sequence, returning the result of parser2

between(parser1, parser2, parser3, parser4)

Same as between/3, but acts as a combinator

both(parser1, parser2, transform)

Applies parser1 and parser2 in sequence, then sends their results to the given function to be transformed. The transformed value is then returned as the result of this parser

both(parser1, parser2, parser3, transform)

Same as both/3, but acts as a combinator

choice(parsers)

This parser is a generalized form of either which allows multiple parsers to be attempted

choice(parser, parsers)

Same as choice/1, but acts as a combinator

either(parser1, parser2)

Tries to apply parser1 and if it fails, tries parser2, if both fail, then this parser fails. Returns whichever result was successful otherwise

either(parser1, parser2, parser3)

Same as either/2, but acts as a combinator

eof()

This parser succeeds if the end of the input has been reached, otherwise it fails

eof(parser)

Same as eof/0, but acts as a combinator

fail(message)

This parser will fail with the given error message

fail(parser, message)

Same as fail/1, but acts as a combinator

fatal(message)

This parser will fail fatally with the given error message

fatal(parser, message)

Same as fatal/1, but acts as a combinator

ignore(parser)

This parser will apply the given parser to the input, and if successful, will ignore the parse result. If the parser fails, this one fails as well

ignore(parser1, parser2)

Same as ignore/1, but acts as a combinator. Given two parsers as arguments, it will apply the first one, and if successful, will apply the second one using the semantics of ignore/1. If either fail, the whole parser fails

label(parser, name)

Applies parser. If it fails, it's error is modified to contain the given label for easier troubleshooting

label(parser1, parser2, text)

Same as label/2, but acts as a combinator

many(parser)

Applies parser zero or more times. Returns results as a list

many1(parser)

Applies parser one or more times. Returns results as a list

map(parser, transform)

Applies a transformation function to the result of the given parser

map(parser1, parser2, transform)

Same as map/2, but acts as a combinator

none_of(parser, items)

Applies a parser and then verifies that the result is not contained in the provided list of matches

none_of(parser1, parser2, items)

Same as none_of/2, except acts as a combinator, applying the first parser to the input, and if successful, applying the second parser via none_of/2

one_of(parser, items)

Applies a parser and then verifies that the result is contained in the provided list of matches

one_of(parser1, parser2, items)

Same as one_of/2, except acts as a combinator, applying the first parser to the input, and if successful, applying the second parser via one_of/2

option(parser)

Applies parser if possible. Returns the parse result if successful or nil if not

option(parser1, parser2)

Same as option/1, but acts as a combinator

pair_both(parser1, parser2)

Applies both parser1 and parser2, returning both results as a tuple

pair_both(parser1, parser2, parser3)

Same as pair_both/2, but acts as a combinator

pair_left(parser1, parser2)

Applies both parser1 and parser2, returning the result of parser1 only

pair_left(parser1, parser2, parser3)

Same as pair_left/2, but acts as a combinator

pair_right(parser1, parser2)

Applies both parser1 and parser2, returning the result of parser2 only

pair_right(parser1, parser2, parser3)

Same as pair_right/2, but acts as a combinator

pipe(parsers, transform)

Applies each parser in parsers, then sends the results to the provided function to be transformed. The result of the transformation is the final result of this parser

pipe(parser, parsers, transform)

Same as pipe/2, but acts as a combinator

satisfy(parser, predicate)

This parser applies the given parser, and if successful, passes the result to the predicate for validation. If either the parser or the predicate assertion fail, this parser fails

satisfy(parser1, parser2, predicate)

Same as satisfy/2, except acts as a combinator, applying the first parser to the input, and if successful, applying the second parser via satisfy/2

sep_by(parser1, parser2)

Applies parser1 zero or more times, separated by parser2. Returns results of parser1 in a list

sep_by(parser1, parser2, parser3)

Same as sep_by/2, but acts as a combinator

sep_by1(parser1, parser2)

Applies parser1 one or more times, separated by parser2. Returns results of parser1 in a list

sep_by1(parser1, parser2, parser3)

Same as sep_by1/2, but acts as a combinator

sequence(parsers)

Applies a sequence of parsers and returns their results as a list

sequence(parser, parsers)

Same as sequence/1, but acts as a combinator

skip(parser)

Applies parser if possible, ignores the result

skip(parser1, parser2)

Same as skip/1, but acts as a combinator

skip_many(parser)

Applies parser zero or more times, ignores the result

skip_many(parser1, parser2)

Same as skip_many/1, but acts as a combinator

skip_many1(parser)

Applies parser one or more times, ignores the result

skip_many1(parser1, parser2)

Same as skip_many1/1, but acts as a combinator

times(parser, n)

Applies parser to the input n many times. Returns the result as a list

times(parser1, parser2, n)

Same as times/2, but acts as a combinator

zero()

This parser will fail with no error

zero(parser)

Same as zero/0, but acts as a combinator

Types

parser :: (Combine.ParserState.t -> Combine.ParserState.t)

predicate :: (term -> boolean)

transform :: (term -> term)

transform2 :: (term, term -> term)

Functions

between(parser1, parser2, parser3)

Specs:

Applies parser1, parser2, and parser3 in sequence, returning the result of parser2.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("(234)", between(char("("), integer, char(")")))
[234]
between(parser1, parser2, parser3, parser4)

Same as between/3, but acts as a combinator

both(parser1, parser2, transform)

Specs:

Applies parser1 and parser2 in sequence, then sends their results to the given function to be transformed. The transformed value is then returned as the result of this parser.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> to_int = fn ("-", y) -> y * -1; (_, y) -> y end
...> Combine.parse("1234-234", both(integer, both(char, integer, to_int), &(&1 + &2)))
[1000]
both(parser1, parser2, parser3, transform)

Same as both/3, but acts as a combinator

choice(parsers)

Specs:

This parser is a generalized form of either which allows multiple parsers to be attempted.

Example

iex> import Elixir.Combine.Parsers.Base
iex> import Combine.Parsers.Text
...> Combine.parse("test", choice([float, integer, word]))
["test"]
choice(parser, parsers)

Same as choice/1, but acts as a combinator.

either(parser1, parser2)

Specs:

Tries to apply parser1 and if it fails, tries parser2, if both fail, then this parser fails. Returns whichever result was successful otherwise.

Example

iex> import Elixir.Combine.Parsers.Base
iex> import Combine.Parsers.Text
...> Combine.parse("1234", either(float, integer))
[1234]
either(parser1, parser2, parser3)

Same as either/2, but acts as a combinator

eof()

Specs:

This parser succeeds if the end of the input has been reached, otherwise it fails.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("  ", spaces |> eof)
[" "]
eof(parser)

Same as eof/0, but acts as a combinator.

fail(message)

Specs:

This parser will fail with the given error message.

fail(parser, message)

Same as fail/1, but acts as a combinator

fatal(message)

Specs:

This parser will fail fatally with the given error message.

fatal(parser, message)

Same as fatal/1, but acts as a combinator.

ignore(parser)

Specs:

This parser will apply the given parser to the input, and if successful, will ignore the parse result. If the parser fails, this one fails as well.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = ignore(char("h"))
...> Combine.parse("h", parser)
[]
ignore(parser1, parser2)

Same as ignore/1, but acts as a combinator. Given two parsers as arguments, it will apply the first one, and if successful, will apply the second one using the semantics of ignore/1. If either fail, the whole parser fails.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = char("h") |> char("i") |> ignore(space) |> char("!")
...> Combine.parse("hi !", parser)
["h", "i", "!"]
label(parser, name)

Specs:

Applies parser. If it fails, it's error is modified to contain the given label for easier troubleshooting.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("abc", label(integer, "year"))
{:error, "Expected `year` at line 1, column 1."}
label(parser1, parser2, text)

Same as label/2, but acts as a combinator.

many(parser)

Specs:

Applies parser zero or more times. Returns results as a list.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("abc", many(char))
[["a", "b", "c"]]
...> Combine.parse("", many(char))
[[]]
many1(parser)

Specs:

Applies parser one or more times. Returns results as a list.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("abc", many1(char))
[["a", "b", "c"]]
map(parser, transform)

Specs:

Applies a transformation function to the result of the given parser.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("1234", map(integer, &(&1 * 2)))
[2468]
map(parser1, parser2, transform)

Same as map/2, but acts as a combinator.

none_of(parser, items)

Applies a parser and then verifies that the result is not contained in the provided list of matches.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = none_of(char, ?a..?z |> Enum.map(&(<<&1::utf8>>)))
...> Combine.parse("ABC", parser)
["A"]
none_of(parser1, parser2, items)

Same as none_of/2, except acts as a combinator, applying the first parser to the input, and if successful, applying the second parser via none_of/2.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = upper |> none_of(char, ["i", "I"])
...> Combine.parse("Hello", parser)
["H", "e"]
one_of(parser, items)

Specs:

Applies a parser and then verifies that the result is contained in the provided list of matches.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = one_of(char, ?a..?z |> Enum.map(&(<<&1::utf8>>)))
...> Combine.parse("abc", parser)
["a"]
one_of(parser1, parser2, items)

Same as one_of/2, except acts as a combinator, applying the first parser to the input, and if successful, applying the second parser via one_of/2.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = upper |> one_of(char, ["i", "I"])
...> Combine.parse("Hi", parser)
["H", "i"]
option(parser)

Specs:

Applies parser if possible. Returns the parse result if successful or nil if not.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("Hi", option(integer) |> word)
[nil, "Hi"]
option(parser1, parser2)

Same as option/1, but acts as a combinator

pair_both(parser1, parser2)

Specs:

Applies both parser1 and parser2, returning both results as a tuple.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("-234", pair_both(char, integer))
[{"-", 234}]
pair_both(parser1, parser2, parser3)

Same as pair_both/2, but acts as a combinator.

pair_left(parser1, parser2)

Specs:

Applies both parser1 and parser2, returning the result of parser1 only.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("234-", pair_left(integer, char))
[234]
pair_left(parser1, parser2, parser3)

Same as pair_left/2, but acts as a combinator.

pair_right(parser1, parser2)

Specs:

Applies both parser1 and parser2, returning the result of parser2 only.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("-234", pair_right(char, integer))
[234]
pair_right(parser1, parser2, parser3)

Same as pair_right/2, but acts as a combinator.

pipe(parsers, transform)

Specs:

Applies each parser in parsers, then sends the results to the provided function to be transformed. The result of the transformation is the final result of this parser.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("123", pipe([digit, digit, digit], fn digits -> {n, _} = Integer.parse(Enum.join(digits)); n end))
[123]
pipe(parser, parsers, transform)

Same as pipe/2, but acts as a combinator.

satisfy(parser, predicate)

Specs:

This parser applies the given parser, and if successful, passes the result to the predicate for validation. If either the parser or the predicate assertion fail, this parser fails.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = satisfy(char, fn x -> x == "H" end)
...> Combine.parse("Hi", parser)
["H"]
satisfy(parser1, parser2, predicate)

Same as satisfy/2, except acts as a combinator, applying the first parser to the input, and if successful, applying the second parser via satisfy/2.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = char("H") |> satisfy(char, fn x -> x == "i" end)
...> Combine.parse("Hi", parser)
["H", "i"]
sep_by(parser1, parser2)

Specs:

Applies parser1 zero or more times, separated by parser2. Returns results of parser1 in a list.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("1, 2, 3", sep_by(digit, string(", ")))
[[1, 2, 3]]
...> Combine.parse("", sep_by(digit, string(", ")))
[[]]
sep_by(parser1, parser2, parser3)

Same as sep_by/2, but acts as a combinator.

sep_by1(parser1, parser2)

Specs:

Applies parser1 one or more times, separated by parser2. Returns results of parser1 in a list.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("1, 2, 3", sep_by1(digit, string(", ")))
[[1, 2, 3]]
sep_by1(parser1, parser2, parser3)

Same as sep_by1/2, but acts as a combinator

sequence(parsers)

Specs:

Applies a sequence of parsers and returns their results as a list.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("123", sequence([digit, digit, digit]))
[[1, 2, 3]]
sequence(parser, parsers)

Same as sequence/1, but acts as a combinator.

skip(parser)

Specs:

Applies parser if possible, ignores the result.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("   abc", skip(spaces) |> word)
["abc"]
...> Combine.parse("", skip(spaces))
[]
skip(parser1, parser2)

Same as skip/1, but acts as a combinator

skip_many(parser)

Specs:

Applies parser zero or more times, ignores the result.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("   abc", skip_many(space) |> word)
["abc"]
...> Combine.parse("", skip_many(space))
[]
skip_many(parser1, parser2)

Same as skip_many/1, but acts as a combinator

skip_many1(parser)

Specs:

Applies parser one or more times, ignores the result.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("   abc", skip_many1(space) |> word)
["abc"]
...> Combine.parse("", skip_many1(space))
{:error, "Expected space, but hit end of input."}
skip_many1(parser1, parser2)

Same as skip_many1/1, but acts as a combinator

times(parser, n)

Specs:

Applies parser to the input n many times. Returns the result as a list.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("123", times(digit, 3))
[[1,2,3]]
times(parser1, parser2, n)

Same as times/2, but acts as a combinator

zero()

Specs:

This parser will fail with no error.

zero(parser)

Same as zero/0, but acts as a combinator.