party
Party: A simple parser combinator library. Party is pre-alpha and breaking changes should be expected in the near future.
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)
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 choice(ps: List(Parser(a, b))) -> Parser(a, b)
Parse with the first parser in the list that doesn’t fail.
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(alt(alphanum(), char("_"))))
return(Ident(pos, first <> string.concat(rest)))
}
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 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 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 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 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 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.