net.hamnaberg.json.internal.org.javafp.parsecj.Parser Maven / Gradle / Ivy
package org.javafp.parsecj;
import org.javafp.data.*;
import java.util.Optional;
import java.util.function.*;
/**
* A parser is essentially a function taking the input stream and returning a ConsumedT.
* The Parser type along with the retn and bind functions constitute a monad.
* @param Input stream symbol type.
* @param Parse result type
*/
@FunctionalInterface
public interface Parser {
public static Parser parser(Function, ConsumedT> parser) {
return parser::apply;
}
static Ref ref() {
return new Ref();
}
static Ref ref(Parser parser) {
return new Ref(parser);
}
/**
* A lazily initialised reference to a Parser.
*/
public static class Ref implements Supplier>, Parser {
private Parser parser;
private Ref(Parser parser) {
this.parser = parser;
}
private Ref() {
this.parser = null;
}
public Parser set(Parser parser) {
this.parser = parser;
return this;
}
@Override
public synchronized Parser get() {
if (parser == null) {
throw new RuntimeException("Null Parser Reference");
}
return parser;
}
@Override
public ConsumedT apply(State input) {
return get().apply(input);
}
}
/**
* Parse the input state
* @return a ConsumedT result
*/
ConsumedT apply(State state);
/**
* Parse the input state, extract the result and apply one of the supplied functions.
* @return a parse result
*/
default Reply parse(State state) {
return
apply(state)
.getReply()
.match(
// Strip off the message if the parse was successful.
ok -> Reply.ok(ok.result, ok.rest, Message.of()),
error -> error
);
}
// Helper functions to allow combinators to be chained in a fluent style.
/**
* @see Combinators#bind
*/
default Parser bind(Function> f) {
return Combinators.bind(this, f);
}
/**
* @see Combinators#then
*/
default Parser then(Parser p) {
return Combinators.then(this, p);
}
/**
* @see Combinators#or
*/
default Parser or(Parser q) {
return Combinators.or(this, q);
}
/**
* @see Combinators#label
*/
default Parser label(String name) {
return Combinators.label(this, name);
}
/**
* @see Combinators#attempt
*/
default Parser attempt() {
return Combinators.attempt(this);
}
/**
* @see Combinators#option
*/
default Parser option(A x) {
return Combinators.option(this, x);
}
/**
* @see Combinators#optionalOpt
*/
default Parser> optionalOpt() {
return Combinators.optionalOpt(this);
}
/**
* @see Combinators#optional
*/
default Parser optional() {
return Combinators.optional(this);
}
/**
* @see Combinators#between
*/
default Parser between(Parser open, Parser close) {
return Combinators.between(open, close, this);
}
/**
* @see Combinators#many
*/
default Parser> many() {
return Combinators.many(this);
}
/**
* @see Combinators#many1
*/
default Parser> many1() {
return Combinators.many1(this);
}
/**
* @see Combinators#skipMany
*/
default Parser skipMany() {
return Combinators.skipMany(this);
}
/**
* @see Combinators#skipMany1
*/
default Parser skipMany1() {
return Combinators.skipMany1(this);
}
/**
* @see Combinators#sepBy
*/
default Parser> sepBy(Parser sep) {
return Combinators.sepBy(this, sep);
}
/**
* @see Combinators#sepBy1
*/
default Parser> sepBy1(Parser sep) {
return Combinators.sepBy1(this, sep);
}
/**
* @see Combinators#sepEndBy
*/
default Parser> sepEndBy(Parser sep) {
return Combinators.sepEndBy(this, sep);
}
/**
* @see Combinators#sepEndBy1
*/
default Parser> sepEndBy1(Parser sep) {
return Combinators.sepEndBy1(this, sep);
}
/**
* @see Combinators#endBy
*/
default Parser> endBy(Parser sep) {
return Combinators.endBy(this, sep);
}
/**
* @see Combinators#endBy1
*/
default Parser> endBy1(Parser sep) {
return Combinators.endBy1(this, sep);
}
/**
* @see Combinators#count
*/
default Parser> count(int n) {
return Combinators.count(this, n);
}
/**
* @see Combinators#chainr
*/
default Parser chainr(Parser> op, A x) {
return Combinators.chainr(this, op, x);
}
/**
* @see Combinators#chainr1
*/
default Parser chainr1(Parser> op) {
return Combinators.chainr1(this, op);
}
/**
* @see Combinators#chainl
*/
default Parser chainl(Parser> op, A x) {
return Combinators.chainl(this, op, x);
}
/**
* @see Combinators#chainl1
*/
default Parser chainl1(Parser> op) {
return Combinators.chainl1(this, op);
}
}