Composable, token-generic parsers for MoonBit.
moon add Nanaloveyuki/parsecimport {
"Nanaloveyuki/parsec",
}import {
"Nanaloveyuki/parsec" @parsec,
"Nanaloveyuki/parsec/char" @char,
"Nanaloveyuki/parsec/lazy" @lazy,
"Nanaloveyuki/parsec/lexer" @lexer,
"Nanaloveyuki/parsec/json" @json,
}let parser = @parsec.Parser::between(
@parsec.Parser::token('(', expected="opening parenthesis"),
@parsec.Parser::token('x', expected="x"),
@parsec.Parser::token(')', expected="closing parenthesis"),
)
match parser.parse_all(['(', 'x', ')']) {
Ok(value) => println(value)
Err(error) => println("parse failed at \{error.offset()}")
}///|
test "parse a delimited token" {
let parser = Parser::between(
Parser::token('(', expected="opening parenthesis"),
Parser::token('x', expected="x"),
Parser::token(')', expected="closing parenthesis"),
)
match parser.parse_all(['(', 'x', ')']) {
Ok(value) => inspect(value, content="x")
Err(_) => fail("expected a complete parse")
}
}pub(all) enum ParseError {
UnexpectedEnd(offset~ : Int)
Expected(label~ : String, offset~ : Int)
ExpectedAny(labels~ : Array[String], offset~ : Int)
EmptyMatchInMany(offset~ : Int)
EmptyChoice(offset~ : Int)
UnboundReference(offset~ : Int)
NotFollowedBy(label~ : String, offset~ : Int)
Context(label~ : String, cause~ : ParseError)
}pub struct Parser[T, A] {
// private fields
}pub struct ParserRef[T, A] {
// private fields
}Composable, token-generic parsers for MoonBit.