party

A simple parser combinator library. Party is stable, though breaking changes might come in a far-future 2.0 or 3.0 release.

Types

The custom error type for the parser, which can itself be parameterized by a user-defined error type. The user-defined error type is useful for, for example, adding a int.parse call into your parser pipeline. See try for using this feature.

pub type ParseError(e) {
  Unexpected(pos: Position, error: String)
  UserError(pos: Position, error: e)
}

Constructors

  • Unexpected(pos: Position, error: String)
  • UserError(pos: Position, error: e)

The parser type, parameterized by the type it parses and the user-defined error type it can return.

pub opaque type Parser(a, e)

The type for positions within a string.

pub type Position {
  Position(row: Int, col: Int)
}

Constructors

  • Position(row: Int, col: Int)

Functions

pub fn all(ps: List(Parser(a, b))) -> Parser(a, b)

Do each parser in the list, returning the result of the last parser.

pub fn alphanum() -> Parser(String, a)

Parse an alphanumeric character.

pub fn any_char() -> Parser(String, a)

Parse a single character.

pub fn between(
  open: Parser(a, b),
  p: Parser(c, b),
  close: Parser(d, b),
) -> Parser(c, b)

Parse open, followed by p and close. Returns the value returned by p. The values returned by open and close are discarded.

pub fn char(c: String) -> Parser(String, a)

Parse a specific character.

pub fn choice(ps: List(Parser(a, b))) -> Parser(a, b)

Parse with the first parser in the list that doesn’t fail.

pub fn digit() -> Parser(String, a)

Parse a digit.

pub fn digits() -> Parser(String, a)

Parse a sequence of digits.

pub fn do(
  p: Parser(a, b),
  f: fn(a) -> Parser(c, b),
) -> Parser(c, b)

A monadic bind for pleasant interplay with gleam’s use syntax. example:

fn identifier() -> Parser(String, e) {
    use pos <- do(pos())
    use first <- do(lowercase_letter())
    use rest <- do(many(either(alphanum(), char("_"))))
    return(Ident(pos, first <> string.concat(rest)))
}
pub fn drop(
  p: Parser(a, b),
  f: fn() -> Parser(c, b),
) -> Parser(c, b)

A version of seq for pleasant interplay with gleam’s use syntax. example:

fn pair() -> Parser(#(String, String), e) {
    use a <- do(alphanum())
    use <- drop(char(","))
    use b <- do(alphanum())
    return(#(a, b))
}
pub fn either(p: Parser(a, b), q: Parser(a, b)) -> Parser(a, b)

Parse the first parser, or the second if the first fails.

pub fn end() -> Parser(Nil, a)

Parses successfully only when at the end of the input string.

pub fn error_map(p: Parser(a, b), f: fn(b) -> c) -> Parser(a, c)

Transform the user-defined error type with a user-provided conversion function.

pub fn fail() -> Parser(a, b)

Immediately fail regardless of the next input.

pub fn go(
  p: Parser(a, b),
  src: String,
) -> Result(a, ParseError(b))

Apply a parser to a string.

pub fn lazy(p: fn() -> Parser(a, b)) -> Parser(a, b)

Run a parser as normal, but the parser itself isn’t evaluated until it is used. This is needed for recursive grammars, such as E := n | E + E where n is a number. Example: lazy(digit) instead of digit().

pub fn letter() -> Parser(String, a)

Parse a lowercase or uppercase letter.

pub fn line() -> Parser(List(String), a)

Parse the rest of a line and return the array of parsed characters. The newline character at the end is discarded.

pub fn line_concat() -> Parser(String, a)

Parse the rest of a line and return the parsed characters as a String. The newline character at the end is discarded.

pub fn lowercase_letter() -> Parser(String, a)

Parse a lowercase letter.

pub fn many(p: Parser(a, b)) -> Parser(List(a), b)

Keep trying the parser until it fails, and return the array of parsed results. This cannot fail because it parses zero or more times!

pub fn many1(p: Parser(a, b)) -> Parser(List(a), b)

Keep trying the parser until it fails, and return the array of parsed results. This can fail, because it must parse successfully at least once!

pub fn many1_concat(p: Parser(String, a)) -> Parser(String, a)

Parse a certain string as many times as possible, returning everything that was parsed. This can fail, because it must parse successfully at least once!

pub fn many_concat(p: Parser(String, a)) -> Parser(String, a)

Parse a certain string as many times as possible, returning everything that was parsed. This cannot fail because it parses zero or more times!

pub fn map(p: Parser(a, b), f: fn(a) -> c) -> Parser(c, b)

Do p, then apply f to the result if it succeeded.

pub fn not(p: Parser(a, b)) -> Parser(Nil, b)

Negate a parser: if it succeeds, this fails, and vice versa. Example: seq(string("if"), not(either(alphanum(), char("_"))))

pub fn perhaps(p: Parser(a, b)) -> Parser(Result(a, Nil), b)

Try running a parser, but still succeed (with Error(Nil)) if it failed.

pub fn pos() -> Parser(Position, a)

Get the current parser position.

pub fn return(x: a) -> Parser(a, b)

A monadic return for pleasant interplay with gleam’s use syntax. see do for more details and an example. This is redundant if the last do is a map instead. But I prefer using it, stylistically.

pub fn run(
  p: Parser(a, b),
  src: List(String),
  pos: Position,
) -> Result(#(a, List(String), Position), ParseError(b))

ADVANCED (exposes the internals of party) Apply a parser to a list of graphemes (holding on to extra result info that party typically threads for you).

pub fn satisfy(
  when pred: fn(String) -> Bool,
) -> Parser(String, a)

Parse a character if it matches the predicate.

pub fn sep(
  parser: Parser(a, b),
  by s: Parser(c, b),
) -> Parser(List(a), b)

Parse a sequence separated by the given separator parser.

pub fn sep1(
  parser: Parser(a, b),
  by s: Parser(c, b),
) -> Parser(List(a), b)

Parse a sequence separated by the given separator parser. This only succeeds if at least one element of the sequence was parsed.

pub fn seq(p: Parser(a, b), q: Parser(c, b)) -> Parser(c, b)

Do the first parser, ignore its result, then do the second parser.

pub fn stateful_many(
  state: a,
  p: Parser(fn(a) -> #(b, a), c),
) -> Parser(#(List(b), a), c)

A many parser that also gets to update some state with each success

pub fn stateful_many1(
  state: a,
  p: Parser(fn(a) -> #(b, a), c),
) -> Parser(#(List(b), a), c)

A many1 parser that also gets to update some state with each success

pub fn string(s: String) -> Parser(String, a)

Parse an exact string of characters.

pub fn try(
  p: Parser(a, b),
  f: fn(a) -> Result(c, b),
) -> Parser(c, b)

Do p, the apply f to the result if it succeeded. f itself can fail with the user-defined error type, and if it does the result is a UserError with the error.

pub fn until(
  do p: Parser(a, b),
  until terminator: Parser(c, b),
) -> Parser(List(a), b)

Parse zero or more repetitions of a parser, collecting the results into a list. Stop when the terminator parser succeeds, even if the looping parser would also succeed. The terminator parser’s results are consumed and discarded. The main motivator for until is multiline comments ending in */, -->, -}, *), etc.

pub fn uppercase_letter() -> Parser(String, a)

Parse an uppercase letter.

pub fn whitespace() -> Parser(String, a)

Parse zero or more whitespace characters.

pub fn whitespace1() -> Parser(String, a)

Parse one or more whitespace characters.

Search Document