combine v0.10.0 Combine.Parsers.Base View Source

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.

Link to this section 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

Link to this section Types

Link to this type predicate() View Source
predicate() :: (term -> boolean)
Link to this type previous_parser() View Source
previous_parser() :: Combine.previous_parser
Link to this type transform() View Source
transform() :: (term -> term)
Link to this type transform2() View Source
transform2() :: (term, term -> term)

Link to this section Functions

Link to this function between(parser \\ nil, parser1, parser2, parser3) View Source

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]
Link to this function both(parser \\ nil, parser1, parser2, transform) View Source

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]
Link to this function choice(parser \\ nil, parsers) View Source
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"]
Link to this function either(parser \\ nil, parser1, parser2) View Source

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]

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())
[" "]

This parser will fail with the given error message.

This parser will fail fatally with the given error message.

Link to this function followed_by(parser \\ nil, parser, other_parser) View Source
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"]
Link to this function if_not(parser \\ nil, predicate_parser, parser) View Source

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)
["^"]
Link to this function ignore(parser \\ nil, parser) View Source

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", "!"]
Link to this function label(parser \\ nil, parser, name) View Source

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."}

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()))
[[]]
Link to this function many1(parser \\ nil, parser) View Source

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, []]
Link to this function map(parser \\ nil, parser, transform) View Source

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]
Link to this function none_of(parser \\ nil, parser, items) View Source
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"]
Link to this function one_of(parser \\ nil, parser, items) View Source
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"]
Link to this function option(parser \\ nil, parser) View Source

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"]
Link to this function pair_both(parser \\ nil, parser1, parser2) View Source

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}]
Link to this function pair_left(parser \\ nil, parser1, parser2) View Source

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]
Link to this function pair_right(parser \\ nil, parser1, parser2) View Source
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]
Link to this function pipe(parser \\ nil, parsers, transform) View Source

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]
Link to this function satisfy(parser \\ nil, parser, predicate) View Source

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"]
Link to this function sep_by(parser \\ nil, parser1, parser2) View Source

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(", ")))
[[]]
Link to this function sep_by1(parser \\ nil, parser1, parser2) View Source

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]]
Link to this function sequence(parser \\ nil, parsers) View Source
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]

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()))
[]
Link to this function skip_many(parser \\ nil, parser) View Source
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()))
[]
Link to this function skip_many1(parser \\ nil, parser) View Source
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."}
Link to this function times(parser \\ nil, parser, n) View Source
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]]

This parser will fail with no error.