combine v0.9.6 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

Functions

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

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

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

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

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

This parser will fail with the given error message

This parser will fail fatally with the given error message

Applies a parser and then verifies that the remaining input allows other_parser to succeed

Applies a parser if and only if predicate_parser fails

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

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

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

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

Applies a transformation function to the result of the given parser. If the result returned is of the form {:error, reason}, the parser will fail with that reason

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

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

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

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

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

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

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

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

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

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

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

Applies parser if possible, ignores the result

Applies parser zero or more times, ignores the result

Applies parser one or more times, ignores the result

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

This parser will fail with no error

Types

parser()
parser() :: Combine.parser
predicate()
predicate() :: (term -> boolean)
previous_parser()
previous_parser() :: Combine.previous_parser
transform()
transform() :: (term -> term)
transform2()
transform2() :: (term, term -> term)

Functions

between(parser \\ nil, parser1, parser2, parser3)

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]
both(parser \\ nil, 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.

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]
choice(parser \\ nil, parsers)
choice(previous_parser, [parser]) :: parser

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"]
either(parser \\ nil, 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.

Example

iex> import Elixir.Combine.Parsers.Base
iex> import Combine.Parsers.Text
...> Combine.parse("1234", either(float(), integer()))
[1234]
eof(parser \\ nil)

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())
[" "]
fail(parser \\ nil, message)

This parser will fail with the given error message.

fatal(parser \\ nil, message)

This parser will fail fatally with the given error message.

followed_by(parser \\ nil, parser, other_parser)
followed_by(previous_parser, parser, parser) :: parser

Applies a parser and then verifies that the remaining input allows other_parser to succeed.

This allows lookahead without mutating the parser state

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = letter() |> followed_by(letter())
...> Combine.parse("AB", parser)
["A"]
if_not(parser \\ nil, predicate_parser, parser)

Applies a parser if and only if predicate_parser fails.

This helps conditional parsing.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> parser = if_not(letter(), char())
...> Combine.parse("^", parser)
["^"]
ignore(parser \\ nil, 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.

Example

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

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."}
many(parser \\ nil, parser)

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 \\ nil, parser)

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"]]
...> Combine.parse("abc", many1(ignore(char())))
[[]]
...> Combine.parse("12abc", digit() |> digit() |> many1(ignore(char())))
[1, 2, []]
map(parser \\ nil, parser, transform)

Applies a transformation function to the result of the given parser. If the result returned is of the form {:error, reason}, the parser will fail with that reason.

Example

iex> import Elixir.Combine.Parsers.Base
...> import Combine.Parsers.Text
...> Combine.parse("1234", map(integer(), &(&1 * 2)))
[2468]
none_of(parser \\ nil, parser, items)
none_of(previous_parser, parser, Range.t | list) :: parser

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"]
...> parser = upper() |> none_of(char(), ["i", "I"])
...> Combine.parse("Hello", parser)
["H", "e"]
one_of(parser \\ nil, parser, items)
one_of(previous_parser, parser, Range.t | list) :: parser

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"]
...> parser = upper() |> one_of(char(), ["i", "I"])
...> Combine.parse("Hi", parser)
["H", "i"]
option(parser \\ nil, parser)

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"]
pair_both(parser \\ nil, parser1, parser2)

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_left(parser \\ nil, parser1, parser2)

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_right(parser \\ nil, parser1, parser2)
pair_right(previous_parser, parser, parser) :: parser

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]
pipe(parser \\ nil, 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.

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]
satisfy(parser \\ nil, 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.

Example

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

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_by1(parser \\ nil, parser1, parser2)

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]]
sequence(parser \\ nil, parsers)
sequence(previous_parser, [parser]) :: parser

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]]
...> Combine.parse("123-234", sequence([integer(), char()]) |> map(sequence([integer()]), fn [x] -> x * 2 end))
[[123, "-"], 468]
skip(parser \\ nil, parser)

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_many(parser \\ nil, parser)
skip_many(previous_parser, parser) :: parser

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_many1(parser \\ nil, parser)
skip_many1(previous_parser, parser) :: parser

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."}
times(parser \\ nil, parser, n)
times(previous_parser, parser, pos_integer) :: parser

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]]
zero(parser \\ nil)

This parser will fail with no error.