nibble

Types

A dead end represents a the point where a parser that had committed down a path failed. It contains the position of the failure, the Error describing the failure, and the context stack for any parsers that had run.

pub type DeadEnd(tok, ctx) {
  DeadEnd(
    pos: Span,
    problem: Error(tok),
    context: List(Located(ctx)),
  )
}

Constructors

  • DeadEnd(
      pos: Span,
      problem: Error(tok),
      context: List(Located(ctx)),
    )
pub type Error(tok) {
  BadParser(String)
  Custom(String)
  EndOfInput
  Expected(String, got: tok)
  Unexpected(tok)
}

Constructors

  • BadParser(String)
  • Custom(String)
  • EndOfInput
  • Expected(String, got: tok)
  • Unexpected(tok)
pub type Located(ctx) {
  Located(pos: Span, context: ctx)
}

Constructors

  • Located(pos: Span, context: ctx)
pub type Loop(a, state) {
  Continue(state)
  Break(a)
}

Constructors

  • Continue(state)
  • Break(a)

The Parser type has three paramteres, let’s take a look at each of them:

Parser(a, tok, ctx)
//     ^            (1)
//        ^^^       (2)
//             ^^^  (3)
  1. a is the type of value that the parser knows how to produce. If you were writing a parser for a programming language, this might be your expression type.

  2. tok is the type of tokens that the parser knows how to consume. You can take a look at the Token type for a bit more info, but note that it’s not necessary for the token stream to come from nibble’s lexer.

  3. ctx is used to make error reporting nicer. You can place a parser into a custom context. When the parser runs the context gets pushed into a stack. If the parser fails you can see the context stack in the error message, which can make error reporting and debugging much easier!

pub opaque type Parser(a, tok, ctx)

Functions

pub fn any() -> Parser(a, a, b)
pub fn backtrackable(parser: Parser(a, b, c)) -> Parser(a, b, c)
pub fn commit(to a: a) -> Parser(a, b, c)
pub fn do(parser: Parser(a, b, c), f: fn(a) -> Parser(d, b, c)) -> Parser(
  d,
  b,
  c,
)
pub fn do_in(context: a, parser: Parser(b, c, a), f: fn(b) ->
    Parser(d, c, a)) -> Parser(d, c, a)
pub fn eof() -> Parser(Nil, a, b)
pub fn fail(message: String) -> Parser(a, b, c)
pub fn in(parser: Parser(a, b, c), context: c) -> Parser(a, b, c)
pub fn inspect(parser: Parser(a, b, c), message: String) -> Parser(
  a,
  b,
  c,
)

Run the given parser and then inspect it’s state.

pub fn lazy(parser: fn() -> Parser(a, b, c)) -> Parser(a, b, c)
pub fn list(parser: Parser(a, b, c), separator sep: Parser(
    d,
    b,
    c,
  )) -> Parser(List(a), b, c)
pub fn loop(init: a, step: fn(a) -> Parser(Loop(b, a), c, d)) -> Parser(
  b,
  c,
  d,
)
pub fn many(parser: Parser(a, b, c)) -> Parser(List(a), b, c)
pub fn many1(parser: Parser(a, b, c)) -> Parser(List(a), b, c)
pub fn map(parser: Parser(a, b, c), f: fn(a) -> d) -> Parser(
  d,
  b,
  c,
)
pub fn one_of(parsers: List(Parser(a, b, c))) -> Parser(a, b, c)
pub fn optional(parser: Parser(a, b, c)) -> Parser(
  Option(a),
  b,
  c,
)
pub fn or(parser: Parser(a, b, c), default: a) -> Parser(a, b, c)
pub fn replace(parser: Parser(a, b, c), with b: d) -> Parser(
  d,
  b,
  c,
)
pub fn return(a: a) -> Parser(a, b, c)
pub fn run(src: List(Token(a)), parser: Parser(b, a, c)) -> Result(
  b,
  List(DeadEnd(a, c)),
)
pub fn take_if(expecting: String, predicate: fn(a) -> Bool) -> Parser(
  a,
  a,
  b,
)
pub fn take_map(expecting: String, f: fn(a) -> Option(b)) -> Parser(
  b,
  a,
  c,
)
pub fn take_map_while(f: fn(a) -> Option(b)) -> Parser(
  List(b),
  a,
  c,
)
pub fn take_map_while1(expecting: String, f: fn(a) -> Option(b)) -> Parser(
  List(b),
  a,
  c,
)
pub fn take_until(predicate: fn(a) -> Bool) -> Parser(
  List(a),
  a,
  b,
)
pub fn take_until1(expecting: String, predicate: fn(a) -> Bool) -> Parser(
  List(a),
  a,
  b,
)
pub fn take_while(predicate: fn(a) -> Bool) -> Parser(
  List(a),
  a,
  b,
)

💡 This parser can succeed without consuming any input (if the predicate immediately fails). You can end up with an infinite loop if you’re not careful. Use take_while1 if you want to guarantee you take at least one token.

pub fn take_while1(expecting: String, predicate: fn(a) -> Bool) -> Parser(
  List(a),
  a,
  b,
)

💡 If this parser succeeds, the list produced is guaranteed to be non-empty. let assert away!

pub fn then(parser: Parser(a, b, c), f: fn(a) -> Parser(d, b, c)) -> Parser(
  d,
  b,
  c,
)
pub fn token(tok: a) -> Parser(Nil, a, b)
Search Document